Assembly IA32汇编:lea指令

Assembly IA32汇编:lea指令,assembly,x86,Assembly,X86,我知道我将要说的这句话可能是迅速在StackOverflow上变得不受欢迎的最好方式。不管怎样,我还是要说:为什么这不能(完全)起作用 我试图弄清楚lea/leal指令的作用。按照我的理解,lea/leal会找出第一个操作数的内存地址,并将该地址写入第二个操作数(可能是寄存器左右) 这部分似乎有效。当我运行下面的程序时,它会说: The memory address of var is 134518204. 然而,紧接着它会说“内存访问错误”PUSH(%eax)显然不起作用。为什么不呢 .da

我知道我将要说的这句话可能是迅速在StackOverflow上变得不受欢迎的最好方式。不管怎样,我还是要说:为什么这不能(完全)起作用

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

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

The memory address of var is 134518204.
然而,紧接着它会说“内存访问错误”PUSH(%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的工作。谢谢你的帮助

按照我的理解,lea/leal会找出第一个操作数的内存地址,并将该地址写入第二个操作数(可能是寄存器左右)

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


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

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

lea
的地址通常是(ab)用于计算:如果您只想在寄存器中输入全局变量的地址,
movl$var,%eax
lea
更清晰(且短一个字节)


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

非常感谢!实际上,我刚刚读到,根据C调用约定,%eax将始终被更改。看来我真的需要做点别的事情了…:D
movl src,dest
表示
dest=src
leal src,dest
表示
dest=&src
(即dest=src的地址)更准确地说,
movl
评估源,将其视为地址并将其内容移动到目标。但是,
leal
对源代码进行求值,并将求值值移动到目标。非常感谢,这也非常有用!