实验4 8086标志寄存器及中断
实验任务1
源代码:
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 add si, 2 ; inc di ; inc di add di, 2 loop s pop di pop si pop cx pop ax ret code ends end start
运行前:
运行后:
改变代码以后:
回答问题:在本题中可以进行替换,原因如下:首先,add的结果会影响标志进位寄存器,inc则不会;本题中偏移地址si, di从0开始,每次加2,总共循环8 次,最终是0eh,不涉及进位,所以不会对结果有影响。
实验任务2
源代码:
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
测试截图:
回答问题:11-18行是每次从键盘读取一个字符,并比较是否等于“#”,若不是,将这个字符放入数据段末尾,并继续读取下一个字符,否则先换行(20-22行实现,0ah对应换行符)打印数据段中已有的字符串(24-30行实现)。
实验任务3
源代码:
assume cs:code, ds:data data segment x dw 91, 792, 8536, 65521, 2021 len equ $- x data ends code segment start: mov ax, data mov ds, ax mov si, 0 mov cx, len / 2 s0: mov ax, [si] inc si inc si call printNumber call printSpace loop s0 mov ah, 4ch int 21h printNumber: push cx mov cx, 0 mov bx, 10 s: inc cx mov dx, 0 div bx push dx ; dx余数入栈 cmp ax, 0 ; 如果商为0,跳转s1 je s1 jmp s s1: pop dx ; 余数出栈 add dx, 48 mov ah, 2 mov dl, dl int 21h loop s1 pop cx ret printSpace: mov ah, 2 mov dl, 32 ;空格的ASCII码 int 21h ret code ends end start
测试截图:
实验任务4
源代码:
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 cx, len mov si, 0 call strupr mov ah, 4ch int 21h strupr: s0: mov al, [si] cmp al, 97 jl s1 cmp al, 122 jg s1 sub al, 32 mov byte ptr [si], al s1: inc si loop s0 ret code ends end start
测试截图:
调用strupr以后:
实验任务5
源代码:
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’ 在第24行70列输出对应的判断结果。
实验任务6
中断的意思是,CPU不再顺序地执行下一条命令,而转去处理外部或内部产生的一个特殊信息。8086CPU用一个字节存放中断类型码,最多可以表示256种中断信息的来源。CPU通过存放在内存地址0处的中断向量表获得不同的中断源对应的中断处理程序的入口地址。中断向量表的每个表项占两个字,高地址存放段地址,低地址存放偏移地址。中断过程与子程序调用的过程相似,主要是:(1)取得中断类型码 (2)标志寄存器的值入栈(3)设置标志寄存器TF和IF值为0 (4)CS入栈(5)IP入栈(6)从[中断类型码 * 4]和[中断类型码 * 4 + 2]两个字单元获取中断处理程序的入口地址IP和CS. 中断处理程序的结构通常是:安装、设置中断向量表、中断处理的核心部分do0.
一个常用的中断命令是int n;n是中断类型码。
书p262 实验13(1)编写并安装int 7ch中断例程,功能为显示一个以数字0为结尾的字符串,例程安装在0: 200处。
源代码:
Task6_3.asm
assume cs:code code segment start: ; 安装do0 mov ax, cs mov ds, ax mov si, offset do0 mov ax, 0 mov es, ax mov di, 200h cld rep movsb mov ax, 0 mov es, ax mov word ptr es:[7ch * 4], 200h ; 偏移地址 mov word ptr es:[7ch * 4 + 2], 0 ; 段地址 mov ah, 4ch int 21h do0: push ax push bx push cx push dx push si mov ah, 0 mov al, dh mov dh, 0ah mul dh add ax, 0b800h mov es, ax mov al, dl mov dl, 2 mul dl mov bx, ax s: mov al, ds:[si] cmp al, 0 je ok mov ah, cl mov es:[bx], ax inc si add bx, 2 jmp s ok: pop si pop dx pop cx pop bx pop ax mov ah, 4ch int 21h do0end: nop code ends end start
Task6_4.asm
assume cs:code data segment db "Welcome to masm!", 0 data ends code segment start: mov dh, 10 mov dl, 10 mov cl, 2 ; 黑底绿字 mov ax, data mov ds, ax mov si, 0 int 7ch mov ah, 4ch int 21h code ends end start
测试截图: