在汇编程序中进行间接调用

时间:2012-04-15 23:58:55

标签: assembly compiler-construction x86

我正在为一个类编写一个编译器,而且我坚持使用GNU的语法进行间接调用。考虑一下这个简单的程序:

.text
.globl main
main:
  movl func, %eax
  call *%eax
  ret

func:
  movl $42, %eax
  ret

使用gcc -m32 -O0进行编译并运行生成的程序会给我一个分段错误。谁能告诉我如何正确地进行通话?

感谢。

文森特。

2 个答案:

答案 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可以进行虚拟地址转换。