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

四、实验结论

1.实验任务1

  • 程序task1.asm源码

 

 1 assume cs:code, ds:data
 2 
 3 data segment
 4     x db 1, 9, 3
 5     len1 equ $ - x    ; 符号常量,$指下一个数据项的偏移地址,这个示例中,是3
 6 
 7     y dw 1, 9, 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    ; 取符号y对应的偏移地址3 -> si
34     mov cx, len2/2    ; 从符号y开始的连续字数据项个数 -> cx
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

 

运行截图:

 

  • 回答问题①

读取汇编指令loop s1时,IP指向001B,执行该指令后IP指向000D。其跳转的位移量是-14。指令对应的机器码E2F2中F2是跳转位移量-14的十六进制补码。CPU将跳转位移量与IP值相加,得到下一条要执行指令的IP,即000D。

  • 回答问题②

读取汇编指令loop s2时,IP指向0039,执行该指令后IP指向0029。其跳转的位移量是-16。指令对应的机器码E2F0中F0是跳转位移量-16的十六进制补码。CPU将跳转位移量与IP值相加,得到下一条要执行指令的IP,即0029。

 

  • 问题③

 

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

 

  • ①CPU在执行call指令时,会将当前ip(或cs和ip)入栈。故ax中存放的应该是line25(pop ax)指令对应的ip,bx中存放的是line28(pop bx)指令对应的IP,cx中存放的是line28指令对应的CS。

由下图可知,寄存器(ax)=0021,(bx)=0026,(cx)=076C

 

②调试结果界面截图:

 调试结果与理论分析结果一致。

 

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 start:
10     mov ax, data
11     mov ds, ax
12 
13     mov cx, len    ;从符号x开始的连续字节数据项个数
14     mov si, 0
15 s:    
16     mov ah, 0
17     mov al, ds:[si]    ;一个两位数占1个字节
18     call printNumber
19     call printSpace
20     inc si
21     loop s
22 
23     mov ah, 4ch
24     int 21h
25 
26 ;以十进制形式输出一个两位数
27 printNumber:
28     mov bl, 10
29     div bl
30     mov dl, al    ;商:十位数
31     mov dh, ah    ;余数:个位数
32     or dl, 30h    ;将数字转成对应字符
33     or dh, 30h
34 
35     mov ah, 2
36     int 21h
37     mov dl, dh
38     int 21h
39     ret
40 
41 ;打印一个空格
42 printSpace:
43     mov ah, 2
44     mov dl, ' '
45     int 21h
46     ret
47 
48 code ends
49 end start

 

  • 运行测试截图

 

4.实验任务4

由下图可知,

黑底绿字:0000 0010,转换成16进制为2H

黑底红字:0000 0100,转换成16进制为4H

 

  • 程序源码task4.asm

 

 1 assume cs:code, ds:data
 2 
 3 data segment
 4     str db 'try'
 5     len equ $ - str
 6 data ends
 7 
 8 code segment
 9 start:
10     mov ax, data
11     mov ds, ax
12     mov ax, 0b800h
13     mov es, ax
14 
15     mov si, offset str
16     mov bl,    2h    ;字符串颜色
17     mov bh,    0    ;指定行
18     call printStr
19 
20     mov si, offset str
21     mov bl, 4h
22     mov bh, 24
23     call printStr
24 
25     mov ah, 4ch
26     int 21h
27 
28 ;在指定行、以指定颜色,在屏幕上显示字符串
29 printStr:
30 ;计算行号对应的首位偏移地址
31     mov al, bh
32     mov dl, 00A0h
33     mul dl
34     
35     mov di, ax
36     mov cx, len    ;从符号str开始的连续字节数据项个数
37 s:
38     mov al, ds:[si]
39     mov es:[di], al
40     inc di
41     mov es:[di], bl
42     inc si
43     inc di
44     loop s
45     ret
46 
47 code ends
48 end start

 

  • 运行测试截图

 

5.实验任务5

蓝底白字:0001 0111,转换成16进制为17H

80列,'-'34 学号12 '-'34

  • 程序源码task5.asm

 

 1 assume cs:code, ds:data
 2 
 3 data segment
 4     stu_no db '201983290259'
 5     len = $ - stu_no
 6 data ends
 7 
 8 code segment
 9 start:
10     mov ax, data
11     mov ds, ax
12     mov ax, 0b800h
13     mov es, ax
14 
15     mov si, offset stu_no
16     mov di, 0
17     mov bl,    17h    ;蓝底白字
18     call printColor
19     call printLine
20     call printNumber
21     call printLine
22 
23     mov ah, 4ch
24     int 21h
25 ;打印背景颜色
26 printColor:
27     mov cx, 1920    ;前24行24*80
28 s0:
29     inc di
30     mov es:[di],bl
31     inc di
32     loop s0
33     ret
34 
35 ;打印学号
36 printNumber:
37     mov cx, len    ;从符号stu_no开始的连续字节数据项个数
38 s1:
39     mov al, ds:[si]
40     mov es:[di], al
41     inc di
42     mov es:[di], bl
43     inc si
44     inc di
45     loop s1
46     ret
47 
48 ;打印34个'-'
49 printLine:
50     mov cx, 34
51 s2:
52     mov word ptr es:[di], '-'
53     inc di
54     mov es:[di], bl
55     inc di
56     loop s2
57     ret
58 
59 code ends
60 end start

 

  • 运行测试截图

 

五、实验总结

运算符offset的用法为 offset 标号 ,作用是在汇编时取标号的偏移地址。

伪指令equ的作用是等值赋值,其格式为 <符号名> equ <表达式> 。

预定义符号$,等价于当前正汇编到的段的当前偏移值。

 

posted @ 2021-11-28 18:49  无悔付雪夜  阅读(105)  评论(2编辑  收藏  举报