1. 程式人生 > >實驗1 —— 用機器指令和匯編指令編程(2)

實驗1 —— 用機器指令和匯編指令編程(2)

也好 neo 語言 計算 技術分享 block 常識 沒有 結果

debug 指令補充

在執行 d 命令時可以帶地址參數 (段地址: 偏移地址),其中的段地址會先被送到 ds 寄存器,再交給處理器。

因此,d 命令也可以這樣用: d SR:offset (SR指段寄存器)
例如:

-r ds 
:1000
-d ds:0         ;查看從 1000:0 開始的內存區間中的內容
-r ds
:1000
-d ds:10 18     ;查看 1000:10 ~ 1000:18 中的內容
-d cs:0         ;查看當前代碼段中的指令代碼
-d ss:0         ;查看當前棧段中的內容

當然 e 命令、a 命令和 u 命令也是一樣的。
例如:

-r ds
:1000
-e ds:0 11 22 33 44 55 66        ;在從 1000:0 開始的內存區間中寫入數據 
-u cs:0         ;以匯編指令的形式,顯示當前代碼段中的代碼,0 代碼的偏移地址
-r ds
:1000
-a ds:0         ;以匯編指令的形式,向從 1000:0 開始的內存單元中寫入指令

有趣的現象

在執行以下的代碼時,你會發現 t 命令會不管用:

mov ax, 2000        ; 1
mov ss, ax          ; 2
mov sp, 10          ; 3

mov ax, 3123        ; 4
push ax             ; 5
mov ax, 3366        ; 6
push ax             ; 7

單步執行結果如下圖所示:

技術分享圖片

技術分享圖片

可見第 2 行和第 3 行代碼一起執行了 (我這裏與書本上的展示不同,可能與軟件版本有關)。
具體是怎麽回事以後深究,我們需要知道的是: 在執行修改 ss 寄存器的指令時,下一條指令會被一並執行。

實驗

本實驗為《匯編語言》(王爽著,第 3 版)第 74 頁 實驗任務

  1. 將下面的程序寫入內存,執行並填空:

    為了便於驗證實驗結果,對該實驗做如下兩點調整:
    1. 在使用 a 命令輸入指令調試前,使用 e 命令將內存單元 0021:00021:7 連續 8 個字節數據修改為 30H, 31H, 32H, 33H, 34H, 35H, 36H, 37H
    2. 將該實驗中第 1 行的 mov ax, ffff
      改為 mov ax, 0021
    mov ax, 0021
    mov ds, ax
    
    mov ax, 2200
    mov ss, ax
    mov sp, 0100
    
    mov ax, [0] ; ax = _3130_
    add ax, [2] ; ax = _6462_
    mov bx, [4] ; bx = _3534_
    add bx, [6] ; bx = _6c6a_
    
    push ax      ; sp =  _00fe_ ; 修改的內存單元的地址是 _220fe_ 內容為 _6462_
    push bx      ; sp =  _00fc_ ; 修改的內存單元的地址是 _220fc_ 內容為 _6c6a_
    pop ax       ; sp =  _00fe_ ; ax = _6c6a_
    pop bx       ; sp =  _0100_ ; bx = _6462_
    
    push [4] ; sp =  _00fe_ ; 修改的內存單元的地址是 _220fe_ 內容為 _3534_
    push [6] ; sp =  _00fc_ ; 修改的內存單元的地址是 _220fc_ 內容為 _3736_

    填空已經寫進了註釋,運行結果如下圖所示:

    技術分享圖片

    技術分享圖片

    技術分享圖片

    技術分享圖片

    技術分享圖片

    這個實驗在 FreeDOS 中會報錯,如下圖所示:

    技術分享圖片

    最後不得不用了 MS-DOS,我分析原因是 FreeDOS 不完全兼容 16 位匯編出現 operand size mismatch

  2. 為什麽 2000:0 ~ 2000:f 中的內容會發生改變?

    運行結果如下圖所示:

    技術分享圖片

    技術分享圖片

    仔細觀察執行後 2000:a2000:d 內存中的數據,可見正好是依照小端法存儲的 csip 的值,據網上資料所說,這是對定義棧段時部分運行環境變量進行暫存,靠近棧頂的 10 個字節中的暫存數據分別是 ssipcs 等的值,是否正確我尚未考證,但應該與系統的調度有關。

我認為匯編是計算機專業的必修課,在計算機系統中也好,單獨作為一門課程也罷,真正需要學習的不是怎麽用,這是為了彌補一個計算機專業學生的基本常識。如果只是覺得什麽東西有用而學它,那是沒有回報的。如果你只看到一件事的1%,不代表你看到了它剩下的99%。在一切因素都不確定的情況下,能做好自己本分又有多少。幹些什麽吧,趁自己還年輕。

Invictus maneo.

實驗1 —— 用機器指令和匯編指令編程(2)