汇编语言课程-实验4-8086标志寄存器及中断

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

1. 实验任务1

 ① add指令对标志寄存器中的零标志位ZF(Zero Flag)、进位标志位CF(Carry Flag)是否有影响?

答:add的结果可以对零标志位ZF和进位标志位CF产生影响。

 ② inc指令对标志寄存器中的零标志位ZF(Zero Flag)、进位标志位CF(Carry Flag)是否有影响?

答:inc指令只能对零标志位ZF产生影响,而无法对CF产生影响。

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

回答问题:

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

1 add si, 2
2 add di, 2

答:可以替换,上图为task1.asm的调试执行过程,我通过 -g e 命令将源程序 task1.asm 执行到128位数据相加步骤,再使用 -d 076a:0 能够看到正确结果;

  随后,我重新在task1.asm源目录下新建 task_1.asm 文件,将其中的 inc 指令换成了 add si | di,2 ,得到相同的结果,如下图:

  按理来说,add对进位是有影响的而inc对进位无影响,但是本题目数据量不大,开始si为0h,di为10h,所以使用本题使用add对si和di的进位并无影响。

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

相加前:

 相加后:

 

2. 实验任务2

附加知识:str db 80 dup(?) -> (?)表示保持内存里的值

程序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

运行测试截图,回答问题:

  运行程序,从键盘上输入一串字符,以#结束(比如,输入Wang Baojian,201983290002!),观察结果。

 

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

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

  答:使用int 21h的1号子功能,将用户输入的字符串放入数据寄存器ds中,当用户输入过程中取“#”时,结束输入。

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

  答:int 21h的2号子功能为输出单个字符到屏幕上,因此20-22行代码为输出ASCII码为0ah的数据到屏幕上,查询可得该数据意思为换行键 -> 为了换行输出用户输入的数据。

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

  答:将si的值复制到cx中,进行单字节输出循环,将用户之前输入的字符串打印到屏幕上,不包括“#”。

 

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        db 16 dup(0)
10 stack ends
11 
12 code segment
13 start:
14     mov ax, data
15     mov ds, ax
16     mov si, 0
17     mov di, 10h
18     mov word ptr [di], 10        ;将除数放在ds:[di]中,以16进制存储
19     mov cx, 5                ;循环5次,共有五个数
20 
21 s:    mov ax, [si]                 ;低位ax
22     mov dx, 0                ;高位dx为0
23     push cx                
24     mov bx, 0
25     call printNumber
26     call printSpace
27     add si, 2
28        pop cx
29     loop s
30 
31     mov ah, 4ch
32     int 21h
33 
34 printNumber:        
35              s1:    div word ptr [di]
36                     inc bx
37                     add dx, 30h        ;余数存在dx中,加上30h -> 相应的10进制数
38             push dx
39             mov dx, 0
40                     mov cx, ax            
41             jcxz s2
42             mov dx, 0
43                     jmp s1
44       
45       s2:        mov cx, bx
46       s3:        mov ah, 2h
47             pop bx
48                     mov dl,bl
49             int 21h
50             loop s3
51             ret    
52 
53 printSpace:        mov ah, 2h 
54                     mov dl, ' '                       
55                     int 21h             
56                     ret
57     
58 code ends
59 end start
运行测试截图 :

 

4. 实验任务4

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 
15 s:    push cx
16     mov bl, [si]        ;bl存储单字节字符
17     call strupr
18 s1:    pop cx
19     inc si
20     loop s
21      
22     mov ah, 4ch
23     int 21h
24 
25 strupr:    
26         mov ch, 0 
27         mov cl, bl
28         sub cx, 20h
29         jcxz s1
30         mov cl, bl
31         sub cx, 27h
32         jcxz s1
33         mov cl, bl
34         sub cx, 2ch
35         jcxz s1
36         and bl, 11011111B    ;将bl中的ASCII码的第5位置为0,变为大写字母
37         mov [si], bl
38         ret
39 
40 code ends
41 end start

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

1)call stupr调用之前,数据段的值:

2)call stupr调用之后,数据段的值:

 

5. 实验任务5

1)task5.asm源码:
 1 assume cs:code, ds:data
 2 data segment
 3 str1 db "yes", '$'
 4 str2 db "no", '$'
 5 data ends
 6 code segment
 7 start:
 8 mov ax, data
 9 mov ds, ax
10 mov ah, 1
11 int 21h ; 从键盘输入字符
12 mov ah, 2
13 mov bh, 0
14 mov dh, 24 ; 设置光标位置在第24行
15 mov dl, 70 ; 设置光标位置在第70列
16 int 10h ; 设置光标位置
17 cmp al, '7'
18 je s1
19 mov ah, 9
20 mov dx, offset str2
21 int 21h ; 显示标号str2处的字符串
22 jmp over
23 s1: mov ah, 9
24 mov dx, offset str1
25 int 21h ; 显示标号str2处的字符串
26 over:
27 mov ah, 4ch
28 int 21h
29 code ends
30 end start
2)程序运行测试截图(输入7,以及输入其他字符,运行结果截图):

输入7后运行结果:

 输入其他字符后运行结果:

3)程序的功能是?

答:用户键盘输入一个字符,程序判断是否该字符为数字“7”,并将判断结果输出到24行,70列位置,如果字符为7,则输出“yes”,反之输出“no”。

 

6. 实验任务6

实验截图:

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

答:总体来说,我对中断这个概念还是有些生疏的,但是我根据高级语言的相关知识,我觉得中断有点像汇编语言中的系统调用函数,用户直接调用即可,而软中断有点像我们用户自己

编写的函数,然后再需要调用的程序中调用执行。

 

实验总结

1)在本次的实验中,实验任务一和实验任务二属于是验证性实验,通过之前第9、第10章的相关学习,比较容易能够通过代码和运行结果得出结论;

而实验任务三和实验任务四则是需要我们自己编写一段代码,中间出现了很多问题,幸好后来都解决了;

2)本次编写代码过程中,我学习到了以下内容:

  1.  mov ax, bl 这种指令是不对的,不能够将8位寄存器内容直接mov到16寄存器中,反之一样;
  2.  在我们编写程序中,如果涉及到主程序和子程序时,应该要注意cx在主程序和子程序中的冲突,因此在父子程序都需要用到cx的情况下,应该使用寄存器或者内存存储父程序中的cx,建议是使用栈或者ds更方便,如果使用寄存器ax,bx或者dx这种,在程序复杂情况下,会导致寄存器数量不足的情况;
  3.  在编写试验任务三的时候,我发现在输出到第二个数字792后,就不输出了,并且很明显是程序执行过程中出错了,在确认了代码不出错的情况下,我发现第三个应输出数字为8536,使用ax存储是完全合适的,但是在进行除法运算时,如果仅仅使用16位被除数,那么8536/10的余数的确可以存储在ah中为6,但是商为853 -> 355h是无法存在8位寄存器al中的,这样就导致除法过程中程序出错了。因此使用32位除法是最合适的

posted @ 2021-12-14 12:36  缘字訣  阅读(33)  评论(1编辑  收藏  举报