是否可以在程序集中的取消引用中取消引用某些内容?



请考虑以下过程,该过程用值填充dword数组,并接受2个参数:EBP + 08h是数组的大小,EBP + 0Ch是给定数组的偏移量。(即OFFSET myarray(:

MyProc PROC
PUSH EBP
MOV EBP, ESP
SUB ESP, 04h
PUSH EDI
PUSH ESI
PUSH EBX
MOV EBX, [EBP + 08h] ;move the size of the array into EBX
MOV [EBP - 04h], 00h ;EBP - 04h will be the counter (or the index.)
MOV ESI, [EBP + 0Ch] ;move the offset of the array into ESI
MOV EDI, 01h
INC EBX
@@:

MOV [ESI + 04h * [EBP - 04h]], EDI ;How can I actually move EDI into
;the dword found at address ESI + 4 * the value found at address EBP - 4?

INC [EBP - 04h] ;increment the counter and the value to be stored.
INC EDI
CMP [EBP - 04h], EBX
JNE @B
POP EBX
POP ESI
POP EDI
MOV ESP, EBP
POP EBP
RET
MyProc ENDP

我尝试将EDI移动到[ESI + 04h * [EBP - 04h]]的地方是我正在尝试执行的操作的一个例子,因为地址EBP - 4处的 dword 是数组的索引。
有没有办法在地址ESI + 4 * the dword at address EBP - 4处实际将EDI移动到dword中?还是我看错了?

你使这个过程过于复杂。您需要做的就是:

push  ebp
mov   ebp, esp
xor   eax, eax            ; Fill buffer with nulls
mov   ecx, [ebp+8]        ; Number of dwords to fill
push  edi
mov   edi, [ebp+12]
rep   stosd
pop   edi
leave
ret   8                    ; Pop arguments passed by caller

大多数ABI认为EAX,ECX和EDX是易失性的,但如果您需要保留它们,请务必。

MOV [ESI + 04h * [EBP - 04h]], EDI ;How can I actually move EDI into
;the dword found at address ESI + 4 * the value found at address EBP - 4?
INC [EBP - 04h] ;increment the counter and the value to be stored.

[EBP-4]处的值将在 dword 数组中保存一个递增索引。我看到这个小问题的 2 个解决方案:

  1. 您继续使用局部变量,并通过 2 个步骤编写有问题的指令:

    mov eax, [ebp-4]
    mov [esi+eax*4], edi
    inc [ebp-4]
    
  2. 您根本不使用局部变量,并将索引保存在寄存器中:

    mov [esi+eax*4], edi
    inc eax
    

要考虑的错误:

INC EBX

这个inc会给你 1 次迭代太多了!


假设你想用正好比元素索引大 1 的递增值填充数组(a[0]=1, a[1]=2, a[2]=3,...(,你可以通过预先递增索引并通过从地址中减去 4 来补偿此操作来编写更好的例程:

MyProc PROC
PUSH EBP
MOV  EBP, ESP
PUSH ESI
xor  eax, eax         ;EAX will be the counter (or the index.)
mov  esi, [ebp + 12]  ;move the offset of the array into ESI
@@:
inc  eax              ;increment the counter and the value to be stored.
mov  [esi + eax * 4 - 4], eax
cmp  eax, [ebp + 8]   ;Compare index to size of the array
jb   @B
POP ESI
MOV ESP, EBP
POP EBP
RET
MyProc ENDP

使用的寄存器更少也意味着需要保留的寄存器更少!

它需要两个指令:

MOV    EAX, [EBP - 04h]
MOV   [ESI + 4*EAX], EDI

您还可以考虑在函数的前言和尾声中保存/恢复 EAX。 在大多数环境中,不需要保留 EAX。

最新更新