汇编语言程序设计实验四:8086标志寄存器及中断
-
实验任务1
- task1.asm源码:
assume cs:code, ds:data data segment x dw 1020h, 2240h, 9522h, 5060h, 3359h, 6652h, 2530h, 7031h y dw 3210h, 5510h, 6066h, 5121h, 8801h, 6210h, 7119h, 3912h data ends code segment start: mov ax, data mov ds, ax mov si, offset x mov di, offset y call add128 mov ah, 4ch int 21h add128: push ax push cx push si push di sub ax, ax mov cx, 8 s: mov ax, [si] adc ax, [di] mov [si], ax inc si inc si inc di inc di loop s pop di pop si pop cx pop ax ret code ends end start-
关于add指令的调试过程截图如下:
![]()
由图可知add指令使得ZF标志位由NZ变为ZR,CF标志位由NC变为CY,可知运算结果为0且在运算中由最高位向更高位产生了进位。 -
关于inc指令的调试过程截图如下:
![]()
由图可知inc指令使得ZF标志位由NZ变为ZR,可知运算结果为0,而CF未曾改变。 -
line31~line34的4条inc指令,不能替换成如下代码,原因是:该题用adc指令进行大整数加法,期间需要用到CF标志位的数值,而上面已经验证过add指令会对CF标志位产生影响,故不能替换。
add si, 2
add di, 2
-
128位加之前数值截图:
![]()
-
完成128位加之后数值截图(有变化):
![]()
-
实验任务2
- task2.asm源码:
assume cs:code, ds:data data segment str db 80 dup(?) data ends code segment start: mov ax, data mov ds, ax mov si, 0 s1: mov ah, 1 int 21h mov [si], al cmp al, '#' je next inc si jmp s1 next: mov ah, 2 mov dl, 0ah int 21h mov cx, si mov si, 0 s2: mov ah, 2 mov dl, [si] int 21h inc si loop s2 mov ah, 4ch int 21h code ends end start-
运行结果截图:
![]()
-
line11-18:获取键盘输入的值并赋值给ds:[si] ,若为“#”,则跳转到next处,否则si++后再次重新进入本循环。
-
line20-22:换行
-
line24-30:打印除“#”外所有用户输入的字符
-
实验任务3
- task3.asm源码:
assume cs:code, ds:data data segment x dw 91, 792, 8536, 65521, 2021 len equ $ - x data ends stack segment y dw 5 dup(?) stack ends code segment start: mov ax, data mov ds, ax mov ax, stack mov ss, ax mov sp, 10 mov si, offset x mov cx, 5 s: mov ax, [si] mov di, 0 mov bx, 10 sa: mov dx, 0 div bx or dl, 30h push dx inc di cmp ax, 0 jne sa s1: mov ah, 2 pop dx int 21h dec di cmp di, 0 jne s1 call s2 inc si inc si loop s mov ah, 4ch int 21h s2: mov ah, 2 mov dl, ' ' int 21h ret code ends end start- 运行结果截图如下:
![]()
-
实验任务4
- task4.asm源码:
assume cs:code, ds:data data segment str db "assembly language, it's not difficult but tedious" len equ $ - str data ends code segment start: mov ax, data mov ds, ax mov si, offset str mov cx, len call s1 mov ah, 4ch int 21h s1: mov ah, 2 mov dl, [si] cmp dl, 61h jb s2 cmp dl, 7ah ja s2 and dl, 11011111B s2: mov [si], dl inc si loop s1 ret code ends end start- 调试截图如下:
![]()
![]()
-
实验任务5
- task5.asm源码:
assume cs:code, ds:data data segment str1 db "yes", '$' str2 db "no", '$' data ends code segment start: mov ax, data mov ds, ax mov ah, 1 int 21h mov ah, 2 mov bh, 0 mov dh, 24 mov dl, 70 int 10h cmp al, '7' je s1 mov ah, 9 mov dx, offset str2 int 21h jmp over s1: mov ah, 9 mov dx, offset str1 int 21h over: mov ah, 4ch int 21h code ends end start-
程序运行测试截图:
![]()
-
程序的功能:判断用户键入的字符是否为7,是则输出“yes”,不是则输出“no”,输出位置在第24行70列。
-
实验任务6
- task6_1.asm源码:
assume cs:code code segment start: ; 42 interrupt routine install code mov ax, cs mov ds, ax mov si, offset int42 ; set ds:si mov ax, 0 mov es, ax mov di, 200h ; set es:di mov cx, offset int42_end - offset int42 cld rep movsb ; set IVT(Interrupt Vector Table) mov ax, 0 mov es, ax mov word ptr es:[42*4], 200h mov word ptr es:[42*4+2], 0 mov ah, 4ch int 21h int42: jmp short int42_start str db "welcome to 2049!" len equ $ - str ; display string "welcome to 2049!" int42_start: mov ax, cs mov ds, ax mov si, 202h mov ax, 0b800h mov es, ax mov di, 24*160 + 32*2 mov cx, len s: mov al, [si] mov es:[di], al mov byte ptr es:[di+1], 2 inc si add di, 2 loop s iret int42_end: nop code ends end start- task6_2.asm源码:
assume cs:code code segment start: int 42 mov ah, 4ch int 21h code ends end start- 运行结果截图如下:
![]()
task6_1.exe安装中断代码,task6_2.exe向CPU发出中断,最终指令42号中断程序成功调用!
-
实验总结
- 中断是指来自CPU执行指令以外的事件发生后,处理机暂停正在运行的程序,转去执行处理该事件的程序的过程。
- 软中断是软件实现的中断,也就是程序运行时其他程序对它的中断。
- 中断过程如下:
- 从中断信息中获取类型码;
- 标志寄存器的值入栈;
- 设置标志寄存器的TF和IF标志位为0
- CS的内容入栈
- IP的内容入栈
- 读取中断处理程序的入口地址IP和CS











浙公网安备 33010602011771号