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

【實驗五】編寫、除錯具有多個段的程式

四、實驗結論

*任務(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段


 

五、總結與體會

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

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