实验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     ;ax置零
25 
26     mov cx, 8      ;循环次数为8
27 s:  mov ax, [si]   ;赋x里的值
28     adc ax, [di]   ;加上[di]×16+CF
29     mov [si], ax   ;将x里的值和y里的值相加并存到x里
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

  答:能。因为adc命令的功能是 ax 加上 [di]×16+CF ,si和di一共循环8次,每次加二,最终结果不会产生进位,因此CF的值不会改变,所以可以替换。

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

  答:通过u命令查看数据段地址,根据数据段地址查看相加之前数据段的值,截图如下:

   运行程序至退出前,再次查看数据段的值,截图如下:

   可以看到实现了x和y的8位数据相加并存到x处的空间内。

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        ;相等则跳到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      ;s2输出str里的符号
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,实现的功能是?

  答:line11-18的功能是实现字符串的输入,直到遇到字符 ‘#’ 停止。

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

  答:0aH是换行符的ASCII码,因此line20-22实现的是换行功能。

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

  答:si表示前面输入字符的个数,将其付给cx作为循环次数,因此line24-30的功能是输出x空间内的字符,即输出前面输入的字符串。

3.实验任务3

  task3.asm源码为:

 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 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     mov ax,stack
17     mov es,ax
18     mov si,offset x  ;x的初始偏移量:0
19     mov cx,5    ;从符号x开始的连续字节数据项个数,即循环次数
20 
21 s:  
22     call s1
23     add si,2
24     call s5
25     loop s
26 
27     mov ah, 4ch
28     int 21h
29 
30 s1:   ;printNumber子程序
31     push cx
32     mov ax,ds:[si]
33     mov dx,0
34     mov bx,10
35     mov cx,0
36 
37 s2:
38     div bx      ;除数为16为,被除数为32位,高位放在dx, 低位放在ax,结果ax保存商, dx保存余数
39     mov es:[di],dx
40     inc di
41     inc cx
42     cmp ax,0
43     je s3       ;商为0则跳到输出
44     mov dx,0
45     jmp s2      ;商不为0则继续
46 
47 s3:  
48     sub di,1 
49     mov dx,es:[di]
50     or dl,30h   ;数值变为对应ascii码
51     mov ah,2
52     int 21h
53     loop s3
54 
55     pop cx
56     ret
57 
58 s5: mov ah,2    ;printSpace子程序
59     mov dl,' '
60     int 21h
61     ret
62 code ends
63 end start

  运行截图如下:

4.实验任务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 cx,len
12     mov si,0
13     call strupr
14 
15     mov ah, 4ch
16     int 21h
17 
18 strupr:
19     mov al,[si]
20     cmp al,20h
21     je s1        ;如果是空格就跳过
22     cmp al,2ch
23     je s1        ;如果是逗号就跳过
24     cmp al,27h
25     je s1        ;如果是单引号就跳过
26     and al,0dfh  ;都不是则转换为大写存入内存
27 s1:
28     mov [si],al
29     inc si
30     loop strupr
31     ret
32 
33 code ends
34 end start

  运行后查看调用strupr前的数据段:

   调用strupr后再次查看:

  发现已经成功将字符串里的小写字符转换成大写。

5.实验任务5

  task5.asm源码为:

 1 assume cs:code, ds:data
 2 data segment
 3     str1 db "yes", '$'
 4     str2 db "no", '$'
 5 data ends
 6 
 7 code segment
 8 start:
 9     mov ax, data
10     mov ds, ax
11 
12     mov ah, 1
13     int 21h ; 从键盘输入字符
14 
15     mov ah, 2
16     mov bh, 0
17     mov dh, 24     ; 设置光标位置在第24行
18     mov dl, 70     ; 设置光标位置在第70列
19     int 10h        ; 设置光标位置
20 
21     cmp al, '7'
22     je s1
23     mov ah, 9
24     mov dx, offset str2
25     int 21h        ; 显示标号str2处的字符串
26     
27     jmp over
28 
29 s1: mov ah, 9
30     mov dx, offset str1
31     int 21h        ; 显示标号str2处的字符串
32 over:
33     mov ah, 4ch
34     int 21h
35 code ends
36 end start

   运行task5.exe后输入7的结果为:

   输入别的符号的结果为:

  源程序task5.asm功能是:先从键盘读取用户输入的一个字符,接着判断是不是’7’ ,如果是则在第24行70列输出“yes”,否则在第24行70列输出“no”。

6.实验任务6

  task6_1.asm源码为:

 1 assume cs:code
 2 
 3 code segment
 4 start:
 5     ; 42 interrupt routine install code
 6     mov ax, cs
 7     mov ds, ax
 8     mov si, offset int42  ; set ds:si
 9 
10     mov ax, 0
11     mov es, ax
12     mov di, 200h        ; set es:di
13 
14     mov cx, offset int42_end - offset int42
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:[42*4], 200h
22     mov word ptr es:[42*4+2], 0
23 
24     mov ah, 4ch
25     int 21h
26 
27 int42: 
28     jmp short int42_start
29     str db "welcome to 2049!"
30     len equ $ - str
31 
32     ; display string "welcome to 2049!"
33 int42_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, 24*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 int42_end:
52    nop
53 code ends
54 end start

  task6_2.asm源码为:

 1 assume cs:code
 2 
 3 code segment
 4 start:
 5     int 42    ;调用自己实现的42号软中断
 6 
 7     mov ah, 4ch
 8     int 21h
 9 code ends
10 end start

  运行两个程序的结果为:

 

  中断分为硬中断和软中断。硬中断通常通过硬件如鼠标键盘来触发中断。

  软中断是通过程序来实现中断,它可以使CPU暂停当前程序的执行,转而执行处理紧急事务,并在该事务处理完后能自动恢复执行原先程序的过程,实验6中就是通过int 42触发软中断立即转到输出字符串。

 实验总结

  通过本次实验,我对常用标志寄存器用途、条件转移指令以及软中断指令的用法有了进一步了解和掌握。

  在实验中收获了以下知识点:

  (1).inc指令对标志寄存器中的零标志位ZF不会有影响,而add指令有影响。

  (2).当ah为1时,int 21h的功能是从键盘上输入单个字符存到al中;当ah为9时,int 21h的功能是显示字符串,且字符串必须以$结束。

  (3).通过cmp命令和je命令的组合可以实现类似C语言中if语句的功能,在任务2,3,4,5中都有用到。

posted @ 2021-12-08 09:51  stCQCQ  阅读(87)  评论(1)    收藏  举报