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

实验任务1

<task4_1.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

① line31~line34的4条inc指令,能否替换成

add si, 2

add di, 2

你的结论的依据/理由是什么?

不能替换,add指令会改变CF位的值,会干扰循环中adc指令的计算

② 在debug中调试,观察数据段中做128位加之前,和,加之后,数据段的值的变化。

加之前:

加之后:

实验任务2

<task4_2.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

运行程序,从键盘上输入一串字符,以#结束(比如,输入George Orwell, 1984#),观察结果:

结合运行结果,理解代码并回答问题:

① 汇编指令代码line11-18,实现的功能是?

从键盘接收字符送往data段,直到遇到“#”,停止接收

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

输出一个换行符

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

将data段的内容输出显示在屏幕上

实验任务3

<task4_3.asm>

 1 assume cs:code,ds:data
 2 data segment
 3     x dw 91, 792, 8536, 65521, 2021 ;10个字节
 4     len equ $ - x
 5 data ends
 6 
 7 code segment
 8 start:
 9     mov ax,data
10     mov ds,ax
11     mov bx,0
12     mov cx,len/2
13 s:  call printNumber
14     call printSpace
15     add bx,2
16     loop s
17     mov ax,4c00h
18     int 21h
19 printNumber:
20     push ax
21     push bx
22     push cx
23     push dx
24 
25     mov si,0 ;记录位数
26     ;经过调试发现,若直接mov ax,ds:[bx],ax高位存放的是代表十六进制数的H,最后除法的时候会有问题
27     ;mov ah,0 
28     ;mov al,ds:[bx] ;低位放真正的被除数
29     mov ax,ds:[bx]
30 convert:
31     mov dx,0 ;被除数高位置0,防止干扰
32     mov cx,10 ;除数
33     div cx
34 
35     add dx,30h ;余数转为字符
36     push dx ;分离出的字符暂时保存到栈;堆栈操作是以字为单位
37 
38     inc si
39     mov cx,ax ;商为0结束
40     jcxz back
41     jmp convert
42 back:
43     mov cx,si
44 s1:
45     pop bx
46     mov ah,2
47     mov dl,bl
48     int 21h
49     loop s1
50 
51     pop dx
52     pop cx
53     pop bx
54     pop ax  
55     ret
56 printSpace:
57     mov ah,2
58     mov dl,32
59     int 21h
60     ret
61 code ends
62 end start

测试结果:

实验任务4

<task4_4.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 ;offset取的是偏移地址!不是段地址!
12     mov cx, len
13     call strupr
14     mov ax, 4c00h
15     int 21h
16 strupr:
17     push si
18     push ax
19 
20 s:  mov al,ds:[si]
21     cmp al,61h  ;大于a
22     jae check
23     inc si
24     loop s
25 check:    
26     cmp al,7ah  ;小于z
27     jbe ok
28     inc si
29     loop s
30 ok:    
31     and al, 0dfh
32     mov ds:[si], al
33     inc si
34     loop s
35     
36     pop ax
37     pop si
38     ret
39 code ends
40 end start

call strupr调用前,后:

实验任务5:

 <task4_5.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    ;DOS系统功能调用int 21h的1号子功能,从键盘输入一个字符
14     int 21h
15 
16     mov ah, 2    ;BIOS中断例程int 10h的2号子功能:设置光标位置
17     mov bh, 0    ;页号
18     mov dh, 24   ;行号
19     mov dl, 70   ;列号
20     int 10h
21 
22     cmp al, '7'
23     je s1        ;如果输入字符等于'7',跳转到s1
24     mov ah, 9    ;DOS系统调用int 21h的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

测试结果:

该程序功能是,如果输入字符='7',则在指定页、行、列位置输出'yes',否则输出'no'

实验任务6

测试结果:

8086CPU软中断实现机制:

1、根据中断信息获取中断类型码

2、标志寄存器入栈,令TF=0、IF=0,以防止执行中断处理程序的时候发生单步中断

3、CS、IP依次入栈(下划线部分是为了执行完中断处理程序后恢复CPU现场)

4、根据中断类型码(N)中断向量表中找到相应中断处理程序的入口地址

(CS=4N+2,IP=4N)

5、执行中断处理程序

6、返回

(在自定义中断处理程序时,若存在数据段,则数据段也应该放在中断程序段内部,防止程序结束后,数据段内容被其他信息覆盖,使程序结果与预期不符)

posted @ 2021-12-13 15:23  dd摇摆  阅读(98)  评论(2编辑  收藏  举报