实验3 转移指令跳转原理及其简单应用编程

四、实验结论

1. 实验任务1

给出程序task1.asm源码,及,运行截图

 1 assume cs:code, ds:data
 2 
 3 data segment
 4     x db 1, 9, 3   ;x初始值是0(偏移地址)
 5     len1 equ $ - x ; 符号常量, $指下一个数据项的偏移地址,这个示例中,是3
 6 
 7     y dw 1, 9, 3   ;y是3
 8     len2 equ $ - y ; 符号常量, $指下一个数据项的偏移地址,这个示例中,是9
 9 data ends
10 
11 code segment
12 start:
13     mov ax, data
14     mov ds, ax
15 
16     mov si, offset x ; 取符号x对应的偏移地址0 -> si
17     mov cx, len1 ; 从符号x开始的连续字节数据项个数 -> cx
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

回答问题①

① line27, 汇编指令 loop s1 跳转时,是根据位移量跳转的。通过debug反汇编,查看其机 器码,分析其跳转的位移量是多少?(位移量数值以十进制数值回答)从CPU的角度,说明 是如何计算得到跳转后标号s1其后指令的偏移地址的。

机器码:F2(h) --> 11110010(b) --> 00001110(b) --> -12(d十进制) (补码-->原码)
位移量的计算: d(h) - 19(h) -->13-25= -12(d十进制)
CPU根据目标偏移地址减去当前偏移地址得到位移量,计算得到跳转后标号s1其后指令的偏移地址的。

回答问题②

② line44,汇编指令 loop s2 跳转时,是根据位移量跳转的。通过debug反汇编,查看其机 器码,分析其跳转的位移量是多少?(位移量数值以十进制数值回答)从CPU的角度,说明 是如何计算得到跳转后标号s2其后指令的偏移地址的。

 位移量:F0(h)

问题③

③ 附上上述分析时,在debug中进行调试观察的反汇编截图

 2. 实验任务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

 给出分析、调试、验证后,寄存器(ax) = ? (bx) = ? (cx) = ? 附上调试结果界面截图。

① 根据call指令的跳转原理,先从理论上分析,程序执行到退出(line31)之前,寄存器(ax) = ? 寄存器(bx) = ? 寄存器(cx) = ?

寄存器(ax) = S1的偏移地址 寄存器 (bx) = S2的偏移地址 寄存器(cx) = S2的段地址

② 对源程序进行汇编、链接,得到可执行程序task2.exe。使用debug调试,观察、验证调试 结果与理论分析结果是否一致。

一致。

3. 实验任务3

给出程序源码task3.asm

 1 assume cs:code, ds:data
 2  
 3 data segment
 4     x    db  99, 72, 85, 63, 89, 97, 55
 5     len    equ $- x
 6 data ends
 7  
 8 code segment
 9     main:     
10         mov ax, data
11         mov ds, ax
12         
13         mov cx, len
14         mov si, offset x
15     print:
16         mov al, [si]
17         mov ah, 0
18         call printNumber
19         call printSpace
20         inc si
21         loop print
22  
23         mov ah, 4ch
24         int 21h
25  
26     ;功能:以十进制形式输出一个两位数
27     ;入口参数:寄存器ax(待输出的数据 --> ax)
28     ;出口参数:无
29     printNumber:
30         mov bl, 10
31         div bl
32         mov bx, ax
33         
34         mov ah, 2
35  
36         mov dl, bl    ; 打印商(10位)
37         or dl, 30h
38         int 21h
39  
40         mov dl, bh    ; 打印余数(个位)
41         or dl, 30h
42         int 21h
43         ret
44              
45     printSpace:
46         mov ah, 2
47         mov dl, ' '
48         int 21h
49         ret
50  
51 code ends
52 end main

运行测试截图

4. 实验任务4

给出程序源码task4.asm

 1 assume cs:code
 2 data segment
 3     str db    'try'
 4     len equ    $ - str
 5 data ends
 6 code segment
 7     main:
 8         mov ax, 0b800h
 9         mov es, ax
10     
11     first_print:
12         mov ax, data
13         mov ds, ax
14         mov si, offset str
15         mov cx, len
16         mov bl, 00000010b    ; 黑底绿字
17         mov bh, 0            ; 第0行
18         call printStr
19     
20     second_print:
21         mov si, offset str
22         mov cx, len
23         mov bl, 00000100b    ; 黑底红字
24         mov bh, 24            ; 第24行
25         call printStr
26     
27         mov ah, 4ch
28         int 21h
29  
30     ; 入口参数:
31       ;    字符串首字符地址 --> ds:si(其中,字符串所在段的段地址—> ds, 字符串起始地址的偏移地址—> si)
32       ;    字符串长度 --> cx
33       ;    字符串颜色 --> bl
34       ;    指定行 --> bh (取值:0 ~2435     printStr:
36         push bp        
37         push di
38  
39         mov ah, 0
40         mov al, 160
41         mul bh                    
42         mov bp, ax                    
43         mov di, si                    
44         printChar:
45             mov al, ds:[si]
46             mov es:[bp+di], al        ; 字符
47             mov es:[bp+di+1], bl    ; 颜色
48             inc si
49             inc di
50             inc di                    
51             loop printChar
52         
53         pop bp                        
54         pop di
55         ret 
56 code ends
57 end main

运行测试截图

5. 实验任务5

给出程序源码task5.asm

 1 assume cs:code, ds:data
 2 data segment
 3     stu_no db '201983290357'
 4     len = $ - stu_no
 5 data ends
 6  
 7 code segment
 8     main:
 9         call print_blue_screen
10         call print_stu_no
11  
12         mov ah, 4ch
13         int 21h
14     print_blue_screen:
15         push ax        
16         push es
17         push si
18  
19         mov ax, 0b800h
20         mov es, ax
21         mov cx, 2000
22         mov si, 1
23         single_blue:
24             mov byte ptr es:[si], 00010000b
25             inc si
26             inc si
27             loop single_blue
28         
29         pop si        
30         pop es
31         pop ax        
32     ret
33     
34     print_stu_no:
35         push ax        
36         push es
37         push si
38         push ds
39         push di
40     prefix:
41         mov ax, 0b800h
42         mov es, ax
43         mov cx, 34
44         mov si, 3840    ; si存放每次显存输出的偏移地址
45         call print_dash
46     content:
47         mov ax, data
48         mov ds, ax
49         mov cx, len
50         mov di, 0        ; di存放data中每个字符的偏移地址
51         single_no:
52             mov al, ds:[di]
53             inc di
54             mov byte ptr es:[si], al 
55             inc si
56             mov byte ptr es:[si], 00010111b
57             inc si
58             loop single_no
59     postfix:
60         mov cx, 34
61         call print_dash
62         
63         pop di
64         pop ds
65         pop si
66         pop es
67         pop ax
68     ret
69     
70     ;    输入参数:
71     ;    显示的基地址si
72     ;    输出长度cx
73     ;    输出:
74     ;    迭代后的基地址si
75     print_dash:
76         single_dash:
77             mov byte ptr es:[si], '-'
78             inc si
79             mov byte ptr es:[si], 00010111b
80             inc si
81             loop single_dash
82     ret
83  
84 code ends
85 end main

运行测试截图

五、实验总结

1.符号常量, $指下一个数据项的偏移地址。

2.EQU是等值命令:

COUNT EQU 100;令COUNT的值为100,存储器中为变量分配 0个字节;
COUNT DB 100 ;应该是令count的值为100的偏移地址。

3.OFFSET 运算符返回数据标号的偏移量。这个偏移量按字节计算,表示的是该数据标号距离数据段起始地址的距离。

posted @ 2021-12-03 00:04  TT524  阅读(165)  评论(1编辑  收藏  举报