实验4 8086标志寄存器及中断

一、实验目的

1. 理解标志寄存器用途,理解常用标志位CF, ZF, OF, SF, TF, IF的用途和意义。

2. 理解条件转移指令je, jz, ja, jb, jg, jl等的跳转原理,掌握组合使用汇编指令cmp和条件转移指令实现 分支和循环的用法

3. 了解软中断指令的用法,体验和理解中断原理

4. 综合应用寻址方式和汇编指令完成简单应用编程

三、实验内容

1. 实验任务1

验证性实验:有些汇编指令会影响到标志寄存器中的一个或多个状态标志位。 在debug环境中,分别实践、观察:

① add指令对标志寄存器中的零标志位ZF(Zero Flag)、进位标志位CF(Carry Flag)是否有影响?

答:对ZF、CF都有影响。

② inc指令对标志寄存器中的零标志位ZF(Zero Flag)、进位标志位CF(Carry Flag)是否有影响?

答:对ZF有影响,对CF没有影响。

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

① line31~line34的4条inc指令,能否替换成如下代码?你的结论的依据/理由是什么?

add si, 2
add di, 2

 

答:不能,因为add指令会改变CF的值。

② 在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

运行截图:

 

① 汇编指令代码line11-18,实现的功能是?

答:获取输入的字符,直到遇见#结束。

② 汇编指令代码line20-22,实现的功能是?

答:0ah是换行符的ascii码, 所以实现的功能是换行.

③ 汇编指令代码line24-30,实现的功能是?

 

 答:输出字符串,不包括#

3. 实验任务3

针对8086CPU,已知逻辑段定义如下: 编写8086汇编源程序task3.asm,在屏幕上以十进制形式输出data段中这一组连续的数据,数据和数据 之间以空格间隔。

要求:

编写子程序printNumber

功能:以十进制形式输出一个任意位数的整数(整数范围0 ~ 65535)

入口参数:寄存器ax(待输出的数据 --> ax)

出口参数:无

编写子程序printSpace

功能:打印一个空格 入口参数:无

出口参数:无 在主体代码中,综合应用寻址方式和循环,调用printNumber和printSpace, 实现题目要求。

assume cs:code, ds:data
data segment
    x dw 91, 792, 8536, 65521, 2021 
    len equ $ - x
data ends
stack segment
    db 16 dup(0)
stack ends
code segment
start:mov ax, data
        mov ds, ax
        
        mov cx, 5
        mov si, offset x

print:mov ax, ds:[si]
        call printNumber
        call printSpace
        inc si
        inc si
        loop print
 
        mov ah, 4ch
        int 21h

printNumber:
        mov bl, 10      
        mov dx, 0        
        mov di, 0
        push cx
s1:    div bx
        push dx         
        inc di
        mov dx, 0
        cmp ax, 0        
         je s2
        jmp s1

s2:    mov ah, 2
        mov cx, di
s3:    pop dx        
        or dl, 30h       
        int 21h
        loop s3

        pop cx
        ret
             
printSpace:
        mov ah, 2
        mov dl, ' '
        int 21h
        ret
 
code ends
end start

运行截图:

 

4. 实验任务4

针对8086CPU,已知逻辑段定义如下:

编写8086汇编源程序task4.asm,将data段中字符串里的小写字符转换成大写。

要求:

编写子程序strupr

功能:将包含任意字符的字符串中的小写字母变成大写

入口参数 (ds:si ) 字符串首地址的段地址和偏移地址分别送至ds和si (cx) 字符串的长度

出口参数:无 在主体代码中,设置入口参数,调用strupr, 实现题目要求。

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 cx,len
mov si,offset str
call strupr

mov ah,4ch
int 21h

strupr:
s:mov al,ds:[si] 
cmp al,'a' 
jb print 
cmp al,'z' 
ja print 

mov ah,2
and al,11011111b 
mov dl,al 
int 21h 
inc si 
loop s
ret

print:
mov ah,2
mov dl,al 
int 21h 
inc si  
loop s 

code ends
end start

 

 

 5. 实验任务5

使用任意文本编辑器,录入8086汇编源码task5.asm。

ask5.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 ; 设置光标位置在第24行
mov dl, 70 ; 设置光标位置在第70列
int 10h ; 设置光标位置
cmp al, '7'
je s1
mov ah, 9
mov dx, offset str2
int 21h ; 显示标号str2处的字符串
jmp over
s1: mov ah, 9
mov dx, offset str1
int 21h ; 显示标号str2处的字符串
over:
mov ah, 4ch
int 21h
code ends
end start

对源程序task5.asm进行汇编、链接,得到可执行文件task5.exe。

运行程序,输入7,观察结果。输入其他字符,观察结果。结合运行结果和注释,理解代码实现的功能。

运行截图:

 

 

 

 

 

 改程序实现的功能是:输入一个字符,判断是不是7;如果是则在第二十四行第七十列输出yes;如果不是则输出no。

6. 实验任务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 ; 调用自己实现的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。

 

运行截图:

屏幕底部输出了“welcome to 2049!”,表示42号中断被成功执行。

 

通过此项实现任务,你对中断、软中断的理解。

中断是指由于接收到外围硬件(相对于CPU与内存而言)的异步信号或者来自软件的同步信号而进行相应的硬件/软件处理。软终端是由软件本身发给操作系统内核的中断信号

 

posted @ 2021-12-13 09:26  山林路  阅读(46)  评论(2)    收藏  举报