x86英特尔汇编程序LEA

时间:2015-10-04 07:43:05

标签: assembly x86 intel addressing

查看以下代码:
(ebp-0x8 - > int)
(ebp-0x4 - > int *)

=> 0x80483f3 <main+6>:  mov    DWORD PTR [ebp-0x8],0x0
   0x80483fa <main+13>: mov    DWORD PTR [ebp-0x4],0x0
   0x8048401 <main+20>: mov    DWORD PTR [ebp-0x8],0xa

   0x8048408 <main+27>: lea    eax,[ebp-0x8]
   0x804840b <main+30>: mov    DWORD PTR [ebp-0x4],eax

   0x804840e <main+33>: mov    eax,0x0
   0x8048413 <main+38>: leave  
   0x8048414 <main+39>: ret  

真的需要LEA命令吗? 我知道下面的表达式是错误的,无论左边的地址是否错误都无效,但是没有类似的方法可以像这样做吗?

=> 0x80483f3 <main+6>:  mov    DWORD PTR [ebp-0x8],0x0
   0x80483fa <main+13>: mov    DWORD PTR [ebp-0x4],0x0
   0x8048401 <main+20>: mov    DWORD PTR [ebp-0x8],0xa

   0x804840b <main+30>: mov    DWORD PTR [ebp-0x4],ebp-0x8

   0x804840e <main+33>: mov    eax,0x0
   0x8048413 <main+38>: leave  
   0x8048414 <main+39>: ret

我认为这不可能,但我想确定。

最后一个问题,表达式ebp-0x8理论上会返回ebp寄存器减去0x8&#34; 的&#34;内容。 因此,表达式[ebp-0x8]将返回内容&#34;内容ebp寄存器减去0x8&#34; 的内存内容。 现在我想知道如果LEA命令只获取内存中某些字节的内容,LEA命令如何获取内存地址。

很抱歉,如果有一些愚蠢的问题,但 [] 有时会非常混乱。

2 个答案:

答案 0 :(得分:3)

为了使您的第二个代码段有效,您需要将减法作为单独的指令。换句话说,而不是

DWORD PTR [ebp-0x4],ebp-0x8

你需要

mov eax,ebp
sub eax,0x8
mov DWORD PTR [ebp-0x4],ax

使用lea的优点是它结合了算术运算和mov指令。因此,而不是两个指令

mov eax,ebp
sub eax,0x8

你可以使用单一指令

lea eax,[ebp-0x8]

lea指令表示“加载有效地址”。第二个操作数指定地址,计算该地址所需的任何计算都由处理器中的地址生成逻辑完成。

另一方面,sub指令使用处理器的通用算术逻辑单元(ALU)。

总之,lea指令通过使用处理器的地址生成逻辑将两条指令合并为一条,以执行数学计算,否则需要在ALU中完成。

答案 1 :(得分:1)

不,它表达无效,你不能在 mov 源操作数中使用内存地址进行数学表达,除非你指定[]括号,这是从内存地址取消引用值的其他含义(与解引用C指针以获取其值完全相同)

使用地址进行数学表达的方法是使用LEA指令,在您的示例中为:

lea    eax,[ebp-0x8]
mov    DWORD PTR [ebp-0x4],eax

请注意, lea mov 指令有很大不同。

这是英特尔手册中 lea 指令的第一个定义:

  

计算第二个操作数的有效地址(源   操作数)并将其存储在第一个操作数(目标操作数)中。

已知

mov 是数据传输指令,而 lea 主要用于使用数学运算来计算地址

这是 mov lea

之间的一些不同示例
mov eax, [ebp-0x8]   ; compute new address ebp-0x8 and get its value from new address
mov eax, ebp-0x8     ; this is invalid
lea eax, [ebp-0x8]   ; compute new address ebp-0x8 and give it to eax