2

我得到了一些 C 代码,它是对应的汇编代码,我将用它来计算由#define. 我的问题是这条线是什么

leal 0(,%eax,8),%edx

做?

4

2 回答 2

7

lea(及其大小后缀的变体)是加载有效地址指令。基本上,它执行地址计算:它采用类似于所采用的地址描述mov,但不是访问该地址处的内存,它只是将计算的地址值加载到寄存器中。例如,这可用于获取 C 中的指针值。

因为地址描述是高度灵活的(任意起始基址、基址偏移量和灵活的元素大小),并且因为lea是一条快速指令,lea所以经常调用它来执行简单的算术运算。在这种情况下,使用lea与物理地址无关,只是用来做数学。通常,当所涉及的寄存器是数值(与指针值相反)时,可以识别这一点。在这种情况下,lea执行操作%edx = %eax * 8。由于将地址乘以 8 很少会产生有意义的地址,因此您可以得出结论,lea这里的指令只是在执行数学运算。

于 2013-10-17T22:41:58.937 回答
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
于 2013-10-17T22:26:18.550 回答