檢測點6.1
(1)依次用內存0:0~15單元中的內容改寫程序中的數據,補全程序:
assume cs:codesg code segment dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h start: mov ax,0 mov ds,ax mov bx,0 mov cx,8 s: mov ax,[bx] mov cs:[bx],ax ;確定目標區域段地址和偏移地址 add bx,2 loop s mov ax,4c00h int 21h codesg ends end start
(2)程序實現依次用0:0~15單元的內容改寫程序中數據,數據傳送用棧來進行。棧空間設置在程序內,補全程序:
assume cs:codesg code segment dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h dw 0,0,0,0,0,0,0,0,0,0 ;10個字空間作為棧 start: mov ax,cs ;設置棧的段地址 mov ss,ax mov sp,1ah ;cs:0~cs:f為原始數據空間,cs:10~cs:19為棧空間,初始為空,棧頂指向下一單元 mov ax,0 mov ds,ax mov bx,0 mov cx,8 s: push [bx] ;先把0:0處的字單元內容入棧 pop cs:[bx] ;再把棧頂內容出棧放入程序數據段中 add bx,2 loop s mov ax,4c00h int 21h codesg ends end start
實驗5 編寫、調試具有多個段的程序
<程序加載后,ds:0~ff為PSP區域,(ds+10H):0為整個程序的入口,如程序依序設置有data\stack\code3個數據段區域,其中設data和stack段各自為16個字節,那么程序加載后(還未運行前):(ds+10h)則為data的入口段地址;(ds+10h+1)為stack的入口段地址;(ds+10h+2)為code的入口段地址;>
1、編譯連接下面程序,用debug加載、跟蹤,回答問題。
assume cs:codesg,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
程序先把數據段前兩個依序入棧,再出棧返回到各數據原先位置。
(1)CPU執行程序,程序返回前,data段中的數據為多少?
執行程序后,data段中的數據不變,為原始數據。
(2)CPU執行程序,程序返回前,cs=13feh,ss=13fdh,ds=13fch.
(3)程序加載后,code段地址設為X,則data段地址為(x-2),stack段的段地址為(X-1).
注:這里提問的是data段和stack段的段地址分別是多少,程序加載時候,還沒有運行,此時的data段只是邏輯上的數據區,並還沒有設置ds指向;stack也如此,只是設想里的棧區。只有程序運行后才成為真正的ds指向數據區和棧段。通過(2)也可以驗證(3)。
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
本題的重點在於:數據段和棧段在程序加載后實際占據的空間都是以16個字節為單位的。程序中只給出了前兩個字數據,其余空間都用0填充。
(1)CPU執行程序,程序返回前,data段中的數據為多少?
執行程序后,data段有16個字節空間,前兩個字數據不變,其余為0。
(2)CPU執行程序,程序返回前,cs=13feh,ss=13fdh,ds=13fch.
(3)程序加載后,code段地址設為X,則data段地址為(x-2),stack段的段地址為(X-1).
(4)對於如下定義的段:
name segment
......
name ends
如果段中數據位N個字節,程序加載后,該段實際占據空間為[N/16]Byte。
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
本題考查重點是三個段的順序調換后是否有變化?在加載后各數據段的入口段地址必然是改變了。
(1)CPU執行程序,程序返回前,data段中的數據為多少?
運行程序至程序返回前,通過:d ds:0~f查看data段數據,觀察未變。
(2)CPU執行程序,程序返回前,cs=13fch,ss=1400h,ds=13ffh.
(3)程序加載后,code段地址設為X,則data段地址為(x+3),stack段的段地址為(X+4).
4、如果不指名start入口,並且使用end替換end start,程序仍然可以執行。因為如果不指名入口,程序則從加載進內存的第一個單元起開始執行,但因為程序中有部分是作為數據使用的,如果不指明入口,CPU會把這些數值數據當成匯編指令執行,因此有必要通過start來指明入口。
5、編寫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 c segment db 0,0,0,0,0,0,0,0 c ends code segment start: mov ax,a mov ds,ax mov ax,b mov ss,ax mov ax,c mov es,ax mov bx,0 mov cx,8 s: mov al,ds:[bx] add al,ss:[bx] mov es:[bx],al inc bx loop s mov ax,4c00h int 21h code ends end start
6、編寫code段中代碼,用push指令將a段中前8個字型數據逆序存儲到b段中。
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 0,0,0,0,0,0,0,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 ds:[bx] add bx,2 loop s mov ax,4c00h int 21h code ends end start
注:5、6題要鞏固練習通過用debug命令檢查內存來看程序是否執行准確。