assembly language 實驗3 多個段的彙編源程式編寫與除錯
實驗內容
實驗任務1
使用任意文字編輯器,錄入彙編源程式task1.asm。
assume cs:code, ds:data data segment db 'Nuist' db 5 dup(2) data ends code segment start: mov ax, data mov ds, ax mov ax, 0b800H mov es, ax mov cx, 5 mov si, 0 mov di, 0f00h s: mov al, [si] and al, 0dfh mov es:[di], al mov al, [5+si] mov es:[di+1], al inc si add di, 2 loop s mov ah, 4ch int 21h code ends end start
理論分析:
程式首先將Data段中的資料的小寫字母轉化為大寫字母,同時將顏色轉變為綠色然後移動資料到顯示卡記憶體上使之顯示出來。
實驗步驟:
實驗任務2
已知資料段data中定義位元組資料如下:
data segments
db 23,50,66,71,35
data ends
編寫程式,在螢幕上以十進位制整數形式列印輸出這5個兩位數。
編寫程式碼:
assume cs:code, ds:data data segment db 23,50,66,71,35 data ends code segment start: mov ax,data mov ds,ax mov dh,0ah mov di,0 mov cx,5 s: mov al,[di] mov ah,00h div dh add al,30h ;數字與字元相差48,即16進位制30h add ah,30h mov bx,ax inc si mov ah,2 mov dl,bl int 21h mov dl,bh int 21h loop s mov ah,4ch int 21h code ends end start
實驗步驟;
實驗任務3
教材「實驗5 編寫、除錯具有多個段的程式」(1)
將下面的程式編譯、連線,用Debug載入、跟蹤,然後回答問題
···
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
···
回答問題:
-
CPU執行程式,程式返回前,data段中的資料為多少?
答:data段中資料為23 01 56 04 89 07 BC 0A EF 0D ED 0F BA 0C 87 09 -
CPU執行程式,程式返回前,cs=?, ss=?, ds=?
答:cs:076C, ss:0769, ds:075A -
設程式載入之後, code段的段地址為X,則data段的段地址為?,stack段的段地址為?
答:data段的段地址為X-1,stack段的段地址為X-2
實驗任務4
教材「實驗5 編寫、除錯具有多個段的程式」(2)
將下面的程式編譯、連線,用Debug載入,追蹤,然後回答問題。
assume cs:code, ds:data, ss:stack
data segment
dw 0123h, 0456h
data ends
stack segment
dw 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
回答問題:
-
CPU執行程式,程式返回前,data段中的資料為多少?
答:data段中資料為23 01 56 04 -
CPU執行程式,程式返回前,cs=?, ss=?, ds=?
答:cs:076C, ss:0769, ds:075A -
設程式載入之後, code段的段地址為X,則data段的段地址為?,stack段的段地址為?
答:data段的段地址為X-1,stack段的段地址為X-2 -
對於如下定義的段:
name segment
...
name ends
如果段中資料佔N個位元組,則程式載入之後,該段實際佔有的空間為?
答:該段實際佔有的空間為⌈N/16⌉*16位元組
實驗任務5
教材「實驗5 編寫、除錯具有多個段的程式」(3)
將下面的程式編譯、連線,用Debug載入,追蹤,然後回答問題。
assume cs:code, ds:data, ss:stack
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
data segment
dw 0123h, 0456h
data ends
stack segment
dw 0,0
stack ends
end start
回答問題:
-
CPU執行程式,程式返回前,data段中的資料為多少?
答:data段中資料為23 01 56 04 89 07 BC 0A EF 0D ED 0F BA 0C 87 09 -
CPU執行程式,程式返回前,cs=?, ss=?, ds=?
答:cs:076A, ss:0769, ds:075A -
設程式載入之後, code段的段地址為X,則data段的段地址為?,stack段的段地址為?
答:data段的段地址為X-1,stack段的段地址為X-2
實驗任務6
教材「實驗5 編寫、除錯具有多個段的程式」(4)
如果將(1)、(2)、(3)題中的最後一條偽指令”end start“改為”end“也就是說不知名程式的入口),則哪個程式任然可以正確執行?請說明理由。
(3)題中的程式可以正確執行,因為end start是指定程式的入口,如果刪掉start,那麼機器會將程式碼一開始作為程式的入口,但是(1)(2)中程式碼開始定義的是data段和stack段,只有(3)
將code段放在了開頭,所以能夠正確執行。
實驗任務7
編寫code段中的程式碼,將a段和b段中的資料依次相加,將結果存到c段。
···
assume cs:code
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
c1 segment ; 在整合軟體環境中,請將此處的段名稱由c→改為c1或其它名稱
db 8 dup(0)
c1 ends
code segment
start:
mov ax,a
mov ds,ax
mov bx,0
mov cx,8
s: mov ax,ds:[bx]
add ax,ds:[bx+16]
mov ds:[bx+32],ax
inc bx
loop s
mov ah,4ch
int 21h
code ends
end start
···
實驗任務8
教材「實驗5 編寫、除錯具有多個段的程式」(6)
程式如下:編寫code段中的程式碼,用push指令將a段中前8個字型資料逆序儲存到c段中。
assume cs:code
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 bx,0
mov cx,8
s: push ds:[bx]
add bx,2
loop s
mov ax,b
mov ds,ax
mov bx,0
mov cx,8
qs: pop ds:[bx]
add bx,2
loop qs
mov ah,4ch
int 21h
code ends
end start
回到頂部
- 1.學習到了單個字元列印方式,利用int 21h的二號子功能,可以實現列印字元。
- 2.每一個數據段的空間只能是16的倍數,可以通過這個計算資料空間,結合cx的值,減去mov ah,4c00h佔用的兩個位元組進行精確的反彙編。 同時每個單獨宣告的資料段佔據不同16倍數字節。
- 3.資料段開闢的順序與在程式碼中宣告的順序有關,先宣告的在前面,後宣告的在後面。“end start”語句的作用是確定程式執行的入口,如果 省略start會導致程式入口被機器確定在開頭,而後者往往是資料段的位置,導致程式執行出錯。
- 4.棧具有先進後出的特點,可以用來順序或者逆序儲存資料。