考虑使用以下值填充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
处的双字是数组的索引。
有没有办法真正将EDI
移到地址ESI + 4 * the dword at address EBP - 4
的双关语中?或者我是以错误的方式看待这个?
答案 0 :(得分:4)
你使这个程序过于复杂。您需要做的就是:
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易变,但如果你需要保留它们,一定要。
答案 1 :(得分:3)
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]
处的值将在您的双字阵列中保存递增索引。我看到了这个小问题的两个解决方案:
您继续使用局部变量并分两步编写有问题的指令:
mov eax, [ebp-4]
mov [esi+eax*4], edi
inc [ebp-4]
您根本不使用本地变量,并将索引保存在寄存器中:
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
使用较少的寄存器也意味着要保留较少的寄存器!
答案 2 :(得分:2)
它需要两条指令:
MOV EAX, [EBP - 04h]
MOV [ESI + 4*EAX], EDI
您还可以考虑在功能的前导码和尾声中保存/恢复EAX。在大多数环境中,不需要保留EAX。