masm x86 Assembly 如何使变量指向设置缓冲区中的值?
masm x86 Assembly How to make a variable point to a value in a set buffer?
假设我创建了一个大约 100 个 DWORD 的简单缓冲区,并且我还定义了一个变量,该变量应该指向该缓冲区中的给定 DWORD。
.DATA?
buffer DWORD 064h DUP(?)
my_ptr DD ?
在 .CODE 部分,我试图让 my_ptr 指向缓冲区中的第一个双字,因此 OFFSET 缓冲区 + 04h * 00h。
我想我可以让寄存器存储地址,然后将寄存器内的地址移动到 my_ptr.
.CODE
;for the sake of the example pretend that the values in buffer
; are initialized.
MOV EDI, OFFSET buffer
MOV EAX, EDI + 04h * 00h ; trying move the address of the first element in
;the buffer into EAX
MOV my_var, EAX ;move the address that eax holds into my_var
所以基本上总结一下,有没有办法让数据变量指向缓冲区内的值?我不知道这是否可能,因为每次我查看寻址时它总是被取消引用,但在这种情况下我只想要地址,而不是地址处的值。
谢谢
.DATA?
buffer DWORD 064h DUP(?)
my_ptr DD ?
.CODE
;for the sake of the example pretend that the values in buffer
; are initialized.
它们是否是无关紧要,因为您不会在以下代码中对它们进行任何操作。
MOV EDI, OFFSET buffer
是的,这是保留内存的地址(在 edi
中)。
MOV EAX, EDI + 04h * 00h ; trying move the address of the first element in
;the buffer into EAX
现在这在 x86 语法中是不合法的,你不能做 mov reg,reg+immediate
,但是当你添加零时,它与 mov eax,edi
是一样的,这是合法的并且会做什么如您所料,将数组地址从 edi
复制到 eax
。现在这当然没用了,因为您可以通过 MOV [my_ptr],edi
直接从 edi
存储地址
但是假设您想要第三个(索引 2)DWORD 的地址,那么您对 mov eax, edi + 4*2
的想法可以这样写:
mov eax,edi ; copy the address first (no math expression possible)
add eax,4*2 ; offset the address to point to third element
mov [my_ptr],eax ; store it
但是 x86 对此有更专门的指令,它允许您使用合法用于取消引用的相同表达式(如 mov eax,[edi+4*2]
)仅用于计算地址。该指令称为 LEA
- load effective address。它的工作原理有点像“MOV
没有勇气”,所以:
lea eax,[edi+4*2]
将计算目标内存地址,如 MOV
,但它不会联系内存获取值,而是将计算出的地址存储到目标寄存器中,因此在这种情况下将设置 eax
到 edi+8
值(这是第三个元素的地址)。
这也可以用于简单的数学计算,如果你忘记描述中的 "address" 措辞,比如你想计算 ecx = eax + 4*edi + 22,那么你可以这样做在 x86 上使用单个指令:lea ecx,[eax + 4*edi + 22]
(但这可能只是因为该表达式是 mov
指令族的有效内存操作数,如果您想要 eax + 5*edi + 22
,则必须使用两个 lea
指令将该表达式分解为两个有效的内存寻址表达式,作为练习自己尝试)。如果您只使用普通的算术指令,则需要其中的四个 (mov ecx,edi
shl ecx,2
add ecx,eax
add ecx,22
).
有时您还可以利用 lea
进行算术运算,同时为其他正在进行的计算保留标志,例如递增指针,而 CF 保留用于对值进行的持续加法。
假设我创建了一个大约 100 个 DWORD 的简单缓冲区,并且我还定义了一个变量,该变量应该指向该缓冲区中的给定 DWORD。
.DATA?
buffer DWORD 064h DUP(?)
my_ptr DD ?
在 .CODE 部分,我试图让 my_ptr 指向缓冲区中的第一个双字,因此 OFFSET 缓冲区 + 04h * 00h。 我想我可以让寄存器存储地址,然后将寄存器内的地址移动到 my_ptr.
.CODE
;for the sake of the example pretend that the values in buffer
; are initialized.
MOV EDI, OFFSET buffer
MOV EAX, EDI + 04h * 00h ; trying move the address of the first element in
;the buffer into EAX
MOV my_var, EAX ;move the address that eax holds into my_var
所以基本上总结一下,有没有办法让数据变量指向缓冲区内的值?我不知道这是否可能,因为每次我查看寻址时它总是被取消引用,但在这种情况下我只想要地址,而不是地址处的值。
谢谢
.DATA?
buffer DWORD 064h DUP(?)
my_ptr DD ?
.CODE
;for the sake of the example pretend that the values in buffer
; are initialized.
它们是否是无关紧要,因为您不会在以下代码中对它们进行任何操作。
MOV EDI, OFFSET buffer
是的,这是保留内存的地址(在 edi
中)。
MOV EAX, EDI + 04h * 00h ; trying move the address of the first element in
;the buffer into EAX
现在这在 x86 语法中是不合法的,你不能做 mov reg,reg+immediate
,但是当你添加零时,它与 mov eax,edi
是一样的,这是合法的并且会做什么如您所料,将数组地址从 edi
复制到 eax
。现在这当然没用了,因为您可以通过 MOV [my_ptr],edi
edi
存储地址
但是假设您想要第三个(索引 2)DWORD 的地址,那么您对 mov eax, edi + 4*2
的想法可以这样写:
mov eax,edi ; copy the address first (no math expression possible)
add eax,4*2 ; offset the address to point to third element
mov [my_ptr],eax ; store it
但是 x86 对此有更专门的指令,它允许您使用合法用于取消引用的相同表达式(如 mov eax,[edi+4*2]
)仅用于计算地址。该指令称为 LEA
- load effective address。它的工作原理有点像“MOV
没有勇气”,所以:
lea eax,[edi+4*2]
将计算目标内存地址,如 MOV
,但它不会联系内存获取值,而是将计算出的地址存储到目标寄存器中,因此在这种情况下将设置 eax
到 edi+8
值(这是第三个元素的地址)。
这也可以用于简单的数学计算,如果你忘记描述中的 "address" 措辞,比如你想计算 ecx = eax + 4*edi + 22,那么你可以这样做在 x86 上使用单个指令:lea ecx,[eax + 4*edi + 22]
(但这可能只是因为该表达式是 mov
指令族的有效内存操作数,如果您想要 eax + 5*edi + 22
,则必须使用两个 lea
指令将该表达式分解为两个有效的内存寻址表达式,作为练习自己尝试)。如果您只使用普通的算术指令,则需要其中的四个 (mov ecx,edi
shl ecx,2
add ecx,eax
add ecx,22
).
有时您还可以利用 lea
进行算术运算,同时为其他正在进行的计算保留标志,例如递增指针,而 CF 保留用于对值进行的持续加法。