Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 用leal做的是什么?_Assembly_X86 - Fatal编程技术网

Assembly 用leal做的是什么?

Assembly 用leal做的是什么?,assembly,x86,Assembly,X86,我得到了一些C代码和它的程序集副本,我将使用它们来计算由#define声明的两个常量的值。我的问题是这条线是什么 leal 0(,%eax,8),%edx 做什么?这部分: 0(,%eax,8) 表格如下: base(offset, index, size) 并计算为(偏移量和索引需要为寄存器): 在您的情况下,eax将保存一些地址,这些地址将乘以8并移动到edx(这些操作是针对地址的,而不是针对值的)。例如,如果eax=0x11111111,则索引将乘以8,edx将保持0x888888,

我得到了一些C代码和它的程序集副本,我将使用它们来计算由
#define
声明的两个常量的值。我的问题是这条线是什么

leal 0(,%eax,8),%edx
做什么?

这部分:

0(,%eax,8)
表格如下:

base(offset, index, size)
并计算为(偏移量和索引需要为寄存器):

在您的情况下,
eax
将保存一些地址,这些地址将乘以8并移动到
edx
(这些操作是针对地址的,而不是针对值的)。例如,如果
eax=0x11111111
,则索引将乘以8,
edx
将保持
0x888888
,这就是我所能说的

这看起来不像是真正的工作代码。它通常与数组一起使用,例如:

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
.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
它也可用于以下结构:

struct_base_address(offset_to_sub_element, 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
.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
lea
(及其大小后缀变体)是加载有效地址指令。基本上,它执行地址计算:它采用与
mov
类似的地址描述,但它不访问该地址的内存,而是将计算出的地址值加载到寄存器中。例如,这可以用来获取C中的指针值


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

请参阅摆脱断气语法,改用英特尔语法,您的理智将为此感谢您:
lea edx,[eax*8+0]
+1,但是您不能明确地说
lea是一条快速指令
。这取决于lea如何转换成UOP,而UOP在CPU之间是不同的。问题不在于它是否快,而是编译器是否认为它是将
%edx
顶部的3位移位到
%eax
。这不是你想要的指导。除了BMI2和RORX之外,LEA是在一条指令中复制和转换的唯一方法。@PeterCordes:的确,你是对的。我不知道我写那篇文章时在想什么——真是漂亮的一记!