activity 帶資料跳轉
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
進行debug,使用r命令觀察接著根據CX進行反彙編
發現反彙編的結果並不是完全正確,多了很多冗餘資料,使用g命令執行到程式結束之前:
進行修改:
重新進行編譯連線:
發現NUIST的IST顏色變色了,所以我猜測這裡的資料作用是改變字串的顏色資訊
2.實驗任務2
已知資料段data中定義位元組資料如下: data segments db 23, 50, 66, 71, 35 data ends 編寫程式,在螢幕上以十進位制整數形式列印輸出這5個兩位數。 先把ds指向資料段,定好迴圈次數cx為5次 定義迴圈s:因為資料段中的每個十位數僅有8個字型資料,所以用al來儲存 接著使用div除法命令,商存入al,而餘數存在ah中 接著將ax複製到dx中並且加上3030H使得數字轉化成數字字元 根據老師所給的int 21h的2號子功能,最後輸出的是dl中的內容 所以先直接輸出一次接著將dh複製到dl中在輸出一次即為一個十進位制數的輸出過程 一次迴圈結束,將ds指向向後移一位,開始下一次迴圈直到五次結束。 程式碼如下: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 cx,5 s: mov ah,0 mov al,ds:[di] mov bl,10 div bl mov dx,ax add dx,3030H mov ah,2 int 21h mov dl,dh mov ah,2 int 21h inc di loop s mov ah,4CH int 21h code ends end start
進行編譯連線並執行:
得到了輸出結果23,50,66,71和35
3.實驗任務3
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
教材問題1:CPU執行程式,程式返回前,data段中的資料為多少?
理論分析來說,不會發生變化
原來data段中存放的資料:到程式返回前,data段中存放的資料為:
執行到程式結束前的資料段:
問題2:CPU執行程式,程式返回前,cs=,ss=,ds=
根據問題1的第二張圖片可得:cs=076C,ss=076B,ds=076A
問題3:設程式載入後,code段的段地址為X,則data段的段地址為,stack段的段地址為
data段的段地址為X-2,stack段的段地址為X-1,因為程式開始前data定義了16個位元組空間的資料,stack定義了16個位元組空間的資料,所以每一個段相差16個即10h個位元組。
4. 實驗任務4assume 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
1.CPU執行程式,程式返回前,data段中的資料為多少?
進入程式進行反彙編到程式返回前
檢視資料段中的值
由程式得,data段中的資料應為4個位元組的內容即0123h,0456h
2.CPU執行程式,程式返回前,cs=,ss=,ds=?
由上圖得,cs=076C,ss=076B,ds=076A
3.設程式載入後,code段的段地址為X,則data段的段地址為,stack段的段地址為
data:X-2,stack:X-1
4.首先佔用的位元組數最少為16個且一定為16的倍數,如果N可以整除16,那麼
佔有的空間就為N個位元組,如果不可以,實際佔有的空間為(N/16+1)*16
5.實驗任務5
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段中的資料為多少?
data段仍舊佔4個位元組,為0123h,0456h
2.CPU執行程式,程式返回前,由執行結果可以看出cs=076A,ss=076E,ds=076D
3.設程式載入後,code段的段地址為X,則data段的段地址為,stack段的段地址為
data段的段地址為X+3,stack段的段地址為X+4
6.實驗任務6
如果將實驗任務3,4,5中的最後一條偽指令“end start”改為“end”(也就是說,不指明程式的入口),則哪個程式仍然可以正確執行?請說明原因
解:只有實驗任務5的程式還可以正確執行,因為實驗任務5的程式的資料段和棧段都定義在程式的code段後,u命令反彙編的情況下不會影響,而實驗任務3,4都定義在code段前,前面定義的data段和棧段中的資料會當作程式碼進行反彙編,無法正確執行。
7.實驗任務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 di,0 mov cx,8 s: mov si,a mov ds,si mov al,ds:[di] mov si,b mov ds,si add al,ds:[di] mov si,c1 mov ds,si mov ds:[di],al inc di loop s mov ax,4c00h int 21h code ends end start
執行到程式結束前,用d命令檢視現在DS存放的內容
發現結果為02 04 06 08 0A 0C 0E 10,完成了要求
8.實驗任務8
編寫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 8 dup(0) b ends code segment start: mov di,0 mov cx,8 s: mov si,a mov ds,si push ds:[di] inc di inc di loop s mov di,0 mov cx,8 s1: mov si,b mov ds,si pop ds:[di] inc di inc di loop s1 mov ax,4c00h int 21h code ends end start
一開始想著逆序輸出到b段中就在第二個迴圈中將bi的初始值設成16,然後dec兩次,
嘗試了幾次發現還是正序,才想到棧的pop函式本身就是先入後出的逆序過程,
我相當於逆序的逆序還是正序了,接著直接進行同樣的步驟執行得到了結果
三、實驗總結
總體來說這次的實驗讓我很清晰的理解了段的分配機制,data段和棧段,定義段的位置
都會對結果產生莫大的影響,最後一個實驗任務還讓我對棧的知識回顧了一下,實驗任務2
讓我重新看了書本上div指令的部分,商預設儲存在al中,ah預設儲存餘數,int 21h的二號子命令
是輸出dl中的內容