1. 程式人生 > >【實驗五】編寫、調試具有多個段的程序

【實驗五】編寫、調試具有多個段的程序

bubuko 中文 clas round lose dup 聲明 margin 提示

四、實驗結論

*任務(1)(2)(3)基本步驟相同,這裏只列舉出(1)的實驗步驟

步驟一:把要使用的代碼粘貼到masm文件夾中。

技術分享圖片步驟二:編譯、連接、用debug調試。

步驟三:用r命令查看哥寄存器的值。

    cs是code的段地址,ds是data的段地址,ss是stack的段地址。這是因為代碼前面的聲明: assume cs:code, ds:data, ss:stack

技術分享圖片

步驟四:用u命令反匯編,註意反匯編是code段,所以u命令後接的應該是cs。

步驟五:用g命令執行,根據反匯編得到的代碼,執行到mov ax,4c00之前。這裏g命令的使用是斷點的使用。

技術分享圖片

步驟六:使用d命令查看data段的值。由於data的段地址是ds,所以從ds:0到ds:f查看16個字節。

技術分享圖片

*任務(2)(3)步驟大同小異,這裏就不多列舉了。


實驗結果:

任務一:

技術分享圖片

任務二:

技術分享圖片

任務三:

技術分享圖片

任務四:

任務一修改:

技術分享圖片

任務二修改:

技術分享圖片

任務三修改:

技術分享圖片

結論:從反匯編可以看出,把end start改成end後,只有實驗三可以正常運行。

分析:start提供程序的入口,使cs:ip 指向第一條要執行的指令。任務一和任務二的代碼中,匯編指令代碼段並不是在開頭,所以cs:ip在默認的開頭;任務三的匯編指令代碼在開頭,cs:ip剛好指向她。


關於任務二的第4小問:舉ex5_1為例;其存儲數據的段地址是ds。

①ex5_1源代碼:

技術分享圖片
assume cs:code, ds:data, ss:stack
data segment
  dw 0123h, 0456h, 0789h, 0abch, 0defh, 0fedh, 0cbah, 0987h
data ends

stack segment
  dw 
0, 0, 0, 0, 0, 0, 0, 0 stack ends code segment start: mov ax,stack mov ss, ax mov sp,16 mov ax, data mov ds, ax push ds:[0] push ds:[2] pop ds:[2] pop ds:[0] mov ax,4c00h int 21h code ends end start
View Code

經過編譯連接運行後,使用r命令查看,ds=075a , ss=076b , cs=076c,這意味著給data段落分配了10h,即16字節的空間。

技術分享圖片

②ex5_1_2源代碼(data段落的字節給了17個字節的數據): (此步驟也可以使用任務三的各個寄存器的值)

技術分享圖片
assume cs:code, ds:data, ss:stack
data segment
  dw 0123h, 0456h, 0789h, 0abch, 0defh, 0fedh, 0cbah, 0987h,0123h
data ends

stack segment
  dw 0, 0, 0, 0, 0, 0, 0, 0
stack ends

code segment
start:  mov ax,stack
        mov ss, ax
        mov sp,16
        
        mov ax, data
        mov ds, ax
        
        push ds:[0]
        push ds:[2]
        pop ds:[2]
        pop ds:[0]
        
        mov ax,4c00h
        int 21h

code ends
end start
View Code

經過編譯連接運行後,使用r命令查看,ds=075a , ss=076c , cs=076d,這意味著給data段落分配了20h,即32字節的空間。

技術分享圖片

結論:由此看來,儲存的數據不足16字節,給他分配16字節的空間;儲存的數據多於16字節的整數倍,則會給多余的、不滿16字節的數據分配一整的16字節的空間。

答案:(N/16+1)*16


另外,在修改程序的過程中,如果把英文字符寫成中文字符,例如:把 ”,“ 寫成 ”,“,會出現如下錯誤:

技術分享圖片


任務五:

源代碼:

assume cs:code, ds:a, es:b, ss:c
a segment
  db 1,2,3,4,5,6,7,8
a ends

b segment
  db 1,2,3,4,5,6,7,8
b ends

c segment  
  db 8 dup(0)
c ends      

code segment
start:
mov ax,a
      mov ds,ax
mov ax,b mov es,ax mov ax,c mov ss,ax
mov cx,8
mov bx,0
 s: mov al, ds:[bx]
    add al, es:[bx]
    mov ss:[bx],al
    inc bx
    loop s

    mov ax,4c00h
    int 21h
code ends
end start


①編譯、連接

技術分享圖片

②debug執行,d命令查看c段

技術分享圖片

③u命令反匯編,g命令執行

技術分享圖片

④d命令查看c段

技術分享圖片

任務六:

assume cs:code,ds:a,ss:b
a segment
     dw 1,2,3,4,5,6,7,8,9,0ah,0bh,0ch,0dh,0eh,0fh,0ffh
a ends

b segment
    dw 8 dup(0)
b ends

code segment
 start: 
    mov ax,a
    mov ds,ax
    mov ax,b
    mov ss,ax
    mov sp,10H
    mov bx,0
    mov cx,8
  s:push [bx]
    add bx,2
    loop s
    mov ax,4c00h
    int 21h
code ends
end start

①編譯、連接

技術分享圖片

②d命令查看執行前ss段

技術分享圖片

③debug執行,r命令查看各寄存器初始值,u命令反匯編,g命令斷點執行

技術分享圖片

④d命令查看執行後ss段

技術分享圖片


五、總結與體會

實驗沒有什麽難處,主要是在任務二的第四小題,看是看不出來的,必須通過實驗來測試。

實驗的好處真的挺多的,還可以發現許多微小錯誤,比如,把英文字符寫成中文字符時的提示等等。

【實驗五】編寫、調試具有多個段的程序