Noseel

导航

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

 

实验任务1

1.验证实验

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

  

  add指令会对标志位ZF和CF产生影响:ZF位从NZ变成了ZR,表示运算结果为0,CF位从NC变成了CY,表示运算中最高位向更高位产生了进位。

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

  inc指令只会对ZF位产生影响, 对CF位不会产生影响:ZF位从NZ变为ZR,表示运算结果位0,CF位未发生变化。

2.使用任意文本编辑器,录入8086汇编源码task1.asm

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 ;功能:实现计算两位128位数的加法
18 ;入口参数:
19 ;ds:si指向存储第一个128位数的存储空间(因为一个数128位,需要8个字节的连续空间)
20 ;ds:di指向存储第二个128位数的存储空间
21 ;出口参数:
22 ;加运算后的结果,保存在第一个数的存储空间中,即:ds:si开始的连续8个字节空间
23 add128:
24     push ax
25     push cx
26     push si
27     push di
28 
29     sub ax, ax
30 
31     mov cx, 8
32 s:  mov ax, [si]
33     adc ax, [di]
34     mov [si], ax
35 
36     inc si
37     inc si
38     inc di
39     inc di
40     loop s
41 
42     pop di
43     pop si
44     pop cx
45     pop ax
46     ret
47 code ends
48 end start

回答问题:

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

add si, 2
add di, 2

inc不能换成add指令,add指令会影响CF标志位,而inc指令不会影响,而本题中大整数加法,所以进行加法运算时运用的是add指令,会用到CF标志位的数值,若使用了add si,2和add di,2指令, 则会对CF标志位产生影响,进而影响到adc指令的执行结果,最终影响到计算结果,所以不能换成add指令。

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

程序运行前:

程序运行后:

 完成了128位二进制数的加法

实验任务2

使用任意文本编辑器,录入8086汇编源码task2.asm

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

运行程序,从键盘上输入一串字符,以#结束(比如,输入George Orwell, 1984#),观察结果。结合运行结果,理解代码并回答问题:

① 汇编指令代码line11-18,实现的功能是?
取用户输入的字符, 并将之保存在ds:[si]中.如果是"#"则跳转到"next"处执行,否则继续读入下一个字符串
 
② 汇编指令代码line20-22,实现的功能是?
换行
 
③ 汇编指令代码line24-30,实现的功能是?
打印输出除了"#"以外输入的所有字符

实验任务3

针对8086CPU,已知逻辑段定义如下:

data segment 
    x dw 91, 792, 8536, 65521, 2021 
    len equ $ - x 
data ends

编写8086汇编源程序task3.asm,在屏幕上以十进制形式输出data段中这一组连续的数据,数据和数据之间以空格间隔。

task3.asm

 1 assume ds:data, cs:code
 2 data segment
 3     x dw 91, 792, 8536, 65521, 2021
 4     len equ $ - x
 5     y db 200 dup(?)   ;为栈的使用开辟空间
 6     leny equ $ - y
 7 data ends
 8 
 9 code segment
10 start:
11     mov ax, offset y
12     mov ss, ax
13     mov sp, leny    ;设置栈顶
14 
15     mov ax, data    ;将x数据段放入ds:[si]中
16     mov ds, ax
17     mov si, 0
18     mov cx, 5       ;一共五个数, 所以循环5次
19 s2:
20     call printNumber
21     call printSpace
22     add si, 2
23     loop s2
24 
25     mov ah, 4ch
26     int 21h
27 
28 ;功能:以十进制形式输出一个任意位数的整数(整数范围0 ~ 65535)
29 ;入口参数:寄存器ax(待输出的数据 --> ax)
30 ;出口参数:无
31 printNumber:
32     push cx         ;将外部循环s2的剩余次数压入栈中
33     mov ax, ds:[si] ;将被除数放入ax中
34     mov dx, 0       ;由于数值最大位65521, 小于8位16进制能表达的最大数6535, 所以被除数的高16位可以设置位0
35     mov bx, 10      ;将除数10放入bx中
36     mov cx, 0h      ;cx寄存器用于计数
37 s1:
38     inc cx      ;每做一次除法都进行一次计数
39     div bx      ;除法操作, 由于除数是16位, 被除数就被解读为dx:ax, 余数在dx中, 商在ax中
40     or dx, 30h      ;将余数转为相应的ASCII码
41     push dx         ;将结果压入栈中
42     mov dx, 0       ;作用与33行的一样, 同时起到将余数清空为0的作用
43     cmp ax, 0
44     jne s1
45 s3:
46     pop dx          ;将栈顶数据放入dx中
47     mov ah, 02h
48     int 21h         ;使用int 21h指令输出
49     loop s3         ;循环输出, 次数为做除法的次数
50     pop cx          ;将栈底的外部循环次数放入cx中
51     ret
52 
53 ;功能:打印一个空格
54 ;入口参数:无
55 ;出口参数:无
56 printSpace:
57     mov dl, ' '
58     mov ah, 02h
59     int 21h
60     ret
61 
62 
63 code ends
64 end start

实验任务4

针对8086CPU,已知逻辑段定义如下

data segment 
    str db "assembly language, it's not difficult but tedious" 
    len equ $ - str 
data ends

编写8086汇编源程序task4.asm,将data段中字符串里的小写字符转换成大写。

task4.asm

 1 assume ds:data, cs:code
 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 
10     mov ax, data
11     mov ds, ax
12     mov si, offset str
13 
14     mov cx, len
15 
16 s1:
17     call strupr
18     inc si
19     loop s1
20 
21     mov ah, 4ch
22     int 21h
23 
24 ;功能:将包含任意字符的字符串中的小写字母变成大写
25 ;入口参数
26 ;(ds:si ) 字符串首地址的段地址和偏移地址分别送至ds和si
27 ;(cx) 字符串的长度
28 ;出口参数:无
29 strupr:
30     cmp byte ptr ds:[si], 96
31     jna s2          ;如果当前的字符小于等于96,则直接输出
32     sub byte ptr ds:[si], 32 ;否则转为大写字母
33 s2:
34     mov dx, ds:[si]
35     mov ah, 2
36     int 21h
37     ret
38 
39 code ends
40 end start

实验任务5

使用任意文本编辑器,录入8086汇编源码task5.asm。

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, 输出yes。如果输入的为非7字符, 则输出no

实验任务6

实验任务1、2、3、5中使用了不少系统提供的中断例程。本实验任务中,要求自行实现一个42号软中断例程,使得通过 int 42 或 int 2ah 软中断调用,实现在屏幕最下方中间以黑底绿字打印"welcome to 2049!"

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
 6 
 7     mov ah, 4ch
 8     int 21h
 9 code ends
10 end start

 

 

posted on 2021-12-14 11:11  Noseel  阅读(111)  评论(3)    收藏  举报