是否可以在汇编中的取消引用中取消引用某些内容?
Is it possible to dereference something inside of a dereference in assembly?
考虑以下用值填充双字数组并接受 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
的双字中吗?还是我看错了?
需要两条指令:
MOV EAX, [EBP - 04h]
MOV [ESI + 4*EAX], EDI
您还可以在函数的序言和尾声中考虑 saving/restoring EAX。在大多数环境下,EAX不需要保留。
你把这个过程搞得太复杂了。您需要做的就是:
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]
处的值将在您的双字数组中保存递增索引。我看到这个小问题有 2 个解决方案:
您继续使用局部变量并分两步编写有问题的指令:
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 个参数的过程: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
的双字中吗?还是我看错了?
需要两条指令:
MOV EAX, [EBP - 04h]
MOV [ESI + 4*EAX], EDI
您还可以在函数的序言和尾声中考虑 saving/restoring EAX。在大多数环境下,EAX不需要保留。
你把这个过程搞得太复杂了。您需要做的就是:
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]
处的值将在您的双字数组中保存递增索引。我看到这个小问题有 2 个解决方案:
您继续使用局部变量并分两步编写有问题的指令:
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
使用的寄存器越少也意味着要保留的寄存器越少!