1. 程式人生 > 實用技巧 >for迴圈和Dowhile迴圈的應用

for迴圈和Dowhile迴圈的應用

一、實驗目的

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 
 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,迴圈實現的功能是什麼,逐行理解每條指令的功能。

  • 使用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 d1,xx      ;xx是待輸出的字元,或其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

使用masm,link對task1.asm進行彙編,連結,得到可執行檔案,執行並觀察結果:

使用debug工具對程式進行除錯:

修改line4裡5個位元組單元的值,重新彙編、連結、執行,觀察結果。

1 db 5 dup(2)
2 --> 改成:
3 db 2,3,4,5,6

猜想:修改之後字元顏色發生了變化,內容沒有變化。通過分析可以得到:db 5 dup(2)表示分配5個位元組記憶體空間並初始化為2,db 2,3,4,5,6 表示分配5個位元組記憶體空間並相應的賦值為2,3,4,5,6。通過上面的結果觀察可知,修改的數值對應著字元的顏色,對內容並無影響。

2.實驗任務2

 1  assume cs:code,ds:data
 2  data segment
 3         db 23,50,66,71,35
 4  data ends
 5  code segment
 6  start:
 7         mov ax,data
 8         mov ds,ax
 9         mov di,0
10         mov cx,5
11 
12 s1:   mov ah,0
13         mov al,ds:[di]
14         mov bl,10
15         div bl
16         mov ds:[10+di],al
17         mov ds:[11+di],ah
18 
19         mov ah,2
20         mov dl,ds:[10+di]
21         add dl,30h
22         int 21h
23 
24         mov ah,2
25         mov dl,ds:[11+di]
26         add dl,30h
27         int 21h
28 
29         mov ah,2
30         mov dl," "
31         int 21h
32     
33         inc di
34         loop s1
35 
36         mov ax,4c00h
37         int 21h
38 code ends
39 end start

3.實驗任務3

 1 assume cs:code, ds:data, ss:stack
 2 data segment
 3   dw 0123h, 0456h, 0789h, 0abch, 0defh, 0fedh, 0cbah, 0987h
 4 data ends
 5 
 6 stack segment
 7   dw 0, 0, 0, 0, 0, 0, 0, 0
 8 stack ends
 9 
10 code segment
11 start:  mov ax,stack
12         mov ss, ax
13         mov sp,16
14         
15         mov ax, data
16         mov ds, ax
17         
18         push ds:[0]
19         push ds:[2]
20         pop ds:[2]
21         pop ds:[0]
22         
23         mov ax,4c00h
24         int 21h
25 
26 code ends
27 end start

(1)執行之後,發現數據段的內容並沒有改變:

(2)在程式返回前,cs=076C,ss=076B,ds=076A (3)設程式載入後,code段的段地址為X,則data段的段地址為X-2,stack段的段地址為X-1。

4.實驗任務4

 1 assume cs:code, ds:data, ss:stack
 2 data segment
 3   dw 0123h, 0456h
 4 data ends
 5 
 6 stack segment
 7   dw 0, 0
 8 stack ends
 9 
10 code segment
11 start:  mov ax,stack
12         mov ss, ax
13         mov sp,16
14         
15         mov ax, data
16         mov ds, ax
17         
18         push ds:[0]
19         push ds:[2]
20         pop ds:[2]
21         pop ds:[0]
22         
23         mov ax,4c00h
24         int 21h
25 
26 code ends
27 end start

(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 assume cs:code, ds:data, ss:stack
 2 
 3 code segment
 4 start:  mov ax,stack
 5         mov ss, ax
 6         mov sp,16
 7         
 8         mov ax, data
 9         mov ds, ax
10         
11         push ds:[0]
12         push ds:[2]
13         pop ds:[2]
14         pop ds:[0]
15         
16         mov ax,4c00h
17         int 21h
18 
19 code ends
20 data segment
21   dw 0123h, 0456h
22 data ends
23 
24 stack segment
25   dw 0,0
26 stack ends
27 end start

(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”(也就是說,不指明程式的入口),則哪個程式仍然可以執行?請說明原因。

答:只有任務5的彙編程式可以正常執行。因為任務5程式的程式碼段定義於資料段和棧段之前,在順序執行的過程中會首先執行code segment,而不會因執行了data segment和stack segment導致程式出現不符合預期的情況。

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       mov ax,4c00h
27       int 21h
28 code ends
29 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  
15        mov ax,b
16        mov ss,ax
17        mov sp,16
18        mov si,0
19  
20        mov cx,8
21  
22 s:     push ds:[si] 
23        add  si,2
24        loop s
25        mov ax,4c00h
26        int 21h
27 code ends
28 end start