彙編-通過子程序交換兩個內存變量

交換兩個內存變量相信大家都不陌生,核心的代碼就是:

;交換[esi],[edi]兩個內存變量
mov eax, [esi]
xchg eax, [edi]
mov [esi],eax

然而現在我們要通過用匯編編寫一段子程序來調用這個子程序來實現交換兩個數,我們定義主函數給子函數傳遞的參數是以地址的形式(指針),傳遞需要交換的兩個內存變量。
源程序如下:

;功能:使用子程序交換兩個內存變量
;作者:王文堃
;創建時間:2016/4/20

INCLUDE vcIO.inc
.data
    num1 DWORD 1234
    num2 DWORD 5678
    str_output BYTE "num1 = %d, num2 = %d",0ah,0
.code
;主程序
main PROC
    push offset num1
    push offset num2
    call swap
    invoke printf, offset str_output, num1, num2 
    ret
main ENDP

;子程序
swap PROC
    push ebp
    mov ebp, esp
    pushad

    ;body of swap
    ;[ebp+4] is return addr,[ebp+8] is the first argument,[ebp+12] is the sec agru
    mov esi, [ebp+8]
    mov edi, [ebp+12]

    ;swap [esi],[edi]
    mov eax, [esi]
    xchg eax, [edi]
    mov [esi], eax

    popad
    pop ebp
    ret 2*4 ;2 is the num of arguments, 4 is the size of argument
swap ENDP

END main

主程序中

push offset num1 ;將參數進棧
push offset num2 ;將第二個參數進棧
call swap ;調用子函數,有兩個動作,第一個是將下一條指令的地址入棧,第二個動作是轉到子程序,即將eip修改爲子程序的地址

子程序中

子程序一進來就有push ebp 和mov ebp, esp兩句
這裏是剛開始接觸子程序調用的難點,爲什麼不直接使用esp而還要賦給ebp使用ebp呢?
因爲esp的位置會隨着程序pop,push而動態改變
我們後面要訪問第一個參數本來是在[esp+8],但因爲pushad後esp改變了,第一個參數也就不再是[esp+8]
所有我們一進來就將esp保存在ebp中,之後第一個參數就可以通過[ebp+8]訪問

需要說明的是通過ebp訪問參數的時候:
[ebp+4]是子程序要返回給主函數的地址
[ebp+8]是第一個參數
[ebp+12]是第二個參數

ret 2*4這一句是說明將兩個參數彈出棧不要了,因爲棧中每個數據戰4個字節,所以*4

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章