实验4 8086标志寄存器及中断
实验4 8086标志寄存器及中断
实验任务1:
test01.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指令,能否替换?你的结论的依据/理由是什么?
答:不可以替换,因为add语句会产生进位,影响CF标志位的值,导致计算结果出错。
在debug中调试,观察数据段中做128位加之前和加之后,数据段的值的变化。给出调试观察截图。
——数据段中做128位加之前:
——数据段中做128位加之后:
实验任务2:
程序test02.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,实现的功能是?
答:将al中的输入字符存到si中,并与‘#’进行比较,若相同,跳出循环,若反之,则继续循环。
② 汇编指令代码line20-22,实现的功能是?
答:输出换行符,进行换行。
③ 汇编指令代码line24-30,实现的功能是?
答:输出除‘#’以外的所有输入字符,因为‘#’并没有令si增一,循环输出时的次数是si,所以不会输出‘#’
实验任务3:
编写8086汇编源程序test03.asm,在屏幕上以十进制形式输出data段中这一组连续的数据,数据和数据之间以空格间隔
test03.asm源码:
1 assume cs:code, ds:data 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 ax, stack 17 mov ss, ax 18 mov sp, 16 19 mov si, offset x 20 21 mov cx, 5 22 23 s: 24 mov ax, ds:[si] 25 call printNumber 26 call printSpace 27 add si, 2 28 loop s 29 30 mov ah, 4ch 31 int 21h 32 33 34 printNumber: 35 push cx 36 mov cx, 0 37 s2: 38 mov bx, 10 39 mov dx, 0 40 div bx 41 push dx 42 inc cx 43 cmp ax, 0 44 jne s2 45 46 s3: 47 pop bx 48 or bl, 30h 49 mov ah, 2 50 mov dl, bl 51 int 21h 52 loop s3 53 pop cx 54 ret 55 56 57 58 printSpace: 59 mov ah, 2 60 mov dl, 20h 61 int 21h 62 ret 63 64 65 code ends 66 end start
运行测试截图:
实验任务4
编写8086汇编源程序test04.asm,将data段中字符串里的小写字符转换成大写。
test04.asm源码:
1 data segment 2 str1 db "assembly language, it's not difficult but tedious" 3 len equ $ - str1 4 data ends 5 6 stack segment 7 db 16 dup(0) 8 stack ends 9 10 code segment 11 assume cs:code,ds:data,ss:stack 12 start: 13 mov ax,data 14 mov ds,ax 15 mov si,offset str1 16 mov cx,len 17 call strupr 18 19 mov ah,4ch 20 int 21h 21 22 strupr: 23 s: 24 mov al,ds:[si] 25 26 cmp al,'a' 27 jb next 28 cmp al,'z' 29 ja next 30 31 and al,0dfh;1101 1111 32 mov ds:[si],al 33 34 next: 35 inc si 36 loop s 37 ret 38 39 code ends 40 end start
在debug中调试截图( call strupr 调用之前,数据段的值,以及,调用之后,数据段的值):
call strupr 调用之前:
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 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: 31 mov ah, 9 32 mov dx, offset str1 33 int 21h 34 over: 35 mov ah, 4ch 36 int 21h 37 code ends 38 end start
程序运行测试截图(输入7,以及输入其他字符,运行结果截图):
程序的功能是?:
答:当键盘输入7后,在屏幕24行70列显示yes, 若输入其他字符,则在屏幕24行70列显示no。该程序设置了光标位置为:0页24行70列。当输入字符为7时,跳转到标号s1处,调用int 21h的子功能,在设置的光标位置显示字符串"yes";若不为7,调用int 21h的子功能,在设置的光标位置显示字符串"no"。
实验任务6:
源代码:
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
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
实验截图:
通过此项实现任务,你对中断、软中断实现机制的理解:
答:中断是指CPU不再接着向下执行,而是转去处理这个特殊信息。是指由于接收到外围硬件(相对于CPU与内存而言)的异步信号或者来自软件的同步信号而进行相应的硬件/软件处理。CPU接受到中断信息后,可以立即对中断信息进行处理,用来处理中断信息的程序被称为中断处理程序。软中断是指由软件本身发给操作系统内核的中断信号。
中断过程是先从从中断信息中取得中断类型码,然后令标志寄存器的值入栈(因为在中断过程中要改变标志寄存器的值,所以先将其保存在栈中),并设置标志寄存器的第8位TF和第9位IF的值为0。CS的内容入栈,IP的内容入栈。最后从内存地址为中断类型码*4和中断类型码*4+2的两个子单元中读取中断处理程序的入口地址设置IP和CS。