8086彙編棧段爲何“亂套”了

帶學生在課堂上觀察在子程序調用時機器內部發生變化的細節。
  有同學關注到了棧中的“亂套”。
  程序如下:

assume cs:code, ss:stack
stack segment
       db  16 dup (0)
stack ends
code segment
start: mov ax,stack
       mov ss,ax
       mov sp,16
       mov ax,1000
       call s   ;調用子程序
       mov ax,4c00h
       int 21h
    s: add ax,ax     ;子程序開始
       ret           ;子程序返回
code ends
end start

編譯、連接,並在debug中運行後,界面是:
在這裏插入圖片描述
  容易推算出,此時的棧空間爲076A:0到076A:F。
  亂子始於執行MOV SS, AX。並且,本來單步執行一條指令,但MOV SP, 10H沒有出現,但,SP的值的確已經變了。
  MOV SP, 10H執行過了——是debug自己幹了,沒有給程序員單步的機會。這個和中斷機制相關(在王爽教材12.11和12.12有詳細解釋,在此不詳述)。
  再往後走,可以看見CALL指令執行過程中,棧是按照我們想到的機制進行。

把程序改一下:

assume cs:code, ss:stack
stack segment
       db  16 dup (0)
stack ends
code segment
start: mov ax,stack
       ;mov ss,ax  ;把這一句加了註釋
       mov sp,16
       mov ax,1000
       call s   ;調用子程序
       mov ax,4c00h
       int 21h
    s: add ax,ax     ;子程序開始
       ret           ;子程序返回
code ends
end start

運行後的界面:
在這裏插入圖片描述
  可見,引起棧變化的,就是MOV SP, 10H。(這時,沒有給SS寄存器賦正確的值,這是危險的,SS保持初進入時的0769H。但爲了觀察,也就這樣搗亂一下看看。)
  再往後走,可以看見CALL指令的執行,是按照我們想到的機制進行。
  -----
  初步結論:棧段的“亂套”,來自於修改SP的值。
  引申解釋:修改SP的值時,存在着某種機制使用了棧,從而給棧中留下了一些數據。其實這些數據應該不是隨便的亂數據,當知道更多時,可以找出這些數據的之所以來。
  遺留問題的解決:或許可以從中斷機制中可以找出一些線索,留待以後再說。

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