2011-11-01 242 views
0

本節讓我徹底困惑。我有一個例子問題,我希望有人可以爲我分解步驟,以便我可以吸收它如何應用於其他問題。彙編語言子程序

mc: call subr 
mr: mov [val],ax 
subr: push ax 
     push bx 
     push cx 
     add ax,dx 
     pop ax 
     pop bx 
     pop cx 
     ret 

書要求在SP和AX寄存器中的十六進制值將是什麼時,代碼從子程序返回併到達指令mr: mov [val],axsp=0100 ax=0002,但我不知道如何得出這些答案。

指令mc: call subr將下一個順序指令mr: mov [val],ax的地址保存在堆棧上,以便子例程可以正確返回。存儲返回地址的內存中的絕對地址是1120E。任何人都可以請詳細說明這一點?

registers given: 
ax = 0000 bx = 0001 cx = 0002 dx = 0004 
si = 0000 di = FFFF bp = 0080 sp = 0100 
cs = 1000 ds = 1100 es = 1110 ss = 1111 
+0

這裏顯示了哪種類型的彙編語言? –

回答

1

mc:呼叫將保存當前的地址,所以當subr:回報,控制將再次在mr:開始。

由於subr:按此順序推動ax,bx和cx。然後按照順序彈出ax,bx和cx,所以從cx彈出的東西被彈出到ax中(反之亦然)。這些的作用是交換ax和cx。 add ax, dx對產生的結果沒有實際影響,因爲在將ax添加到ax之後,它將軸從堆棧中彈出。 add確實會影響標誌,但這裏沒有任何內容會根據標誌做任何事情,所以至少在你顯示的代碼中,這也沒有多大意義。

控制返回到mr:後,它將ax中的值寫入內存,然後返回到subr:,從而將ax和cx交換回它們開始的位置。

督察,整體而言,這是實現大致相同效果的一個非常緩慢的,迂迴的方式:

mc: mov [val], cx 
    ret 

至於絕對地址去,沒有太多可說的。特別是,如果你再次運行相同的代碼,它可能會被加載到不同的地址,所以保存在堆棧中的地址可能完全不同。

+0

感謝您的快速響應。我認爲我現在更瞭解推動和流行,但是在什麼情況下更改了「sp」?我更新了原來的帖子以顯示給定的寄存器,所以也許你可以幫助解釋我如何用這些值來計算絕對地址。 – raphnguyen

+0

@raphnguyen:絕對地址,你需要PC寄存器,這不包括在你列出的。 'sp'被任何推動或彈出堆棧的東西(包括'call'中的隱式push和'ret'中的隱式pop)所改變。 –

+0

嗯奇怪,我想知道爲什麼這本書選擇了1120E作爲五個地址組中的絕對地址。所以,因爲有3個「推」呼叫和3個「流行」呼叫,他們互相抵消了嗎?我似乎無法找到與「sp」行爲對應的部分。它是否隨着每個'push'而增加,並且隨着每個'pop'而遞減? – raphnguyen