ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

实验4 8086标志寄存器及中断

2021-12-16 20:32:50  阅读:170  来源: 互联网

标签:8086 中断 ah mov int si 寄存器 ax data


实验4

task 1

验证性实验:有些汇编指令会影响到标志寄存器中的一个或多个状态标志位。
在debug环境中,分别实践、观察:
① add指令对标志寄存器中的零标志位ZF(Zero Flag)、进位标志位CF(Carry Flag)是否有影响?

add 指令对 零标志位ZF(Zero Flag) 位有影响,对进位标志位CF(Carry Flag)也有影响。

② inc指令对标志寄存器中的零标志位ZF(Zero Flag)、进位标志位CF(Carry Flag)是否有影响?

inc指令只会对零标志位ZF(Zero Flag) 位产生影响, 对进位标志位CF(Carry Flag)不会产生影响。

使用任意文本编辑器,录入8086汇编源task1.asm。

 1 assume cs:code, ds:data
 2 
 3 data segment
 4    x dw 1020h, 2240h, 9522h, 5060h, 3359h, 6652h, 2530h, 7031h
 5    y dw 3210h, 5510h, 6066h, 5121h, 8801h, 6210h, 7119h, 3912h
 6 data ends
 7 code segment 
 8 start:
 9     mov ax, data
10     mov ds, ax
11     mov si, offset x
12     mov di, offset y
13     call add128
14 
15     mov ah, 4ch
16     int 21h
17 
18 add128:
19     push ax
20     push cx
21     push si
22     push di
23 
24     sub ax, ax
25 
26     mov cx, 8
27 s:  mov ax, [si]
28     adc ax, [di]
29     mov [si], ax
30 
31     inc si
32     inc si
33     inc di
34     inc di
35     loop s
36 
37     pop di
38     pop si
39     pop cx
40     pop ax
41     ret
42 code ends
43 end start

add128是子程序子程序,功能:实现计算两位128位数的加法
入口参数:

  • ds:si指向存储第一个128位数的存储空间(因为一个数128位,需要8个字节的连续空间)
  • ds:di指向存储第二个128位数的存储空间

出口参数:

  • 加运算后的结果,保存在第一个数的存储空间中,即:ds:si开始的连续8个字节空间

在代码段种,调用add128实现对标号x和y处存储的两个128位数据相加,结果保存在x处的连续128个字节中。
对程序进行汇编、链接,得到可执行程序task1.exe。在debug中调试程序,回答问题:

① line31-line34的4条inc指令,能否替换成如下代码?

1 add si, 2
2 add di, 2

不能:因为add si, 2、add di, 2指令会对进位标志位CF产生影响,导致影响最后结果,而原文的inc指令不会影响CF的值。但是在此题中没有涉及到影响。
② 在debug中调试,观察数据段中做128位加之前和加之后,数据段的值的变化。

前:

 后:

 task2

使用任意文本编辑器,录入8086汇编源码task2.asm:

 1 assume cs:code, ds:data
 2 data segment
 3         str db 80 dup(?)
 4 data ends
 5 
 6 code segment
 7 start:  
 8         mov ax, data
 9         mov ds, ax
10         mov si, 0
11 s1:        
12         mov ah, 1
13         int 21h
14         mov [si], al
15         cmp al, '#'
16         je next
17         inc si
18         jmp s1
19 next:
20         mov ah, 2
21         mov dl, 0ah
22         int 21h
23         
24         mov cx, si
25         mov si, 0
26 s2:     mov ah, 2
27         mov dl, [si]
28         int 21h
29         inc si
30         loop s2
31 
32         mov ah, 4ch
33         int 21h
34 code ends
35 end start

对源程序task2.asm进行汇编、链接,得到可执行文件task2.exe。
运行程序,从键盘上输入一串字符,以#结束(比如,输入George Orwell, 1984#),观察结果。

 

结合运行结果,理解代码并回答问题:
① 汇编指令代码line11-18,实现的功能是:

读入一个字符,判断输入字符是否等于 #,若不等于则存入DS偏移地址为si的位置, si 计数,并继续读入;若等于#,则条件指令je,跳转到标记next处。

② 汇编指令代码line20-22,实现的功能是?

输出换行符(ASCII码中换行符即为0AH),在下一行开始输出字符串。

③汇编指令代码line24-30,实现的功能是?

将读入字符串长度,使用 loop 输出先前数据段中的字符串,从而实现记录输入语句的功能。

说明:task2.asm中用到的两个DOS系统功能调用:     DOS系统功能调用int 21h的1号子功能     功能:从键盘上输入单个字符     入口参数:(ah) = 1     出口参数: (al)存放输入字符的ASCⅡ码     即:
1 mov ah, 1 
2 int 21h     ; (al) <-- 输入字符的ascⅡ码
    DOS系统功能调用int 21h的2号子功能     功能:输出单个字符到屏幕上     入口参数:(ah) = 2, (dl) = 待输出的字符或其ascⅡ码     出口参数:无     即:
1 mov ah, 2 
2 mov dl, ×× ; ××是待输出的字符,或,其ascⅡ码 
3 int 21h

3. 实验任务 3

  针对8086CPU,已知逻辑段定义如下:
1 data segment 
2     x dw 91, 792, 8536, 65521, 2021 
3     len equ $ - x 
4 data ends
  编写8086汇编源程序task3.asm,在屏幕上以十进制形式输出data段中这一组连续的数据,数据和数据之间以空格间隔。   要求:     编写子程序printNumber     功能:以十进制形式输出一个任意位数的整数(整数范围0 ~ 65535)     入口参数:寄存器ax(待输出的数据 --> ax)     出口参数:无   编写子程序printSpace     功能:打印一个空格     入口参数:无     出口参数:无   在主体代码中,综合应用寻址方式和循环,调用printNumber和printSpace, 实现题目要求。  
 1 assume cs:code, ds:data
 2 
 3 data segment
 4     x dw 91, 792, 8536, 65521, 2021
 5     len equ $ - x
 6 data ends
 7 
 8 code segment
 9 
10 printNumber:
11     push bx
12     push di
13     push cx
14     mov cx,0  ; 计数器,控制输出循环次数
15     mov di,0
16 s1:mov dx,0
17     mov bx,10
18     div bx  ; 除数(十进制),每次除以10得到单独数位上的数字
19     or dl,30h
20     push dx ;得到余数进栈
21     inc di
22     cmp ax,0 ; 被除数为0时结束计算,跳出循环
23     jne s1
24     mov cx,di
25 s2:pop dx
26     mov ah,2
27     int 21h
28     loop s2
29 
30     pop cx
31     pop di
32     pop bx
33     ret  
34       
35 printSpace:
36     mov ah,2
37      mov dl,20h ;转为ASCII值打印
38      int 21h
39      ret
40 
41 start: 
42     mov ax, data
43     mov ds, ax
44 
45     mov cx, len
46     mov di, offset x
47 s:  mov ax, [di]
48     call printNumber
49     call printSpace
50     add di, 2
51     sub cx, 1
52     loop s
53 
54     mov ax, 4c00h
55     int 21h
56 
57 code ends
58 
59 end main

 

 运行结果:

 

4. 实验任务4

  针对8086CPU,已知逻辑段定义如下:
1 data segment 
2     str db "assembly language, it's not difficult but tedious" 
3     len equ $ - str 
4 data ends
  编写8086汇编源程序task4.asm,将data段中字符串里的小写字符转换成大写。   要求:   编写子程序strupr     功能:将包含任意字符的字符串中的小写字母变成大写     入口参数       (ds:si ) 字符串首地址的段地址和偏移地址分别送至ds和si       (cx) 字符串的长度     出口参数:无   在主体代码中,设置入口参数,调用strupr, 实现题目要求。  
 1 assume cs:code,ds:data
 2 data segment
 3     str db "assembly language, it's not difficult but tedious"
 4     len equ $ - str
 5 data ends
 6 
 7 code segment
 8 start:
 9     mov ax,data
10     mov ds,ax
11      
12     mov cx,len
13     mov si,offset str
14 s1:
15     call strupr
16     inc si
17     loop s1
18     
19     mov ah,4ch
20     int 21h
21     
22 strupr:
23     mov al,[si]
24     cmp al,'a'
25     jb  s2    ; jump below 小于“a”
26     cmp al,'z'
27     ja s2    ; jump above 大于“z”
28     and byte ptr [si],11011111b
29 s2:
30     ret
31     
32 code ends
33 end start

测试结果:

 

5. 实验任务5

  使用任意文本编辑器,录入8086汇编源码task5.asm。
 1 assume cs:code, ds:data
 2 
 3 data segment
 4     str1 db "yes", '$'
 5     str2 db "no", '$'
 6 data ends
 7 
 8 code segment
 9 start:
10     mov ax, data
11     mov ds, ax
12 
13     mov ah, 1
14     int 21h
15 
16     mov ah, 2
17     mov bh, 0
18     mov dh, 24
19     mov dl, 70
20     int 10h
21 
22     cmp al, '7'
23     je s1
24     mov ah, 9
25     mov dx, offset str2
26     int 21h
27 
28     jmp over
29 
30 s1: mov ah, 9
31     mov dx, offset str1
32     int 21h
33 over:  
34     mov ah, 4ch
35     int 21h
36 code ends
37 end start

 

对源程序task5.asm进行汇编、链接,得到可执行文件task5.exe。   运行程序,输入7,观察结果。输入其他字符,观察结果。结合运行结果和注释,理解代码实现的功能。     说明:task5.asm中,使用用到的DOS系统功能调用和BIOS中断例程     DOS系统功能调用int 21h的1号子功能     功能:从键盘上输入单个字符     入口参数:(ah) = 1     出口参数: (al)存放输入字符的ASCⅡ码     即:
1 mov ah, 1 
2 int 21h     ; (al) <-- 输入字符的ascⅡ码
    DOS系统功能调用int 21h的9号子功能     功能:显示字符串     入口参数:(ah) = 9,(ds:dx) = 字符串的首地址的段地址和偏移地址     出口参数: 无     其它要求:字符串必须以$结束     即:
1 mov ah, 9 
2 mov ds, ××     ; ××是待输出字符串所在段的段地址 
3 mov dx, ××     ; ××是待输出字符串第一个字符的偏移地址 
4 int 21h
    BIOS中断例程int 10h的2号子功能     功能:设置光标位置     入口参数:(ah) = 2, (bh) = 页号(默认取0), (dh) = 行号, (dl) = 列号     出口参数:无     即:
1 mov ah, 2 
2 mov bh, ××     ; ××是页号 
3 mov dh, ×× 
4 mov dl, ××      ; ××是列号 
5 int 10h
实验:输入“7”,观察结果 ,发现屏幕上输出“yes”字符串;

输入其他字符,如“1”、“2”,观察都只能得到屏幕上输出的字符串“no”:

 

 分析源码,得到task5的功能为:分析输入的字符,如果为“7”,则在屏幕上输出“yes”字符串;如果不为“7”而是其他任何数字,都只能得到屏幕上输出字符串“no”。

 

实验6

实验任务1、2、3、5中使用了不少系统提供的中断例程。本实验任务中,要求自行实现一个42号软中断例程,使得通过 int 42 或 int 2ah 软中断调用,实现在屏幕最下方中间以黑底绿字打印"welcome to 2049!"。  

 

 1 ; task6_1.asm
 2 assume cs:code
 3 
 4 code segment
 5 start:
 6     ; 42 interrupt routine install code
 7     mov ax, cs
 8     mov ds, ax
 9     mov si, offset int42  ; set ds:si
10 
11     mov ax, 0
12     mov es, ax
13     mov di, 200h        ; set es:di
14 
15     mov cx, offset int42_end - offset int42
16     cld
17     rep movsb
18 
19     ; set IVT(Interrupt Vector Table)
20     mov ax, 0
21     mov es, ax
22     mov word ptr es:[42*4], 200h
23     mov word ptr es:[42*4+2], 0
24 
25     mov ah, 4ch
26     int 21h
27 
28 int42:
29     jmp short int42_start
30     str db "welcome to 2049!"
31     len equ $ - str
32 
33     ; display string "welcome to 2049!"
34 int42_start:
35     mov ax, cs
36     mov ds, ax
37     mov si, 202h
38 
39     mov ax, 0b800h
40     mov es, ax
41     mov di, 24*160 + 32*2
42 
43     mov cx, len
44 s:  mov al, [si]
45     mov es:[di], al
46     mov byte ptr es:[di+1], 2
47     inc si
48     add di, 2
49     loop s
50 
51     iret
52 int42_end:
53    nop
54 code ends
55 end start

 

 1 ; task6_2.asm
 2 assume cs:code
 3 
 4 code segment
 5 start:
 6     int 42
 7 
 8     mov ah, 4ch
 9     int 21h
10 code ends
11 end start

运行结果:输出“welcom to 2049!”

 程序功能:实现软中断:软中断是由程序中的int指令引起的。如果设置了中断程序,则必须将其添加到中断向量表中,即程序的输入地址。如果在程序执行过程中int指令导致中断,CPU将接收中断号,获得中断段条目的段地址和偏移地址,继续中断程序。

标签:8086,中断,ah,mov,int,si,寄存器,ax,data
来源: https://www.cnblogs.com/IMeanGabriel/p/15696168.html

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

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

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

ICode9版权所有