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

实验任务1

  • 验证性实验

  验证 add 指令对对标志寄存器中的零标志位 ZF(Zero Flag)、进位标志位 CF(Carry Flag) 的影响的实验截图如下:

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

 

    可见,add 指令既能影响零标志位 ZF,也能影响进位标志位 CF。

  

  验证 inc 指令对对标志寄存器中的零标志位 ZF(Zero Flag)、进位标志位 CF(Carry Flag) 的影响的实验截图如下:

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

 

    可见,add 指令能影响零标志位 ZF,但不能影响进位标志位 CF。

 

  • task1.asm的源码如下:
 1 assume cs:code, ds:data
 2 data segment
 3     x dw 1020h, 2240h, 9522h, 5060h, 3359h, 6652h, 2530h, 7031h
 4     y dw 3210h, 5510h, 6066h, 5121h, 8801h, 6210h, 7119h, 3912h
 5 data ends
 6 code segment
 7 start:
 8     mov ax, data
 9     mov ds, ax
10     mov si, offset x
11     mov di, offset y
12     call add128
13 
14     mov ah, 4ch
15     int 21h
16 add128:
17     push ax
18     push cx
19     push si
20     push di
21 
22     sub ax, ax
23 
24     mov cx, 8
25 s:  mov ax, [si]
26     adc ax, [di]
27     mov [si], ax
28 
29     inc si
30     inc si
31     inc di
32     inc di
33     loop s
34 
35     pop di
36     pop si
37     pop cx
38     pop ax
39     ret
40 code ends
41 end start
  • 问题回答:line31~line34的4条inc指令,能否替换成如下代码?你的结论的依据/理由是什么?
1 add si, 2
2 add di, 2

  答:不能替换。因为 inc 指令不影响 CF 标志位,而 add 指令影响会影响 CF 标志位,当加法计算过程中出现进位,CF = 1,如果中途对 si, di 使用 add 指令,CF就会被重新置0,导致最终的计算结果不正确,因此 inc 指令是不能用 add 指令替换的。

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

    答:做128位加法之前,数据段值如下图所示:

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

 

      做128位加法之后,数据段值如下图所示:

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

 

 实验任务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
  • 运行测试截图如下:

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

 

  可以看到,程序实现了对输入字符串的打印输出。 

  • 问题回答:

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

  答:代码 line11-18 的功能是逐个读取键盘输入的字符,依次存入data 数据段中,直到遇到字符 ‘#’ 时,才停止读取。

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

  答:代码 line20-22 的功能是进行换行,方便后续在新的一行显示输入的字符串。

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

  答:代码 line24-30 的功能是在屏幕上输出之前输入的字符串,但输出的字符串中不包含最后的 ‘#’。

 

 

实验任务3

  •  task3.asm 源码如下:
 1 assume cs:code, ds:data, ss:stack
 2 data segment
 3     x dw 91, 792, 8536, 65521, 2021
 4     len equ $ - x
 5 data ends
 6 
 7 stack segment
 8     dw 0,0,0,0,0,0,0,0
 9 stack ends
10 
11 code segment
12 start:
13     mov ax, data
14     mov ds, ax
15     mov ax, stack
16     mov ss, ax
17     mov sp, 16
18     
19     mov cx, len/2
20     mov si, 0
21     mov di, 0
22 s:  mov ax, ds:[si]    
23     call printNumber
24     call printSpace
25     add si, 2
26     loop s
27     
28     mov ah, 4ch
29     int 21h
30 printNumber:
31     push cx
32     mov cx, 0
33     mov bx, 10
34 s1:    
35     mov dx, 0
36     div bx    
37     push dx
38     inc cx     ;cx存储栈中数字个数
39     cmp ax, 0
40     je s2
41     jmp s1
42 s2:
43     mov ah, 2
44     pop dx
45     or dl, 30h
46     int 21h
47     loop s2
48 
49     pop cx
50     ret
51 
52 printSpace:
53     mov ah, 2
54     mov dl, ' '
55     int 21h
56     ret
57 code ends
58 end start
  • 运行测试截图如下:

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

 

   从运行结果中可以看出,程序成功实现了对 data 段连续数据的输出。

 

 

实验任务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     
12     mov cx, len
13     mov si, 0
14     call strupr
15 
16     mov ah, 4ch
17     int 21h    
18 strupr:
19 s:
20     cmp byte ptr ds:[si], 'a'
21     jl s1
22     cmp byte ptr ds:[si], 'z'
23     jg s1
24     and byte ptr ds:[si], 11011111b
25 s1:    
26     inc si
27     loop s
28     ret
29 code ends
30 end start
  • 在 debug 中调试截图如下:

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

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

 

  call strupr 指令调用之后,数据段的值:

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

 

  从 call strupr 指令调用前后数据段的值可以看出,程序成功将小写字母转化成了大写字母。

 

 

实验任务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 ; 设置光标位置在第24行
19     mov dl, 70 ; 设置光标位置在第70列
20     int 10h ; 设置光标位置
21 
22     cmp al, '7'
23     je s1
24     mov ah, 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
  • 程序运行测试截图如下:

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

 

  •  程序功能:判断输入的字符是否为 字符‘7’,如果是,则在界面显示 "yes",否则在屏幕上显示 “no”。

 

 

实验任务6

  •  对中断、软中断实现机制的理解:

  中断有硬中断和软中断之分,软中断是利用软件方式进行模拟,以达到异步执行的效果,int属于软中断指令,软中断的中断过程一般是固定的,都是由 CPU 通过中断类型码在中断向量表中找到中断处理程序的入口地址,设置CS和IP。由于有一部分中断向量表项是空的,所以用户可以选取一个未被使用的中断码,实现一个软中断,本次实验中出现的 int 42 软中断,就是这样的例子。我以为这是对系统已有的int软中断的补充与拓展,给了用户一定的*,增加了程序的灵活性,与C++中的运算符重载有异曲同工之妙。与运算符重载类似,由用户自定义的软中断在实际应用中也应当有所节制,不能滥用,否则会导致程序可读性较差。

 

上一篇:list.stream().map().collect(Collectors.toList())


下一篇:python 列表叠加: