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

一、实验目的

  1. 理解标志寄存器用途,理解常用标志位CF, ZF, OF, SF, TF, IF的用途和意义。

  2. 理解条件转移指令je, jz, ja, jb, jg, jl等的跳转原理,掌握组合使用汇编指令cmp和条件转移指令实现 分支和循环的用法

  3. 了解软中断指令的用法,体验和理解中断原理

  4. 综合应用寻址方式和汇编指令完成简单应用编程

二、实验准备

  复习教材「第10章 call和ret指令」、「第11章 标志寄存器」 学习教材「第12章 内中断 」、「第13章 int指令」

三、实验内容

 1. 实验任务1

Add指令

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

  由图可以看出add指令对标志寄存器中的零标志位ZF和进位标志位CF都有影响,图中ZF零标志位由NZ转变成了ZR,即从0变成了1,CF进位标志位从NC转变成了CY,即从0变成了1。

由于al中本身值为ff,再加1得100超过al的两位限制,所以1被舍弃,结果就是零,所以零标志位ZF置1。

 

Inc指令

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

由图可以看出inc指令对零标志位ZF有影响,因为计算出结果100,舍去1后结果是0,所以ZF从NZ变成了ZR,即从0变成1。而对进位标志位CF没有影响,依然是NC。

 

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

 

 

Task1.asm汇编链接后,task1.exe执行结果如下:

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

可以看到两个128位数相加后结果存放在x开始的连续16个字节中。

 

若将line31~line34的4条inc指令替换成如下

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

执行结果如下:

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

可以看到结果依然正确,并且存放在x开始的连续16个字节中。

这里我认为是可以替换的,因为add指令和inc指令对进位标志位的影响不同,当add指令计算完产生进位时会对CF产生影响,而inc则无论如何不会对CF产生影响,在本题中,si的范围是从0000到000f,di的范围是从0010到001f,二者都没有发生进位,所以add指令不会对CF产生影响,就不会影响最终的结果。

 

实验任务2:

 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.exe运行截图如下:

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

问题1:line11-18实现的功能是从键盘上读取字符并保存到data段str开始的位置,直到‘#’为止,如果读入了‘#’,就跳转到next开始的位置执行代码,否则继续读取字符。

问题2:line20-22实现的功能是输出一个换行符,因为换行符的ascii码是10,所以将0ah移入dl中,再输出。

问题3:line24-30实现的功能是将存放在数据段str开始的字符输出到屏幕上。

整个程序的功能是从键盘上读取字符直到‘#’结束,并在下一行将读取的字符输出(不包括‘#’)。

 

实验任务3:

task3.asm代码如下:

 1 assume cs:code, ds:data
 2 data segment
 3             x dw 91, 792, 8536, 65521, 2021
 4     len equ $ - x
 5 data ends
 6 
 7 code segment
 8 start:  
 9         mov ax, data
10     mov ds, ax
11     mov si, offset x
12     mov cx, 5
13 
14 s:    push cx
15     mov cx, 0
16     mov al, ds:[si]
17     mov ah, ds:[si + 1]
18     call printNumber
19     call printSpace
20     pop cx
21     loop s
22     
23     mov ah, 4ch
24     int 21h
25     
26 printNumber:
27     mov bx, 10
28     mov dx, 0
29     div bx
30     inc cx
31     push dx
32     cmp ax, 0
33     jne printNumber
34     
35 s1:    mov ah, 2
36     pop dx
37     or dl, 30h
38     int 21h
39     loop s1
40     inc si
41     inc si
42     ret
43 
44 printSpace:
45     mov ah, 2
46     mov dl, ' '
47     int 21h
48     ret
49 
50 code ends
51 end start

task3.exe运行截图如下:

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

 

实验任务4:

task4.asm代码如下:

 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     mov si, offset str
12     mov cx, len
13     
14 s:    mov al, ds:[si]
15     call strupr
16     inc si
17     loop s
18 
19     mov ah, 4ch
20     int 21h
21 strupr:    cmp al,  97
22     jb s1
23     cmp al, 122
24     ja s1
25     and al, 11011111B
26     jmp s1
27 
28 s1:    mov ah, 2
29     mov dl, al
30     int 21h
31     ret
32 
33     
34 
35 code ends
36 end start

task4.exe运行截图如下:

执行之前数据段内容如下:

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

 执行后截图如下:

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

 

实验任务5:

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

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

该程序功能是判断从键盘输入的字符是否是7,若是则在右下角打印yes,不是则打印no。

 

实验任务6:

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

下为使用255中断码:

task6_3代码:

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

task6_4.asm代码:

 1 assume cs:code
 2 
 3 code segment
 4 start:
 5     int 255
 6 
 7     mov ah, 4ch
 8     int 21h
 9 code ends
10 end start

运行截图如下:

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

   我学习到关于中断的知识有如下:由于程序运行过程中会产生异常,CPU会自动识别出异常,并将它定位到异常向量表中的一个位置吗,通过异常向量表来实现对不同异常的处理。中断又分为软中断和硬中断,软中断是由程序执行的中断,硬中断是由硬件执行的中断。软中断执行后,硬件先复位,然后PC指向异常向量表中的第一个位置:0x00,然后执行跳转rest函数,通过swi触发软中断。

 

四、实验总结

  通过本次实验我学习到了关于标志寄存器和一些跳转指令的知识,知道了如何在Dosbox里使用标志寄存器和跳转指令来达到自己的目的。也学习了关于中断和软中断相关的知识,了解了软中断在程序中是如何触发的,以及相关的汇编中默认和空闲的中断码等等,希望以后可以更深入地学习这一方面。

上一篇:高质量语音市场现状及未来发展趋势


下一篇:实验4 8086标志寄存器及中断