实验4 8086标志寄存器及中断
实验结论
1、实验任务1
task4_1.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指令,能否替换成如下代码?你的结论的依据/理由是什么?
1 add si, 2 2 add di, 2
答:不能。原因:因为如果使用add
会导致进位寄存器CF
的值发生变化。如果本来应当是有进位的,CF
的值为CY(1)
,但是做了add
操作后CF
会变成NC(0)
,会对后面的位数加法产生影响。所以不能使用add
。
调试截图:
2、实验任务2
task4_2.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
处执行;如果不是则si + 1
并继续读入下一个字符。
② 汇编指令代码line20-22,实现的功能是?
答:打印一个回车(换行符)。
③ 汇编指令代码line24-30,实现的功能是?
答:打印字符串,并且不会把#
打出来。
3、实验任务3
task4_3.asm源码:
1 assume ds:data, cs:code, ss:stack 2 3 data segment 4 x dw 91, 792, 8536, 65535, 2021, 0 5 len equ $ - x 6 data ends 7 8 stack segment 9 dw 8 dup(?) 10 stack ends 11 12 code segment 13 start: 14 mov ax, data 15 mov ds, ax 16 17 mov ax, stack 18 mov ss, ax 19 mov sp, 16 20 21 mov cx, len/2 22 print: 23 mov ax, word ptr ds:[di] 24 add di, 2 25 26 push cx 27 call printNumber 28 call printSpace 29 30 pop cx 31 loop print 32 33 mov ah, 4ch 34 int 21h 35 36 ; 子程序: printNumber 37 ; 功能: 打印数字 38 ; 入口参数: 39 ; 寄存器ax (待输出的数据 --> ax) 40 ; 局部变量说明: 41 ; bx -> 存储数字字符个数 42 printNumber: 43 mov bx, 0 44 ; getEach循环: 获取每一位,然后压入栈中 45 getEach: 46 ; 除数放在16位寄存器bp中 47 mov bp, 10 48 mov dx, 0 49 div bp 50 51 push dx 52 inc bx 53 54 mov cx, ax 55 inc cx 56 57 loop getEach 58 59 ; 打印数字 60 mov cx, bx 61 printEach: 62 pop dx 63 add dl, 30h 64 mov ah, 2 65 int 21h 66 loop printEach 67 68 ret 69 70 ; 子程序: printSpace 71 ; 功能: 打印空格 72 printSpace: 73 mov ah, 2 74 mov dl, 20h 75 int 21h 76 ret 77 78 code ends 79 end start
运行截图:
4、实验任务4
task4_4.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 stack segment 8 db 8 dup(?) 9 stack ends 10 11 code segment 12 start: 13 mov ax, data 14 mov ds, ax 15 mov si, 0 16 mov cx, len 17 call strupr 18 call printStr 19 20 mov ax, 4c00h 21 int 21h 22 23 ; 子程序 strupr 24 ; 功能: 将包含任意字符的字符串中的小写字母变成大写 25 ; 入口参数 26 ; (ds:si) 字符串首地址的段地址和偏移地址分别送至ds和si 27 ; (cx) 字符串的长度 28 strupr: 29 push cx 30 push si 31 transform: 32 mov al, ds:[si] 33 cmp al, 97 34 jl continue 35 cmp al, 122 36 jg continue 37 and al, 0dfh 38 mov ds:[si], al 39 continue: 40 inc si 41 loop transform 42 43 pop si 44 pop cx 45 ret 46 47 ; 子程序 printStr 48 ; 功能: 打印字符串 49 ; 入口参数 50 ; (ds:si) 字符串首地址的段地址和偏移地址分别送至ds和si 51 ; (cx) 字符串的长度 52 printStr: 53 push cx 54 push si 55 56 print: 57 mov ah, 2 58 mov dl, ds:[si] 59 int 21h 60 inc si 61 loop print 62 63 pop si 64 pop cx 65 ret 66 67 code ends 68 end start
调试截图:
5、实验任务5
task4_5.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则输出yes,否则输出no。
6、实验任务6
运行42号中断程序:
通过编译连接运行task6_1.asm
和task6_2.asm
后可以看到,屏幕底部出现了绿色的"welcome to 2049!
",说明42号中断程序被成功调用。