實驗3 轉移指令跳轉原理及其簡單應用編程


一、實驗目的

  1. 理解和掌握轉移指令的跳轉原理

  2. 掌握使用call和ret指令實現子程序的方法,理解和掌握其參數傳遞方式

  3. 理解和掌握80×25彩色字符模式顯示原理

  4. 綜合應用尋址方式和匯編指令完成簡單應用編程

二、實驗准備

  復習教材9-10章: 轉移指令的跳轉原理 匯編指令jmp, loop, jcxz, call, ret, retf的用法

三、實驗內容

 實驗任務1:

  task1.asm代碼如下:

 

 1 assume cs:code, ds:data
 2 
 3 data segment
 4     x db 1, 9, 3
 5     len1 equ $ - x
 6 
 7     y dw 1, 9, 3
 8     len2 equ $ - y
 9 data ends
10 
11 code segment
12 start:
13     mov ax, data
14     mov ds, ax
15 
16     mov si, offset x
17     mov cx, len1
18     mov ah, 2
19  s1:mov dl, [si]
20     or dl, 30h
21     int 21h
22 
23     mov dl, ' '
24     int 21h
25 
26     inc si
27     loop s1
28 
29     mov ah, 2
30     mov dl, 0ah
31     int 21h
32 
33     mov si, offset y
34     mov cx, len2/2
35     mov ah, 2
36  s2:mov dx, [si]
37     or dl, 30h
38     int 21h
39 
40     mov dl, ' '
41     int 21h
42 
43     add si, 2
44     loop s2
45 
46     mov ah, 4ch
47     int 21h
48 code ends
49 end start

 

  問題1:程序反匯編截圖如下:

  

 

 

   可以看到Loop處的機器碼為E2F2,這里E2為Loop,而F2的含義是偏移量的補碼形式,我們將F2的2進制(11110010)求補后得10001110,即10進制中的-14,代表向前偏移14個字節,而我們用Loop指令的偏移地址與s1的偏移地址相減時發現偏移量為-12,所以並非從Loop指令處計算,而是從它的下一個指令所在的偏移地址計算,在本題中是001B,用001B和000D相減,可以得到偏移量為-14。CPU應該是先取Loop指令的下一條指令的偏移地址,然后從Loop指令的機器碼后兩位中獲得偏移量的補碼形式,再求補得到偏移量,然后用下一條指令的偏移地址與偏移量相減得到跳轉位置的偏移地址000D。

  問題2:程序反匯編截圖如下:

  

 

 

   可以看到Loop處的機器碼為E2F0,同問題1,由F0(11110000)求補得到10010000,即十進制中的-16,代表向前偏移16個字節,而此時CPU也是從Loop指令的下一條指令的偏移地址0039開始計算,將它與16相減,獲得s2處的偏移地址0029。

  實驗任務2:

  task2.asm源代碼如下:

 

 1 assume cs:code, ds:data
 2 
 3 data segment
 4     dw 200h, 0h, 230h, 0h
 5 data ends
 6 
 7 stack segment
 8     db 16 dup(0)
 9 stack ends
10 
11 code segment
12 start:  
13     mov ax, data
14     mov ds, ax
15 
16     mov word ptr ds:[0], offset s1
17     mov word ptr ds:[2], offset s2
18     mov ds:[4], cs
19 
20     mov ax, stack
21     mov ss, ax
22     mov sp, 16
23 
24     call word ptr ds:[0]
25 s1: pop ax
26 
27     call dword ptr ds:[2]
28 s2: pop bx
29     pop cx
30 
31     mov ah, 4ch
32     int 21h
33 code ends
34 end start

 

  問題1:從理論上看:

  (1)call word ptr將下一條指令的偏移地址壓入棧,再跳轉到相應地址執行命令

       (2)call dword ptr 先將下一條指令的段地址壓入棧,再將下一條指令的偏移地址壓入棧,再跳轉到相應地址執行命令。

       (3)本題ds:[0]中存放的是s1的偏移地址,ds:[2]中存放的是s2的偏移地址,所以第一個call指令先將s1的偏移地址壓入棧,在跳轉到s1處執行pop ax,即將s1的偏移地址0021出棧並存放到ax。

       (4)第二個call指令先將s2處的偏移地址壓入棧,再將s2處的段地址壓入棧,再跳轉到ds:[2]即s2處執行pop bx,即將s2的偏移地址0026出棧並存放到bx,再執行pop cx,即將s2的段地址076C出棧並存放到cx中。

  綜上可得程序執行到line31之前,ax=0021,bx=0026,cx=076C

  問題2:在debug中驗證,反匯編截圖如下:

  

  

  執行到line31之前:

  

  可以看到ax=0021,bx=0026,cx=076C,驗證正確。

  實驗任務3:

  task3.asm代碼編寫如下:

 1 assume ds:data, cs:code
 2 data segment
 3     x db 99, 72, 85, 63, 89, 97, 55
 4     len equ $- x
 5 data ends
 6 
 7 code segment
 8 start:
 9     mov ax, data
10     mov ds, ax
11     mov si, offset x
12     mov cx, len
13     mov byte ptr ds:[10], 10
14     
15 s1:    mov ah, 0
16     mov al, ds:[si]
17 
18     div byte ptr ds:[10]
19     call printNumber
20     call printSpace
21     inc si
22     loop s1
23 
24     mov ax, 4c00h
25     int 21h
26 
27 printNumber:mov bx, ax
28     or bl, 30h
29     or bh, 30h
30     mov ah, 2
31     mov dl, bl
32     int 21h
33     mov dl, bh
34     int 21h
35     ret
36 
37 printSpace:mov ah, 2
38     mov dl, ' '
39     int 21h
40     ret
41     
42 code ends
43 end start

  在debug中調試截圖如下:

  

  實驗任務4:

  task4.asm代碼編寫如下:

 1 assume ds:data, cs:code
 2 data segment
 3     str db 'try'
 4     len equ $ - str
 5 data ends
 6 
 7 code segment
 8 start:
 9     mov ax, data
10     mov ds, ax
11     mov cx, len
12     mov si, offset str
13     mov ax, 0b800h
14     mov es, ax
15     mov di, 0
16     mov ah, 2
17 
18 s:    call printStr
19     inc si
20     add di, 2
21     loop s
22     
23     mov di, 3840
24     mov si, offset str
25     mov cx, len
26     mov ah, 4
27 
28 s1:    call printStr
29     inc si
30     add di, 2
31     loop s1
32     
33     mov ax, 4c00h
34     int 21h
35 
36 printStr:mov al, [si]
37     mov es:[di], al
38     mov es:[di+1], ah
39     ret
40     
41 code ends
42 end start

  在debug中運行截圖如下:

  

  實驗任務5:

  task5.asm代碼如下:

 1 assume ds:data, cs:code
 2 data segment
 3     stu_no db '201983290205'
 4     len = $ - stu_no
 5 data ends
 6 
 7 code segment
 8 start:
 9     mov ax, data
10     mov ds, ax
11     mov cx, 4000
12     mov si, offset stu_no
13     mov ax, 0b800h
14     mov es, ax
15     mov di, 0
16     mov ah,17h
17 
18 s:    mov al, 0
19     mov es:[di], al
20     mov es:[di+1], ah
21     inc si
22     add di, 2
23     loop s
24     
25     mov di, 3840
26     mov si, offset stu_no
27     mov cx, 74
28     mov ah, 17h
29 s1:    call printgang
30     add di, 2    
31     loop s1
32 
33     mov di, 3908
34     mov si, offset stu_no
35     mov cx, len
36     mov ah, 17h
37 s2:    call printStu_no
38     inc si
39     add di, 2
40     loop s2
41     
42     mov di, 3932
43     mov si, offset stu_no
44     mov cx, 74
45     mov ah, 17h
46 s3:    call printgang
47     add di, 2
48     loop s3
49 
50     mov ax, 4c00h
51     int 21h
52 
53 printStu_no:mov al, [si]
54     mov es:[di], al
55     mov es:[di+1], ah
56     ret
57 
58 printgang:mov al, 45
59     mov es:[di], al
60     mov es:[di + 1], ah
61     ret
62     
63 code ends
64 end start

  在debug中運行截圖如下:

 

  四.實驗總結

  經過本次上機實驗,我學習並理解了轉移指令的跳轉原理,了解了Loop指令的機器碼的含義以及如何計算跳轉地址,學會了如何使用call和ret編寫子程序並運用,學習了彩色字符是如何打印在屏幕上的,以及它們的屬性字節中8個數字分別代表的含義,希望在以后能更深入地學習這方面。

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM