新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 匯編入門學習筆記 (九)—— call和ret

        匯編入門學習筆記 (九)—— call和ret

        作者: 時間:2016-11-09 來源:網絡 收藏
        瘋狂的暑假學習之 匯編入門學習筆記 (九)—— callret

        本文引用地址:http://www.104case.com/article/201611/317783.htm

        參考: 《匯編語言》 王爽 第10章

        call和ret都是轉移指令。

        1. ret和retf

        ret指令:用棧中的數據,修改IP內容,從而實現近轉移

        相當于:

        pop ip

        retf指令:用棧中的數據,修改CS和IP,從而實現遠轉移

        相當于:

        pop ip

        pop cs

        例子:ret

        1. assumecs:code,ss:stack
        2. stacksegment
        3. db16dup(1)
        4. stackends
        5. codesegment
        6. movax,4c00H
        7. int21H
        8. start:movax,stack
        9. movss,ax
        10. movsp,16
        11. movax,0
        12. pushax
        13. ret
        14. codeends
        15. endstart

        retf

        1. assumecs:code,ss:stack
        2. stacksegment
        3. db16dup(1)
        4. stackends
        5. codesegment
        6. movax,4c00H
        7. int21H
        8. start:movax,stack
        9. movss,ax
        10. movsp,16
        11. movax,0
        12. pushcs
        13. pushax
        14. retf
        15. codeends
        16. endstart


        2. call指令

        call指令,執行操作:

        1.將當前IP或CS和IP壓入棧中

        2.跳轉

        (1)依據位移進行轉移的call指令

        格式: call 標號

        將下一條的指令的ip壓入棧中,在轉到標號處

        相當于:

        push ip

        jmp near ptr 標號

        (2)轉移的目的地址在指令中的call指令

        格式:

        call far ptr 標號

        將下一條的指令的CS和IP壓入棧中,在轉到標號處

        相當于:

        push cs

        push ip

        jmp far ptr

        (3)轉移地址地址在寄存器中的call指令

        格式:call 16位reg

        相當于:

        push ip

        jmp 16位reg

        (4)轉移地址在內存中的call指令

        1. call word ptr 內存單元

        相當于:

        push ip

        jmp word ptr 內存單元

        2. call dword ptr 內存單元

        相當于:

        push cs

        push ip

        jmp dword ptr 內存單元

        3. mul 指令

        mul 是乘法指令

        表示兩個數相乘,它必須是都是8位或者都是16位

        8位相乘 結果默認存放在ax中

        16位相乘 結果高位存放在dx中,低位存放在ax中

        例子見下面。

        3. call和ret配合使用

        call于ret結合使用,就相當于函數。

        例子:求dw中數值的3次方。把bx當做“函數”參數,ax當做“函數”的返回值。

        1. assumecs:code,ds:data
        2. datasegment
        3. dw1,2,3,4,5,6,7,8
        4. dd0,0,0,0,0,0,0,0
        5. dataends
        6. codesegment
        7. start:movax,data
        8. movds,ax
        9. movsi,0
        10. movdi,16
        11. movcx,8
        12. s:movbx,ds:[si]
        13. callcube
        14. movds:[di],ax
        15. movds:[di+2],dx
        16. addsi,2
        17. adddi,4
        18. loops
        19. movax,4c00H
        20. int21H
        21. cube:movax,bx
        22. mulbx
        23. mulbx
        24. ret
        25. codeends
        26. endstart

        寄存器數量有限,如果要傳的參數,或者返回的參數過多。可以使用內存,或者棧。

        例子:小寫轉大寫。(用內存存放參數)

        1. assumecs:code,ds:data
        2. datasegment
        3. dbconversation
        4. dataends
        5. codesegment
        6. start:movax,data
        7. movds,ax
        8. movsi,0
        9. movcx,12
        10. callcaptial
        11. movax,4c00H
        12. int21H
        13. captial:andbyteptrds:[si],11011111b
        14. incsi
        15. loopcaptial
        16. codeends
        17. endstart

        例子:計算 (a - b) ^3 假設a=3,b=1 (用棧來存放參數)

        1. assumecs:code
        2. codesegment
        3. start:movax,1
        4. pushax
        5. movax,3
        6. pushax
        7. calldifcube
        8. movax,4c00H
        9. int21H
        10. difcube:pushbp
        11. movbp,sp
        12. movax,[bp+4]
        13. subax,[bp+6]
        14. movbp,ax
        15. mulbp
        16. mulbp
        17. popbp
        18. ret4
        19. codeends
        20. endstart

        上面代碼中的 ret 4 表示:

        pop ip

        add sp,n

        例子:小寫轉大寫,用0結尾來判斷。(用棧來處理寄存器沖突)

        1. assumecs:code,ds:data
        2. datasegment
        3. dbword,0
        4. dbcity,0
        5. dbgood,0
        6. dataends
        7. codesegment
        8. start:movax,data
        9. movds,ax
        10. movcx,3
        11. movbx,0
        12. s:pushcx
        13. movsi,bx
        14. callcapital
        15. addbx,5
        16. popcx
        17. loops
        18. movax,4c00H
        19. int21H
        20. capital:movcl,[si]
        21. movch,0
        22. jcxzok
        23. andbyteptr[si],11011111b
        24. incsi
        25. jmpshortcapital
        26. ok:ret
        27. codeends
        28. endstart

        注意:要用棧保存cx

        例子:實現show_str “函數” 在屏幕顯示字符串。用dh指定函數 ,dl指定列號,cl指定顏色

        1. assumecs:code,ds:data,ss:stack
        2. datasegment
        3. dbWelcometomasm!,0
        4. dataends
        5. stacksegment
        6. dw8dup(0)
        7. stackends
        8. codesegment
        9. start:movax,data
        10. movds,ax
        11. movax,stack
        12. movss,ax
        13. movsp,16
        14. movdh,10;行
        15. movdl,17;列
        16. movcl,2;顏色
        17. movsi,0
        18. callshow_str
        19. movax,4c00h
        20. int21h
        21. show_str:pushax
        22. pushdi
        23. pushdx
        24. movax,10;確定行段es
        25. muldh
        26. addax,0b800h
        27. moves,ax
        28. movdh,0;確定列偏移di,注意,一個字符兩個字節
        29. adddx,dx
        30. movdi,dx
        31. s:pushcx;保存cx
        32. movch,0
        33. movcl,ds:[si]
        34. jcxzok;如果為0跳轉
        35. moves:[di],cl
        36. popcx
        37. moves:[di+1],cl
        38. incsi
        39. adddi,2
        40. jmpshorts
        41. ok:popcx;不要忘記pop,眼不讓rec還原的ip就不對了
        42. popdx
        43. popdi
        44. popax
        45. ret
        46. codeends
        47. endstart



        關鍵詞: 匯編入門callre

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 许昌市| 八宿县| 河东区| 长顺县| 湘乡市| 旺苍县| 咸阳市| 沧源| 长治县| 休宁县| 鄄城县| 云阳县| 花垣县| 鱼台县| 安庆市| 清徐县| 玛曲县| 习水县| 张家港市| 黄大仙区| 沙雅县| 中山市| 藁城市| 泰宁县| 浦江县| 荥经县| 唐山市| 洛宁县| 通江县| 南郑县| 静海县| 云霄县| 瑞金市| 青阳县| 巫溪县| 淮南市| 尉犁县| 汶川县| 安庆市| 搜索| 安龙县|