实验4 8086标志寄存器及中断 201983290153吕轩皓
一、实验目的
1. 理解标志寄存器用途,理解常用标志位CF, ZF, OF, SF, TF, IF的用途和意义。
2. 理解条件转移指令je, jz, ja, jb, jg, jl等的跳转原理,掌握组合使用汇编指令cmp和条件转移指令实现
分支和循环的用法
3. 了解软中断指令的用法,体验和理解中断原理
4. 综合应用寻址方式和汇编指令完成简单应用编程
二、实验准备
复习教材「第10章 call和ret指令」、「第11章 标志寄存器」
学习教材「第12章 内中断 」、「第13章 int指令」三、实验内容
1. 实验任务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
inc di
inc di
loop s
pop di
pop si
pop cx
pop ax
ret
code ends
end start
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
在debug环境中,分别实践、观察:
① add指令对标志寄存器中的零标志位ZF(Zero Flag)、进位标志位CF(Carry Flag)是否有影响?
add指令会影响寄存器CF,ZF.
② inc指令对标志寄存器中的零标志位ZF(Zero Flag)、进位标志位CF(Carry Flag)是否有影响?
inc对寄存器CF没有影响
修改后debug

① line31~line34的4条inc指令,能否替换成如下代码?你的结论的依据/理由是什么?
add si, 2
add di, 2
调试后发现本题可以替换,在这个实验里128位加法中未产生进位
② 在debug中调试,观察数据段中做128位加之前,和,加之后,数据段的值的变化。
2. 实验任务2
使用任意文本编辑器,录入8086汇编源码task2.asm。
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
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
对源程序task2.asm进行汇编、链接,得到可执行文件task2.exe。
运行程序,从键盘上输入一串字符,以#结束(比如,输入George Orwell, 1984#),观察结果。结合运
行结果,理解代码并回答问题:
① 汇编指令代码line11-18,实现的功能是?
接收输入,当输入到#时输入截止,
② 汇编指令代码line20-22,实现的功能是?
回车效果
③ 汇编指令代码line24-30,实现的功能是?
将输入的字符串打印,但不输出#
3. 实验任务3
针对8086CPU,已知逻辑段定义如下:
assume cs:code
code segment
start:
int 42
mov ah, 4ch
int 21h
code ends
end start
data segment
x dw 91, 792, 8536, 65521, 2021
len equ $ - x
data ends
编写8086汇编源程序task3.asm,在屏幕上以十进制形式输出data段中这一组连续的数据,数据和数据
之间以空格间隔。
要求:
编写子程序printNumber
功能:以十进制形式输出一个任意位数的整数(整数范围0 ~ 65535)
入口参数:寄存器ax(待输出的数据 --> ax)
出口参数:无
编写子程序printSpace
功能:打印一个空格
入口参数:无
出口参数:无
在主体代码中,综合应用寻址方式和循环,调用printNumber和printSpace, 实现题目要求。
代码:
结果:
4. 实验任务4
针对8086CPU,已知逻辑段定义如下:
data segment
str db "assembly language, it's not difficult but tedious"
len equ $ - str
data ends
编写8086汇编源程序task4.asm,将data段中字符串里的小写字符转换成大写。
要求:
编写子程序strupr
功能:将包含任意字符的字符串中的小写字母变成大写
入口参数
(ds:si ) 字符串首地址的段地址和偏移地址分别送至ds和si
(cx) 字符串的长度
出口参数:无
在主体代码中,设置入口参数,调用strupr, 实现题目要求。
代码:
assume cs:code, ds:data
data segment
str db "assembly language, it's not difficult but tedious"
len = $ - str
data ends
code segment
start:
mov ax, data
mov ds, ax
mov si,offset str
mov cx,len
strupr:
mov al,[si]
call isLow
and al,11011111b
mov [si],al
printUpperLetter:
mov ah,2
mov dl,[si]
int 21h
next:inc si
loop strupr
cmp cx,0
je endd
isLow:
cmp al,'a'
jb next
cmp al,'z'
ja next
ret
endd:mov ah, 4ch
int 21h
code ends
end start
data segment
str db "assembly language, it's not difficult but tedious"
len = $ - str
data ends
code segment
start:
mov ax, data
mov ds, ax
mov si,offset str
mov cx,len
strupr:
mov al,[si]
call isLow
and al,11011111b
mov [si],al
printUpperLetter:
mov ah,2
mov dl,[si]
int 21h
next:inc si
loop strupr
cmp cx,0
je endd
isLow:
cmp al,'a'
jb next
cmp al,'z'
ja next
ret
endd:mov ah, 4ch
int 21h
code ends
end start
结果:
5. 实验任务5
使用任意文本编辑器,录入8086汇编源码task5.asm。
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
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
对源程序task5.asm进行汇编、链接,得到可执行文件task5.exe。
运行程序,输入7,观察结果。输入其他字符,观察结果。结合运行结果和注释,理解代码实现的功能。
程序功能时判断输入是否为7,输入7输出yes,其他输出no
6. 实验任务6
实验任务1、2、3、5中使用了不少系统提供的中断例程。本实验任务中,要求自行实现一个42号软中断
例程,使得通过 int 42 或 int 2ah 软中断调用,实现在屏幕最下方中间以黑底绿字打印"welcome to
2049!"。
建议配合教材第12章学习理解并实践。
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
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
code segment
start:
int 42
mov ah, 4ch
int 21h
code ends
end start
对汇编源程序task6_1.asm进行汇编、链接,得到可执行程序task6_1.exe。运行task6_1.exe,实现将
42号中断处理程序安装到0:200开始的连续内存空间,并设置中断向量表,使得将来通过 int 42 ,系统
可以跳转到中断处理程序。
对汇编源程序task6_2.asm进行汇编、链接,得到可执行程序task6_2.exe。运行task6_2.exe。
自己编写后输出

软中断是由程序执行的,执行int指令时,会产生中断信息,然后cpu会收到中断信息,执行改中断信息处理程序
浙公网安备 33010602011771号