2017-07-19 55 views
3

考慮以下過程,它使用值填充一個雙字數組,並帶入兩個參數: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是數組索引的例子。
有沒有什麼辦法可以將EDI實際移動到地址ESI + 4 * the dword at address EBP - 4的雙字上?還是我看着這個錯誤的方式?

回答

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]值將在您的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次迭代太多了!


鑑於要使用增加了恰恰比元素的索引(A [0] = 1時,A [1] = 2,1大值[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 

也用更少的寄存器意味着更少的寄存器保存!

+0

「變量」是一個高級概念。你仍然可以考慮你的循環計數器一個變量,如果你把它保存在一個寄存器中,並且不需要任何堆棧空間來泄漏它。 –

2

它需要兩個指令:

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

你也可以考慮保存/在函數的序言和跋恢復EAX。在大多數環境中,EAX不需要保存。

+0

我可能是錯的,但我認爲你要找的術語是「功能結語」。「:) –

+1

@DavidHoelzer:是的,當我遠足幾個小時回來並立即嘗試寫出一個連貫的答案時,會發生什麼情況。謝謝。 – wallyk

+3

我現在不能嘗試,但你確定'[ESI + 4 * [EAX]]''不應該是'[ESI + 4 * EAX]'?這些術語是序言和結尾的

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波動,但如果你需要保留它們,通過各種手段。

相關問題