我给了一些C代码和它的汇编代码,我将用它来计算#define
声明的两个常量的值。我的问题是该行
leal 0(,%eax,8),%edx
办?
答案 0 :(得分:7)
lea
(及其大小后缀的变体)是加载有效地址指令。基本上,它执行地址计算:它采用类似于mov
所采用的地址描述,但它不是访问该地址的内存,而只是将计算出的地址值加载到寄存器中。例如,这可用于获取C中的指针值。
因为地址描述非常灵活(任意起始基数,偏离基数和灵活元素大小),并且因为lea
是快速指令,所以经常调用lea
来执行简单算术。在这种情况下,lea
的使用与物理地址无关,只是用来做数学。通常,当涉及的寄存器是数值(而不是指针值)时,可以识别这一点。在这种情况下,lea
执行操作%edx = %eax * 8
。由于将地址乘以8很少会产生有意义的地址,因此您可以得出结论,此处的lea
指令只是执行数学运算。
答案 1 :(得分:4)
这部分:
0(,%eax,8)
的格式为:
base(offset, index, size)
并计算为(偏移和索引需要是寄存器):
address = base + offset + (index × size)
在您的情况下,eax
将保留一些地址,该地址将乘以8并移至edx
(这些操作位于不在值上的地址上)。例如,如果eax = 0x11111111
,则索引将乘以8而edx
将保留0x88888888
,这就是我所能说的。
这看起来不像真正的工作代码。它通常用于数组:
array_base_address( , index_of_element, sizeof_an_element)
例如:
.data
# array of 3 elements 2 bytes each
array: .short 0x0000, 0x1111, 0x2222
.text
.global _main
_main:
# address of 0x0000
movl $0, %eax
leal array( , %eax, 2), %ebx
# address of 0x1111
movl $1, %eax
leal array( , %eax, 2), %ebx
# address of 0x2222
movl $2, %eax
leal array( , %eax, 2), %ebx
它也可以与结构一起使用:
struct_base_address(offset_to_sub_element, index_of_element, sizeof_an_element)
例如:
.data
struct:
bytes: .byte 0, 1, 2, 3
array: .int 0x00000000, 0x11111111, 0x22222222
.text
.global _main
_main:
# the offset to array
movl $4, %eax
# the index of 0x22222222
movl $2, %ebx
leal struct(%eax, %ebx, 4), %edx