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

1. 实验任务1

1)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 ;将CF置为0
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

2)回答问题:line31~line34的4条inc指令,能否替换成如下代码?你的结论的依据/理由是什么?

1 add si, 2
2 add di, 2

答:不能。inc指令不会改变进位标志位CF的值;若改成如上代码,adc的运算中CF的实际值将受到影响,加法结果也将受到影响。

     但在本题中,第一两组数的相加实际并不会产生进位,第二add si,2 和add di,2也不会产生进位,所以实际结果并不会变。

3)在debug中调试,观察数据段中做128位加之前和加之后,数据段的值的变化。给出调试观察截图。

做128位加之前数据段的值:

 做128位加之后数据段的值:

 可以看到x+y的结果成功赋值到数据段x中。

2. 实验任务2

1)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 ;调用int 21h的1号子功能
13         int 21h
14         mov [si], al ;从键盘上输入单个字符到al
15         cmp al, '#' ;判断是否为'#'
16         je next ;是则跳转
17         inc si
18         jmp s1
19 next:
20         mov ah, 2 ;调用int 21h的2号子功能
21         mov dl, 0ah ;输出单个字符到屏幕上,0ah换行符的ASCII码
22         int 21h
23         
24         mov cx, si
25         mov si, 0
26 s2:     mov ah, 2 ;调用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

2)运行测试截图

 3)回答问题

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

 答:从键盘一个一个读入字符并判断是否为#,若是,跳转到子程序next;若不是,继续读入并计数。

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

 答:输出一个换行符。

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

 答:输出读入的字符串(不包括#)。

3. 实验任务3

1)task3.asm源码

 1 ;借助32÷16的除法,无需考虑溢出
 2 assume cs:code,ds:data,ss:stack
 3 
 4 data segment
 5         x dw 91, 792, 8536, 65521, 2021
 6         len equ $ - x
 7 data ends
 8 
 9 stack segment
10         db 10 dup(?)
11 stack ends
12 
13 code segment
14 start:   
15         mov ax, data
16         mov ds, ax
17         mov cx,len/2
18         mov si,0
19 print:
20         push cx ;保存cx的值
21         mov ax,ds:[si] ;数据放到ax
22         mov dx,0 ;高位为0
23         call printNumber
24         add si,2
25         pop cx
26         loop print
27         
28         mov ax, 4c00h
29         int 21h
30 
31 printNumber:
32         mov bl,10 ;除数10
33         mov di,0
34         
35 s1:   div bx
36        push dx ;保存余数
37        mov dx,0
38        inc di
39        cmp ax,0 ;被除数为0结束
40        jne s1
41 
42        mov cx,di ;位数
43        mov ah,2
44 s2:   pop dx
45        or dl,30h
46        int 21h
47        loop s2
48        call printSpace
49        ret
50 
51 printSpace:
52         mov ah, 2
53         mov dl, ' '
54         int 21h
55         ret
56 
57 code ends
58 end start

2)运行测试截图

4.实验任务4

1)task4.asm源码

 1 assume cs:code,ds:data
 2 
 3 data segment
 4         str db "assembly language, it's not difficult but tedious"
 5         len equ $ - str
 6 data ends
 7 
 8 code segment
 9 start:   
10         mov ax, data
11         mov ds, ax
12         mov cx,len
13         mov si,0
14 s1:
15         call strupr
16         add si,1
17         loop s1
18         
19         mov ax, 4c00h
20         int 21h
21 
22 strupr:
23        cmp byte ptr ds:[si],'a' ;过滤
24        jb s2
25        cmp byte ptr ds:[si],'z'
26        ja s2
27        mov bl,ds:[si] ;小写转大写
28        sub bl,20H
29        mov ds:[si],bl
30 s2:     ret
31 
32 code ends
33 end start

2)在debug中调试截图(call strupr调用之前,数据段的值,以及,调用之后,数据段的值)

调用之前:

 调用之后:

 5. 实验任务5

1)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 ;int 10h的2号子功能
17     mov bh, 0
18     mov dh, 24 ;设置光标位置在第24行
19     mov dl, 70 ;设置光标位置在第70列
20     int 10h ;设置光标位置
21 
22     cmp al, '7'
23     je s1
24     mov ah, 9 ;用int 21h的9号子功能,输出字符串,字符串必须以$截止
25     mov dx, offset str2
26     int 21h ;显示标号str2处的字符串
27 
28     jmp over
29 
30 s1: mov ah, 9
31     mov dx, offset str1
32     int 21h ;显示标号str2处的字符串
33 over:  
34     mov ah, 4ch
35     int 21h
36 code ends
37 end start

2)程序运行测试截图(输入7,以及输入其他字符,运行结果截图)

输入7:

 其他字符:

 

3)程序的功能是?

 答:从程序读入一个字符并判断是否为'7',若为'7',在第24行70列输出yes并退出;若不为'7',在第24行70列输出no并退出。

6. 实验任务6

编译、运行task6_1.asm和task6_2.asm

 通过此项实现任务,你对中断、软中断实现机制的理解

 中断分为硬中断与软中断。硬中断主要为硬件触发的中断,软中断主要为内核机制触发事件产生的中断。

 中断的过程类似于函数的调用。

 内核机制触发事件产生中断,CPU收到对应的中断类型码,通过中断类型码到中断向量表中找到

 中断处理程序的段地址(0000:中断类型码*4)和偏移地址(0000:中断类型码*4+2),然后通过修改CS和IP的值定位中断处理程序并执行它

 注意和调用函数相似的,要保留中断前的CS和IP,因为执行完中断程序要返回。

posted @ 2021-12-10 12:08  HypnosTT  阅读(56)  评论(2编辑  收藏  举报