4

我知道我要说的那句话可能是很快在 StackOverflow 上变得非常冷门的最好方法。无论如何我都会说:为什么这不起作用(完全)?

我试图弄清楚lea/leal 指令的作用。我理解它的方式,lea/leal 找出第一个操作数的内存地址并将这个地址写入第二个操作数(可能是一个寄存器左右)。

这部分似乎工作。当我运行下面的程序时,它说:

The memory address of var is 134518204.

但是,在此之后,它会说“内存访问错误”之类的东西。pushl (%eax)显然不起作用。为什么不?

.data
    var:    .long 42
    str1:   .string "The memory address of var is %d.\n"
    str2:   .string "At this memory address we find var's value: %d.\n"

.text
.global main
main: 
    leal var, %eax          # Copy the address of var into %eax
    pushl %eax
    pushl $str1
    call printf             # Print str1
    pushl (%eax)
    pushl $str2
    call printf             # Print str2

    # Some stack cleaning should be here :)

    movl $1, %eax
    int $0x80

我什至不确定 lea/leal 的作用是否正确。帮助表示赞赏。;)

4

2 回答 2

2

我理解它的方式,lea/leal 找出第一个操作数的内存地址并将这个地址写入第二个操作数(可能是一个寄存器左右)。

听起来足够准确。它用于执行地址运算;这可以像加载地址一样简单,但您也可以使用它来执行某些常数的乘法运算。


pushl (%eax)显然行不通。为什么不?

您的push指令没有引用您认为的地址:printf返回写入的字符数,并且该值在%eax寄存器中返回,因此%eax不再包含var.

于 2013-11-02T15:52:49.237 回答
2

lea通常(ab)用于计算:如果您只想要寄存器中的全局地址,movl $var, %eax则比lea.

另外,为了清楚起见,目标操作数lea 必须是寄存器。

于 2013-11-02T16:15:04.330 回答