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

任务一

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

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

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

 

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

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

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

 

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

add si, 2

add di, 2

不能,因为add指令会影响进位标志位CF, 从而影响128位加法的进位链.

2、 在debug中调试,观察数据段中做128位加之前,和,加之后,数据段的值的变化。

加之前:

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

加之后:

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

加之前076a:0000~076a:009存放的是x串被加数,加之后存放的是x与y相加后的结果.

 

任务二

task4_2的源码如下:

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

运行程序,从键盘上输入一串字符,以#结束(比如,输入George Orwell, 1984#),观察结果。结合运行结果,理解代码并回答问题:

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

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

输入一段字符,将其存入数据段中,如输入#则结束存入,进行跳转.

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

0ah是换行符的ASCII码,所以该处功能为输出换行.

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

按序输出存在数据段中的字符,#除外.

 

任务三

源码如下:

assume ds:data, cs:code, ss:stack

data segment
    x dw 91, 792, 8536, 65535, 2021, 0
    len equ  ($- x)/2  ;数据个数
data ends

stack segment
    dw 8 dup(0)
stack ends

code segment
start:
    mov ax, data
    mov ds, ax

    mov ax, stack
    mov ss, ax
    mov sp, 16

    mov cx, len
    mov di,0

    print:
        mov ax, word ptr ds:[di]    ; 把数据放入ax
        add di, 2                   ; di指针后移2字节处理下一个数据
        push cx             ; 防止寄存器冲突
        call printNumber    ; 打印数字
        call printSpace     ; 打印空格
        pop cx         
    loop print
    
    mov ah, 4ch
    int 21h

;打印数字
printNumber:
    mov bx, 0       ;位数
    get:
        mov bp, 10      
        mov dx, 0           
        div bp          
        push dx         
        inc bx          
        mov cx, ax      
        inc cx
    loop get


    mov cx, bx          ;逐位打印
    print1:
        pop dx          
        add dl, 30h     ;转化成字符
        mov ah, 2       
        int 21h
    loop print1

    ret

;打印空格
printSpace:
    mov ah, 2
    mov dl, 20h         ;空格ASCII码
    int 21h
    ret

code ends
end start

结果如下:

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

 

任务四:

源码如下:

assume cs:code,ds:data
data segment
    str db "assembly language, it's not difficult but tedious"
    len equ $ - str
data ends

stack segment
    db 8 dup(0)
stack ends

code segment
start: 
    mov ax, data
    mov ds, ax
    mov si, 0
    mov cx, len     
    call strupr     ; 大小写转换
    call printStr   ; 打印新的字符串

    mov ax, 4c00h
    int 21h

;逐字符进行小写字符判断及转换
strupr:
    push cx
    push si         ;压入栈,防止寄存器冲突导致原循环出错
    transform:
        mov al, ds:[si] 
    ; 取出一个字符,接下来判断该字符的ASCII码是否在97-122之间
    ;若在则进行大小写转换,若不在则跳转到下一个字符
        cmp al, 97      
        jl next     
        cmp al, 122     
        jg next     
        and al, 0dfh    ; 小写转成大写
        mov ds:[si], al ; 将大写字符写入
    next:
        inc si          
        loop transform  

    pop si
    pop cx          
    ret            

;打印新的字符串
printStr:
    push cx         
    push si        ;压入栈,防止寄存器冲突导致原循环出错

    print:          
        mov ah, 2
        mov dl, ds:[si]
        int 21h
        inc si
    loop print

    pop si          
    pop cx
    ret             

code ends
end start

结果如下:

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

 

任务五

源码如下:

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

结果如下:

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

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

该程序的功能为: 从键盘输入一个字符,如果为7,在屏幕的第24行第70列显示yes;

如果不为7,在屏幕的第24行第70列显示no.

 

 

任务六:

源码如下:

 task4_6_1:

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

task4_6_2:

assume cs:code

code segment
start:
    int 42

    mov ah, 4ch
    int 21h
code ends
end start

结果如下:

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

 

 (3)通过此项实现任务,你对中断、软中断实现机制的理解:

中断是指CPU在接收到外部发送的或内部产生的一种特殊信息时,会立即处理特殊信息;中断是指CPU内部产生特殊信息(如除法错误、单步执行、执行into指令和执行int指令)时,立即处理该情况。

上一篇:【Spring专场】「IOC容器」不看源码就带你认识核心流程以及运作原理


下一篇:实验3 转移指令跳转原理及其简单应用编程