ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2021-11-25 17:36:28  阅读:135  来源: 互联网

标签:segment 编程 mov si 指令 跳转 ax data ds


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

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

 

标签:segment,编程,mov,si,指令,跳转,ax,data,ds
来源: https://www.cnblogs.com/Severus-Vast/p/15601157.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有