0

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

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

func:
  movl $42, %eax
  ret

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

谢谢。

文森特。

4

2 回答 2

6

call指令本身实际上是好的。:)

您的问题是您似乎忘记了 AT&T 语法的工作原理。您在这里所做的movl func, %eax是将标签地址中的双字复制funceax寄存器中。本质上,eax以函数的前 4 个字节的实际代码结束。

AT&T 中的立即操作数以 . 为前缀$。作为编译时常量的func标签的值可以用作立即数,这就是您在这种情况下想要的。因此,替换movl func, %eaxmovl $func, %eax,你会没事的。:)

在这里使用lea是多余的。当然,它会起作用,但由于func它是一个编译时常量,因此将它简单地放在代码中而不是在运行时找出它会更有效。

于 2012-04-16T00:24:46.260 回答
-3

我想我明白了;使用lea而不是movl解决问题;我想 lea 进行虚拟地址转换。

于 2012-04-16T00:22:00.677 回答