masm x86汇编如何使变量指向设置缓冲区中的值?

时间:2017-07-22 16:46:41

标签: assembly x86 masm

让我们说我已经制作了一个大约100个DWORDS的简单缓冲区,并且我还有一个定义的变量,它应该指向该缓冲区中的给定DWORD。

.DATA?
buffer DWORD 064h DUP(?)
my_ptr DD ?

在.CODE部分,我试图让my_ptr指向,比如缓冲区中的第一个dword,所以OFFSET buffer + 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

所以基本上总结一下,无论如何使数据变量指向缓冲区内的值?我不知道这是否可行,因为每次我查看它时,它总是被解除引用,但我只想要这个地址的地址,而不是地址的值。

由于

1 个答案:

答案 0 :(得分:2)

.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。现在这当然没用了,因为你可以直接从edi存储地址:MOV [my_ptr],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将设置为{ {1}}值(以及第三个元素的地址)。

这也可以用于简单的数学计算,如果你忘记了描述中的“地址”措辞,比如你想要计算ecx = eax + 4 * edi + 22,那么你可以用单指令来做x86:edi+8(但这可能只是因为该表达式是lea ecx,[eax + 4*edi + 22]指令族的有效内存操作数,如果您需要mov,则必须使用两个eax + 5*edi + 22指令将该表达式分解为两个有效的内存寻址表达式,可以自己尝试将其作为练习)。如果您只使用普通的算术指令,则需要其中的四个(lea mov ecx,edi shl ecx,2 add ecx,eax)。

有时你可以利用add ecx,22进行算术运算,同时为其他正在进行的计算保留标志,比如递增指针,而CF则保留用于对值进行的持续加法。