【发布时间】:2018-07-15 23:34:20
【问题描述】:
我正在学习汇编语言,我创建了一个简单的 linux 内核模块来尝试如何从模块调用汇编函数,而后者又调用 C 函数。代码编译得很好。但是,当我尝试插入模块时,会导致内核崩溃。我从这篇文章中得到了这个想法:Calling C functions from x86 assembly language。我想知道是否有人可以帮助我理解为什么它不起作用。
首先是汇编代码:
#include <linux/linkage.h>
ENTRY(sample_assembly_function)
pushq $10
call printMessage
add $0x4, %rsp
END(sample_assembly_function)
第二个文件是示例模块文件:
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("Proprietary");
void sample_assembly_function(void);
void printMessage(int num)
{
printk(KERN_ERR "MixAssemblyAndC: PrintMessage=%d.\n", num);
}
static int __init AModule_init(void)
{
sample_assembly_function();
return 0;
}
static void __exit AModule_exit(void)
{
printk("MixAssemblyAndC: Goodbye, world!\n");
}
module_init(AModule_init);
module_exit(AModule_exit);
最后这是 Makefile:
KERNELDIR:=/lib/modules/$(shell uname -r)/build
PWD=$(shell pwd)
obj-m += test.o
test-y := AModule.o ASample.o
all:
$(MAKE) -C $(KERNELDIR) M=$(PWD)
clean:
$(MAKE) -C $(KERNELDIR) M=$(PWD) clean
install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
【问题讨论】:
-
x64 调用约定与 x86 调用约定完全不同。也许看看stackoverflow.com/a/28601779/12711 和/或cs.nyu.edu/courses/fall11/CSCI-GA.2130-001/x64-intro.pdf
-
我同意 Michael 的观点,另一个明显的问题是您推送一个 8 字节的值,然后只在之后将 RSP 调整 4(而不是 8)
-
当你刚刚学习 asm 时,你肯定需要一个调试器。您可以从查看寄存器值和单步执行中学到更多,而不是从崩溃中学到的东西。 kernel.org/doc/html/v4.13/dev-tools/kgdb.html
-
感谢您的所有建议。有一些很好的参考点! @MichaelPetch 请参阅我的 cmets 来回答您的问题。谢谢。
标签: c assembly linux-kernel x86-64 calling-convention