[英]Why call and ret functions work like this in assembly?
所以,我在弄亂裝配,偶然發現了奇怪的東西。 在寫任何東西之前,我將寄存器設置為以下值:
AX 0000, BX 0000, SP 00FD.
可以說,我們編寫了簡單的代碼,這增加了寄存器AX和BX:
A100
INC AX
CALL 0200
A200
INC BX
RETN
編寫完之后,我嘗試查看使用T命令逐個執行命令時寄存器如何變化。 第一次,它增加AX
,移至0200
,增加BX
並返回。 這是一個奇怪的位:返回時,它執行命令: ADD [BX+SI],AX
,然后再次調用0200
。
當它再次調用0200
時,它會重復自身,但是現在,當它返回時,它返回到CALL 0100
命令(而不是CALL 0200
)並再次增加AX
,依此類推。 為什么會這樣呢?
我有完整輸出的圖像,也許這可以幫助更好地理解我的問題?: http : //s18.postimg.org/wt6eracg9/Untitled.png
根據您的屏幕截圖,您的代碼似乎是這樣的(用nop
填充,用udcli
分解):
echo 40 e8 fc 00 01 00 e8 f7 00 e8 f4 ff x{1..244} 43 c3 | sed 's/x[0-9]*\>/90/g' | udcli -o 0x100 -x -16
0000000000000100 40 inc ax 0000000000000101 e8fc00 call word 0x200 0000000000000104 0100 add [bx+si], ax 0000000000000106 e8f700 call word 0x200 0000000000000109 e8f4ff call word 0x100 000000000000010c *** never reached *** 0000000000000200 43 inc bx 0000000000000201 c3 ret
代碼流如下,逐行:
0000000000000100 40 inc ax
ax
增加。
0000000000000101 e8fc00 call word 0x200
返回地址0x104被壓入堆棧, ip
(指令指針)設置為0x200。
0000000000000200 43 inc bx
bx
遞增。
0000000000000201 c3 ret
即將返回時,即ip
從堆棧中彈出。 新的ip
將是0x104。
0000000000000104 0100 add [bx+si], ax
將ax
的值添加到[bx+si]
的單詞值上。
0000000000000106 e8f700 call word 0x200
返回地址0x109被壓入堆棧, ip
(指令指針)設置為0x200。
0000000000000200 43 inc bx
bx
遞增。
0000000000000201 c3 ret
即將返回時,即ip
從堆棧中彈出。 新的ip
將為0x109。
0000000000000109 e8f4ff call word 0x100
返回地址0x10c被壓入堆棧, ip
(指令指針)設置為0x100。 因此,這實際上是一個無限遞歸函數,將用完堆棧。
因此,您的問題是您沒有在CALL 0200
之后定義代碼。 恰好是01 00
( add [bx+si], ax
),返回后將執行它,之后執行其他未定義的指令。
我的建議:盡快下載任何不錯的匯編器(NASM,YASM,FASM ...),不要因為嘗試用DEBUG編寫匯編代碼而浪費生命。 嘗試使用DEBUG編寫匯編程序注定會失敗。
可能的原因是您沒有退出,沒有使用DOS的0x4c
服務,並且程序綁定了代碼並開始執行隨機命令,或者執行流程命中了一些ret
指令,其中不使用任何call
,因此然后會表現異常。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.