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

2021/11/25 17:40:02

本文主要是介绍实验3 转移指令跳转原理及其简单应用编程,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

1. 实验任务1   使用任何一款文本编辑器,录入8086汇编程序源码task1.asm。   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

 

  对源程序进行汇编、链接,得到可执行程序task1.exe,运行后,结合运行结果和注释,及必要的debug调试:   1. 理解运算符offset、伪指令equ、预定义符号$的灵活使用。通过line5、line8,以及数据项的数据属性(字节、字、双字,等),可以方便计算出连续数据项的个数,而无需人工计数。    注*: 符号常量len1, len2不占用数据段内存空间   2. 回答问题   ① line27, 汇编指令 loop s1 跳转时,是根据位移量跳转的。通过debug反汇编,查看其机器码,分析其跳转的位移量是多少?(位移量数值以十进制数值回答)从CPU的角度,说明是如何计算得到跳转后标号s1其后指令的偏移地址的。   跳转位移量为F2,转换为十进制即242个字节。   程序运行到loop s1时,指令寄存器IP=001B指向下一条指令,而001B+00F2=010D,高位舍弃,即IP指向000D。     ② line44,汇编指令 loop s2 跳转时,是根据位移量跳转的。通过debug反汇编,查看其机器码,分析其跳转的位移量是多少?(位移量数值以十进制数值回答)从CPU的角度,说明是如何计算得到跳转后标号s2其后指令的偏移地址的。      跳转位移量为F0,转换为十进制即240个字节。   程序运行到loop s2时,指令寄存器IP=0039指向下一条指令,而0037+00F0=0129,高位舍弃,即IP指向0029。     ③ 附上上述分析时,在debug中进行调试观察的反汇编截图   分析及反汇编截图如上,以下给出程序运行截图

 

2. 实验任务2   使用任何一款文本编辑器,录入8086汇编程序源码task2.asm。   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
  ① 根据call指令的跳转原理,先从理论上分析,程序执行到退出(line31)之前,寄存器(ax) = s1 寄存器(bx) = s2 寄存器(cx) = cs   指令call word ptr ds:[0]执行短转移,只记录下一条指令的IP值,即s1。   指令call dword ptr ds:[2]执行长转移,跳转到该程序的内存空间之外,同时记录下一条指令的CS值和IP值,即cs和s2。     ② 对源程序进行汇编、链接,得到可执行程序task2.exe。使用debug调试,观察、验证调试结果与理论分析结果是否一致。 

  可以注意到ax, bx, cx均符合上述分析。

3. 实验任务3   针对8086CPU,已知逻辑段定义如下:
1 data segment 
2     x db 99, 72, 85, 63, 89, 97, 55
3     len equ $- x 
4 data ends

  编写8086汇编源程序task3.asm,在屏幕上以十进制形式输出data段中这一组连续的数据,数据和数据之间以空格间隔。

  要求:   编写子程序printNumber     功能:以十进制形式输出一个两位数     入口参数:寄存器ax(待输出的数据 --> ax)     出口参数:无   编写子程序printSpace     功能:打印一个空格     入口参数:无     出口参数:无   在主体代码中,综合应用寻址方式和循环,调用printNumber和printSpace, 实现题目要求。

 

 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 stack segment
 9         db 16 dup(0)
10 stack ends
11 
12 code segment
13 start:  
14         mov ax, data
15     mov ds, ax
16     
17     mov cx, len
18     mov si, offset x
19 s:    mov ah, 0
20     mov al, ds:[si]
21     call printNumber
22     call printSpace
23     inc si
24 loop s
25 
26     mov ah, 4ch
27     int 21h
28 
29 printNumber:    
30     mov bl, 10
31     div bl
32     mov dl, al
33 
34     mov dh, ah
35 
36     or dl, 30H    ;数值转字符
37     mov ah, 2    
38     int 21h        ;输出高位
39 
40     mov dl, dh
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 start

 

  4. 实验任务4   针对8086CPU,已知逻辑段定义如下:
1 data segment 
2     str db 'try' 
3     len equ $ - str 
4 data ends
  编写8086汇编源程序task4.asm,在屏幕上以指定颜色、指定行,在屏幕上输出字符串。   要求:     编写子程序printStr       功能:在指定行、以指定颜色,在屏幕上显示字符串       入口参数         字符串首字符地址 --> ds:si(其中,字符串所在段的段地址—> ds, 字符串起始地址的偏         移地址—> si)         字符串长度 --> cx         字符串颜色 --> bl         指定行 --> bh (取值:0 ~24)       出口参数:无      在主体代码中,两次调用printStr,使得在屏幕最上方以黑底绿字显示字符串,在屏幕最下方以黑底红色显示字符串 
 1 assume cs:code, ds:data
 2 
 3 data segment
 4         str db 'try' 
 5     len equ $ - str
 6 data ends
 7 
 8 stack segment
 9         db 16 dup(0)
10 stack ends
11 
12 code segment
13 start:  
14         mov ax, data
15     mov ds, ax
16     mov ax, 0b800h
17     mov es, ax
18     
19     mov cx, len
20     mov si, 0
21     mov bl, 2    ;green
22     mov bh, 0    ;第一行
23     mov di, bh    ;行首地址
24     call printStr
25     
26     mov bh, 24    ;最后一行
27     ;每行占用空间为00A0H
28     mov bl, bh
29     mov bh, 0
30     mov cx, bx
31     mov ax, 0
32 findLastRow:
33     add ax, 00A0H
34 loop findLastRow
35     mov di, ax
36 
37     mov cx, len
38     mov si, 0
39     mov bl, 4    ;red
40     call printStr
41 
42     mov ah, 4ch
43     int 21h
44     
45 printStr:
46 s:
47     mov al, ds:[si]
48     mov ah, bl
49     mov es:[di], ax
50     inc si
51     inc di
52     inc di
53 loop s
54 ret
55 
56 code ends
57 end start

 

5. 实验任务5   针对8086CPU,针对8086CPU,已知逻辑段定义如下: 
1 data segment 
2     stu_no db '20498329042' 
3     len = $ - stu_no 
4 data ends
  在80×25彩色字符模式下,在屏幕最后一行正中间显示学号。要求输出窗口蓝底,学号和两侧折线,以白色前景色显示。 
 1 assume cs:code, ds:data
 2 
 3 data segment
 4     stu_no db '201983290033' 
 5     len = $ - stu_no 
 6 data ends
 7 
 8 stack segment
 9         db 16 dup(0)
10 stack ends
11 
12 code segment
13 start:  
14         mov ax, data
15     mov ds, ax
16     mov ax, 0b800h
17     mov es, ax
18 
19     mov bl, 17H    ;蓝底白字
20     mov si, 0
21     call setBgColor
22     
23     mov bh, 24    ;最后一行
24     ;每行占用空间为00A0H
25     mov bl, bh
26     mov bh, 0
27     mov cx, bx
28     mov ax, 0
29 findLastRow:
30     add ax, 00A0H
31 loop findLastRow
32     mov di, ax
33 
34     ;前白色线长34
35     mov al, '-'
36     mov cx, 34
37     mov bl, 17H    ;蓝底白字
38     call printLine
39 
40     mov cx, stu_no
41     mov si, 0
42     mov bl, 17H    ;蓝底白字
43     call printStr
44 
45     ;后白色线长34
46     mov al, '-'
47     mov cx, 34
48     mov bl, 17H    ;蓝底白字
49     call printLine
50 
51     mov ah, 4ch
52     int 21h
53     
54 printStr:
55 s:
56     mov al, ds:[si]
57     mov ah, bl
58     mov es:[di], ax
59     inc si
60     inc di
61     inc di
62 loop s
63 ret
64 
65 printLine:
66 s1:
67     mov al, '-'
68     mov ah, bl
69     mov es:[di], ax
70     inc di
71     inc di
72 loop s1
73 ret
74 
75 setBgColor:
76     mov cx, 2000    ;80*25
77 s2:
78     mov al, ' '
79     mov ah, bl
80     mov es:[si], ax
81     inc si
82     inc si
83 loop s2
84 ret
85 
86 code ends
87 end start

   后面的绘制折线不执行了,暂未找到原因。



这篇关于实验3 转移指令跳转原理及其简单应用编程的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程