x86 英特尔汇编器 LEA
x86 Intel Assembler LEA
查看以下代码:
(ebp-0x8 -> 整数)
(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
理论上会 return "content of the ebp
register minus 0x8
"。
因此表达式 [ebp-0x8]
将 return 地址为 "content of the ebp
register minus 0x8
" 的内存内容。
现在我想知道 LEA 命令如果只获取内存中某些字节的内容,如何获取内存地址。
抱歉,如果有一些愚蠢的问题,但 [] 有时会非常混乱。
为了使您的第二个代码片段有效,您需要将减法作为单独的指令进行。换句话说,而不是
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
指令表示"load the effective address"。第二个操作数指定地址,计算该地址所需的任何计算均由处理器中的地址生成逻辑完成。
另一方面,sub
指令使用处理器的通用算术逻辑单元 (ALU)。
综上所述,lea
指令通过使用处理器的地址生成逻辑将两条指令合二为一,执行原本需要在ALU中完成的数学计算。
不,它是无效的表达式,你不能用mov源操作数中的内存地址做数学表达式,除非你指定[] 括号,这是另一个含义,即从内存地址中取消引用值(这与取消引用 C 指针以获取其值完全相同)
用地址做数学表达式的方法是使用LEA指令,在你的例子中是:
lea eax,[ebp-0x8]
mov DWORD PTR [ebp-0x4],eax
请注意 lea 与 mov 指令的工作方式非常不同。
这是英特尔手册中对 lea 指令的第一个定义:
Computes the effective address of the second operand (the source
operand) and stores it in the first operand (destination operand).
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
查看以下代码:
(ebp-0x8 -> 整数)
(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
理论上会 return "content of the ebp
register minus 0x8
"。
因此表达式 [ebp-0x8]
将 return 地址为 "content of the ebp
register minus 0x8
" 的内存内容。
现在我想知道 LEA 命令如果只获取内存中某些字节的内容,如何获取内存地址。
抱歉,如果有一些愚蠢的问题,但 [] 有时会非常混乱。
为了使您的第二个代码片段有效,您需要将减法作为单独的指令进行。换句话说,而不是
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
指令表示"load the effective address"。第二个操作数指定地址,计算该地址所需的任何计算均由处理器中的地址生成逻辑完成。
另一方面,sub
指令使用处理器的通用算术逻辑单元 (ALU)。
综上所述,lea
指令通过使用处理器的地址生成逻辑将两条指令合二为一,执行原本需要在ALU中完成的数学计算。
不,它是无效的表达式,你不能用mov源操作数中的内存地址做数学表达式,除非你指定[] 括号,这是另一个含义,即从内存地址中取消引用值(这与取消引用 C 指针以获取其值完全相同)
用地址做数学表达式的方法是使用LEA指令,在你的例子中是:
lea eax,[ebp-0x8]
mov DWORD PTR [ebp-0x4],eax
请注意 lea 与 mov 指令的工作方式非常不同。
这是英特尔手册中对 lea 指令的第一个定义:
Computes the effective address of the second operand (the source operand) and stores it in the first operand (destination operand).
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