我正在为一个类编写一个编译器,而且我坚持使用GNU的语法进行间接调用。考虑一下这个简单的程序:
.text
.globl main
main:
movl func, %eax
call *%eax
ret
func:
movl $42, %eax
ret
使用gcc -m32 -O0
进行编译并运行生成的程序会给我一个分段错误。谁能告诉我如何正确地进行通话?
感谢。
文森特。
答案 0 :(得分:5)
call
指令本身实际上很好。 :)
您的问题是您似乎忘记了AT& T语法的工作原理。您正在使用movl func, %eax
执行的操作是将dword从标签func
的地址复制到eax
寄存器。基本上,eax
最终会得到函数实际代码的前4个字节。
AT& T中的立即操作数以$
为前缀。作为编译时常量的func
标签的值可以用作立即数,这就是你想要的情况。因此,将movl func, %eax
替换为movl $func, %eax
,您就可以了。 :)
在这里使用lea
是多余的。当然,它会起作用,但由于func
是一个编译时常量,所以简单地将它作为一个直接的代码放在代码中而不是在运行时计算它会更有效。
答案 1 :(得分:-2)
我想我明白了;使用lea
代替movl
解决了问题;我想lea可以进行虚拟地址转换。