CSP-S 2020 遊記
一、實驗目的
1.理解和掌握將資料、程式碼、棧放入不同邏輯段的程式的編寫和除錯 2.理解具有多個段的彙編源程式對應的目標程式執行時,記憶體分配方式 3.掌握大小寫字元的轉換方法、數字字元和數值之間的轉換方法4.理解並掌握各種定址方式的靈活應用
5.掌握彙編指令loop, and, or,div, mul的用法
二、實驗準備
複習教材chapter 6-8章。- chapter 6包含多個段的程式
- chapter 7更靈活的定位記憶體地址的方法
- chapter 8資料處理的兩個基本問題
三、實驗內容
1.實驗任務1
使用任意文字編輯器,錄入彙編源程式task1.asm。
1 assume cs:code, ds:data 2 data segment 3 db 'Nuist' 4 db 5 dup(2) 5 data ends 6 7code segment 8 start: 9 mov ax, data 10 mov ds, ax 11 12 mov ax, 0b800H 13 mov es, ax 14 15 mov cx, 5 16 mov si, 0 17 mov di, 0f00h 18 s: mov al, [si] 19 and al, 0dfh 20 mov es:[di], al 21 mov al, [5+si] 22 mov es:[di+1], al 23 inc si 24 add di, 2 25 loop s 26 27 mov ah, 4ch 28 int 21h 29 code ends 30 end start
閱讀源程式,從理論上分析原始碼的功能,尤其是line15-25,迴圈實現的功能是什麼,逐行理解每條指令的功能。
- 使用masm、link對task1.asm進行彙編、連結,得到可執行檔案task1.exe,執行並觀察結果。
- 使用debug工具對程式進行除錯,執行到程式返回前,即line27之前,觀察結果。
- 修改line4裡5個位元組單元的值,重新彙編、連結、執行,觀察結果。
1 db 5 dup(2) 2 --> 改成: 3 db 2,3,4,5,6
基於觀察,分析、猜測這裡的數值作用是什麼。
2.實驗任務2
已知資料段data中定義位元組資料如下:
1 data segments 2 db 23, 50, 66, 71, 35 3 data ends
編寫程式,在螢幕上以十進位制整數形式列印輸出這5個兩位數。
提示:
- 1個兩位數如何輸出
思路如下:
具體處理步驟如下:
第1步,利用除法指令div,計算出每個數位上的數值。
第2步,利用數值和數字字元之間ascII碼的關係,把數值→數字字元
第3步,利用系統功能呼叫int 21h中的2號子功能,輸出單個字元。
int 21h中的2號子功能說明如下:
功能:輸出單個字元
用法:
1 mov ah, 2 2 mov dl, ×× ; ××是待輸出的字元,或其ASCII碼值 3 int 21h
-
5個兩位數如何輸出
利用loop指令,以及,靈活的定址方式。
3.實驗任務3
教材「實驗5編寫、除錯具有多個段的程式」(1)
程式原始碼見task3.asm。
4.實驗任務4
教材「實驗5編寫、除錯具有多個段的程式」(2)
程式原始碼見task4.asm。
5.實驗任務5
教材「實驗5編寫、除錯具有多個段的程式」(3)
程式原始碼見task5.asm。
6.實驗任務6
教材「實驗5編寫、除錯具有多個段的程式」(4)
7.實驗任務7
教材「實驗5編寫、除錯具有多個段的程式」(5)
程式原始碼見task7.asm。
注*:如果在整合軟體環境下編寫、彙編這個實驗任務,請將段名為c的邏輯段,名稱改為c1或別的標識 符。由於早期一些指令集中使用c指代暫存器,如不更正,有些彙編器在彙編時會報錯。
1 c segment ; 段名稱改成c1或別的合法的識別符號 2 ... 3 c ends ; c1
8.實驗任務8
教材「實驗5編寫、除錯具有多個段的程式」(6)
程式原始碼見task8.asm。
四、實驗結論
1.實驗任務1
task1:
1 assume cs:code, ds:data 2 data segment 3 db 'Nuist' 4 db 5 dup(2) 5 data ends 6 7 code segment 8 start: 9 mov ax, data 10 mov ds, ax 11 12 mov ax, 0b800H 13 mov es, ax 14 15 mov cx, 5 16 mov si, 0 17 mov di, 0f00h 18 s: mov al, [si] 19 and al, 0dfh 20 mov es:[di], al 21 mov al, [5+si] 22 mov es:[di+1], al 23 inc si 24 add di, 2 25 loop s 26 27 mov ah, 4ch 28 int 21h 29 code ends 30 end start
程式碼的line15-25是實現了將data segment中存放的字母全部變為大寫,並賦上顏色輸出到視訊記憶體。其中line15記錄了迴圈的次數,line16記錄了ds的起始偏置,line17記錄了視訊記憶體的起始偏置。
從line18開始進入到迴圈,line18其實是mov al, ds:[si],將data segment中的第一個字元“N”傳入到al暫存器中,在line19將al與DFH做與運算,將其轉換為大寫字母,在line20將該大寫字母寫入視訊記憶體,line21和line22實現將顏色資訊傳入到視訊記憶體中。
使用masm、link對task1.asm進行彙編、連結,得到可執行檔案task1.exe,執行並觀察結果。
使用debug工具對程式進行除錯,執行到程式返回前,即line27之前,觀察結果。
修改line4裡5個位元組單元的值,重新彙編、連結、執行,觀察結果。
1 db 5 dup(2) 2 --> 改成: 3 db 2,3,4,5,6
猜想,視訊記憶體字資料中高位位元組裡存放的是顏色資訊,低位位元組裡存放的是內容資訊。IA32採用的是小端存放,所以先存放的是低位內容資訊,後存放的是高位顏色資訊。內容資訊是ASCII碼,顏色資訊是8位顏色資訊。所以line4存放的是顏色資訊。
2.實驗任務2
1 assume cs:code, ds:data 2 data segment 3 db 23, 50, 66, 71, 35 4 data ends 5 6 code segment 7 start: 8 mov ax, data 9 mov ds, ax 10 11 mov cx, 5 12 mov si, 0 13 14 s1: mov bl, 10 15 mov ah, 0 16 mov al, [si] 17 div bl 18 mov bx, ax ;al存放的是商,ah存放的是餘數 19 20 mov ah, 2 21 mov dl, 30h 22 add dl, bl 23 int 21h 24 25 mov dl, 30h 26 add dl, bh 27 int 21h 28 mov dl," " 29 int 21h 30 31 inc si 32 loop s1 33 34 mov ah, 4ch 35 int 21h 36 code ends 37 end start
3.實驗任務3
(1)可以發現數據段內容沒有發生變化。(2)在程式返回前,cs=076C,ss=076B,ds=076A (3)設程式載入後,code段的段地址為X,則data段的段地址為X-2,stack段的段地址為X-1。
4.實驗任務4
(1)data段資料未發生變化,0123H,0456H
(2)在程式返回前,cs=076C,ss=076B,ds=076A
(3)設程式載入後,code段的段地址為X,則data段的段地址為X-2,stack段的段地址為X-1。
(4)對於如下定義的段:
1 name segment 2 ... 3 name ends
如果段中的資料佔N個位元組,則程式載入後,該段實際佔有的空間為 16×⌈N/16⌉ 位元組。
5.實驗任務5
(1)CPU執行程式,程式返回前,data段中的資料為 0123H,0456H(2)CPU執行程式,程式返回前,cs=076AH,ss=076EH,ds=076DH。
(3)設程式載入後,code段的段地址為X,則data段的段地址為X+3,stack段的段地址為X+4。
6.實驗任務6
如果將(1)、(2)、(3)題中的最後一條偽指令“end start”改為“end”(也就是說,不指明程式的入口),則哪個程式仍然可以執行?請說明原因。
答:第(3)題的程式task5.exe仍然可以正確執行,因為如果不指明入口位置,程式就會預設以ip=0執行,而不是從start開始執行,而(3)的data和stack都在code之後,所以ip本來就為0,可以正確執行。
7.實驗任務7
1 assume cs:code 2 a segment 3 db 1,2,3,4,5,6,7,8 4 a ends 5 6 b segment 7 db 1,2,3,4,5,6,7,8 8 b ends 9 10 c1 segment ; 在整合軟體環境中,請將此處的段名稱由c→改為c1或其它名稱 11 db 8 dup(0) 12 c1 ends 13 14 code segment 15 start: 16 mov ax, a 17 mov ds, ax 18 mov cx,8 19 mov si,0 20 21 s: mov ax,[si] 22 add ax,[si+10H] 23 mov [si+20H],ax 24 inc si 25 loop s 26 27 mov ax,4c00H 28 int 21H 29 code ends 30 end start
8.實驗任務8
1 assume cs:code 2 a segment 3 dw 1,2,3,4,5,6,7,8,9,0ah,0bh,0ch,0dh,0eh,0fh,0ffh 4 a ends 5 6 b segment 7 dw 8 dup(0) 8 b ends 9 10 code segment 11 start: 12 mov ax,a 13 mov ds,ax 14 mov ax,b 15 mov ss,ax 16 mov si,0 17 mov cx,8 18 mov sp,10H 19 20 s: push [si] 21 add si,2 22 loop s 23 24 mov ax,4c00h 25 int 21h 26 code ends 27 end start