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

四、实验结论

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
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指令。

由于task1.asm中的两个128位数相加时没有产生进位,并且也没有出现运算结果为0的情况。故将inc指令替换成相应的add指令不会影响计算结果和标志寄存器中标志位ZF、CF的值。

但在一些使用add指令会产生进位和结果为0 的情况,必须使用inc指令,否则将影响计算结果。

inc指令的调试过程

 

add指令的调试过程

 

  • 调试观察截图如下所示

 由图可知,数据段中做128位加之前,存放的是两个128位数。在加之后,原来存放第一个128位数的空间,现在存放的是原来两个128位数之和。

 

2.实验任务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

 

  • 运行测试截图

 

  • 回答问题

①汇编指令代码line11-18,实现的功能是调用int 21h的1号子功能,将从键盘输入的字符串中各字符依次存放到data数据段中,直至输入的字符为'#',通过je指令跳转到next标号,结束对字符的读入。

②汇编指令代码line20-22,实现的功能是调用int 21h的2号子功能,输出换行符到屏幕上。(0ah为换行符的ASCII码值)

③汇编指令代码line24-30,实现的功能是调用int 21h的2号子功能,循环依次打印之前输入的字符(不包括'#')。

 

3.实验任务3

  • task3.asm源码

 

 1 assume cs:code, ds:data, ss:stack
 2 
 3 data segment
 4     x dw 91, 792, 8536, 65521, 2021
 5     len equ $ - x
 6 data ends
 7 
 8 stack segment
 9     dw 8 dup(0)
10 stack ends
11 
12 code segment
13 start:
14     mov ax, data
15     mov ds, ax
16     mov ax, stacksg
17     mov ss, ax
18     mov sp, 16
19 
20     mov cx, len/2        ;双字,长度为一半
21     mov si, offset x
22 s:
23     mov ax, word ptr ds:[si]
24     call printNumber
25     call printSpace
26     add si, 2
27     loop s
28 
29     mov ah, 4ch
30     int 21h
31 
32 ;以十进制形式输出一个任意位数的整数(整数范围0~65535)
33 printNumber:
34     push cx
35     mov bx, 10    ;除数
36     mov di, 0
37 
38 count:
39     mov dx, 0
40     div bx
41     push dx        ;余数
42     inc di        ;整数的位数
43     cmp ax, 0    ;商为0结束循环
44     je s0
45     jmp count
46 
47 s0:    mov ah, 2
48     mov cx, di
49 print:
50     pop dx
51     or dl, 30h    ;将数字转换成对应字符
52     int 21h
53     loop print
54 
55     pop cx
56     ret
57 
58 ;打印一个空格
59 printSpace:
60     mov ah, 2
61     mov dl, ' '
62     int 21h
63     ret
64 
65 code ends
66 end start

 

  • 运行测试截图

 

4.实验任务4

  • task4.asm源码

 

 1 assume cs:code, ds:data, ss:stack
 2 
 3 data segment
 4     str db "assembly language, it's not difficult but tedious"
 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     
17     mov cx, len
18     mov si, 0
19     call strupr
20 
21     mov ah, 4ch
22     int 21h
23 
24 strupr:
25     push cx
26     push si
27 
28 s:
29     mov dl, ds:[si]
30     ;小写字母的ASCII码 97~122
31     cmp dl, 97
32     jl next    ;用于有符号数,小于时跳过
33     cmp dl, 122
34     jg next    ;用于有符号数,大于时跳过
35     and dl, 0dfh    ;小写字母转化为大写字母
36     mov ds:[si], dl
37 
38 next:
39     inc si
40     loop s
41 
42     pop si
43     pop cx
44 print:
45     mov ah, 2;
46     mov dl, ds:[si]
47     int 21h
48     inc si
49     loop print
50     ret
51 
52 code ends
53 end start

 

  • 在debug中调试截图

call strupr调用之前,数据段的值

 

调用之后,数据段的值

 

5.实验任务5

  • 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

 

  • 程序运行测试截图

 

  • 程序的功能是从键盘输入一个字符,判断是否为7,若为7在屏幕的第24行第70列显示yes,否则在屏幕的第24行第70列显示no。

 

6.实验任务6

  • 汇编源程序task6_1.asm和task6_2.asm运行结果如下

中断:CPU在接收到外部发送的或内部产生的一种特殊信息时,会立即处理特殊信息。

软中断:CPU内部产生特殊信息(如除法错误、单步执行、执行into指令和执行int指令)时,立即处理该情况。

 

  • 中断码为242(F2h),该中断例程实现的功能与实验3的实验任务5相似,能在屏幕的最后一行正中间显示学号姓名,显示为蓝底白字。

  源码如下:

 

 1 assume cs:code
 2 
 3 code segment
 4 start:
 5     mov ax, cs
 6     mov ds, ax
 7     mov si, offset intF2  ; set ds:si
 8 
 9     mov ax, 0
10     mov es, ax
11     mov di, 200h        ; set es:di
12 
13     mov cx, offset intF2_end - offset intF2
14     cld
15     rep movsb
16 
17     ;设置中断向量表
18     mov ax, 0
19     mov es, ax
20     mov word ptr es:[0F2h*4], 200h
21     mov word ptr es:[0F2h*4+2], 0
22 
23     mov ah, 4ch
24     int 21h
25 
26 intF2: 
27     jmp short intF2_start
28     stu_no db "201983290259liuxiaodie"
29     len = $ - stu_no
30 
31 intF2_start:
32     mov ax, cs
33     mov ds, ax
34     mov si, 202h
35 
36     mov ax, 0b800h
37     mov es, ax
38     mov di, 0
39 
40     mov bl,    17h    ;蓝底白字
41     call printColor
42     call printLine
43     call printNumber
44     call printLine
45 
46     iret
47 
48 ;打印背景颜色
49 printColor:
50     mov cx, 1920    ;前24行24*80
51 s0:
52     inc di
53     mov es:[di],bl
54     inc di
55     loop s0
56     ret
57 
58 ;打印学号
59 printNumber:
60     mov cx, len    ;从符号x开始的连续字节数据项个数
61 s1:
62     mov al, ds:[si]
63     mov es:[di], al
64     inc di
65     mov es:[di], bl
66     inc si
67     inc di
68     loop s1
69     ret
70 
71 ;打印29个'-'
72 printLine:
73     mov cx, 29
74 s2:
75     mov word ptr es:[di], '-'
76     inc di
77     mov es:[di], bl
78     inc di
79     loop s2
80     ret
81 
82 intF2_end:
83    nop
84 code ends
85 end start

 

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

 

运行结果如下:

 

五、实验总结(选)

关于在有栈段的情况下,link时出现了warning L4021: no stack segment的警告,可参考如下博客解决问题。

(24条消息) no stack segment警告为何还在?_迂者-贺利坚的专栏-CSDN博客_no stack

posted @ 2021-12-08 20:55  无悔付雪夜  阅读(72)  评论(2编辑  收藏  举报