實驗4 8086標志寄存器及中斷


實驗4 8086標志寄存器及中斷

實驗任務1

任務點1

驗證add對ZF和CF的影響


可以看到對ZF和CF都造成了影響

驗證inc對ZF和CF的影響


只對ZF造成影響

測試代碼如下

assume cs:code,ds:data
data segment
    db 16 dup(0)
data ends
stack segment
    db 128 dup(0)
    top equ $+1
stack ends
code segment
start:
    mov ax,data
    mov ds,ax
    mov ax,stack
    mov ss,ax
    mov sp,top

    mov ax,0ffffh
    add ax,1
    ;測試add對CF和ZF的影響

    mov ax,1
    add ax,1
    ;恢復測試之前的影響,即無進位

    mov ax,0ffffh
    inc ax
    ;測試inc對CF和ZF的影響
    mov ah,4ch
    int 21h
code ends
end start

任務點2

TASK_1.ASM代碼

assume cs:code, ds:data

data segment
   x dw 1020h, 2240h, 9522h, 5060h, 3359h, 6652h, 2530h, 7031h;一個128位數字
   y dw 3210h, 5510h, 6066h, 5121h, 8801h, 6210h, 7119h, 3912h;一個128位數字
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

對於inc能否用add替換的回答

inc的結果

add的結果

可以看到沒有任何區別,這是因為代碼中給出的數據不會產生任何進位,所以addinc在這種特殊的情況下無區別
下面修改代碼里面的數據,使其能產生進位

data segment
   x dw 9020h, 2240h, 9522h, 5060h, 3359h, 6652h, 2530h, 7031h
   y dw 9210h, 5510h, 6066h, 5121h, 8801h, 6210h, 7119h, 3912h
data ends

inc的結果

add的結果

這就有了區別了
后16位的運算需要用到前16位運算的進位值,所以不能用add
因為根據之前的實驗,add會對CF標志寄存器造成影響,inc則不會。

運行並觀察數據段的變化

做加法之前

做加法后

可以看到進行了加法,但並沒有產生進位
接下來的運行結果類似,並沒有產生進位

實驗任務2

代碼以及注釋解析

assume cs:code, ds:data
data segment
        str db 80 dup(?);80個字節未初始化的內存空間
data ends

code segment
start:  
        mov ax, data
        mov ds, ax
        mov si, 0
s1:        
        mov ah, 1;int 21h中斷的參數,表示輸入單個字符
        int 21h;調用中斷例程
        mov [si], al;將結果存入ds:[si]中
        cmp al, '#';與'#'比對,影響標志寄存器ZF,運算結果為0表示相同,則ZF標志寄存器變為ZR
        je next;if(al == '#'(ZF == ZR)) goto next
        inc si;偏移地址加一
        jmp s1;繼續輸入一個字符
next:
        mov ah, 2;int 21h中斷的參數,表示打印一個ASCII字符
        mov dl, 0ah;換行
        int 21h;調用中斷例程
        
        mov cx, si;將輸入的字符的數量(不包括#)賦給cx寄存器
        mov si, 0;將si寄存器置零
s2:     mov ah, 2;int 21h中斷的參數,表示打印一個ASCII字符
        mov dl, [si];將ds:[si]出內存的值賦給dl
        int 21h;調用中斷例程
        inc si;偏移地址+1
        loop s2;循環,直到cx=0

        mov ah, 4ch;int 21h中斷的參數,表示回到DOS
        int 21h;執行中斷例程
code ends
end start

運行結果

實驗任務2

代碼

assume cs:code,ds:data
data segment
    x dw 91, 792, 8536, 65521, 2021
    len equ $ - x
data ends
stack segment
    db 64 dup(0)
    top equ $+1
stack ends
code segment
start:
    mov ax,data
    mov ds,ax
    mov ax,stack
    mov ss,ax
    mov sp,top

    mov cx,len/2
    mov bx,0
s1:  
    mov ax,ds:[bx]
    push bx
    push cx
    call printNumber
    call printSpace
    pop cx
    pop bx
    add bx,2
    loop s1

    mov ah,4ch
    int 21h

printNumber:
    ;ax dx
    ;ax 被除數,直到
    ;cx計有多少位,然后循環出棧輸出
    mov bx,10
    mov cx,0
s2:
    mov dx,0
    div bx
    ;ax 商
    ;dx 余數
    push dx
    inc cx
    cmp ax,0
    jne s2

s3:
    mov ah,2
    pop dx
    or dl,30h
    int 21h
    loop s3
    ret

printSpace:
    mov ah,2
    mov dl,20h
    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 = ($ - str)
data ends
stack segment
    db 128 dup(0)
    top equ $ + 1
stack ends
code segment
start:
    mov ax,data
    mov ds,ax
    mov ax,stack
    mov ss,ax
    mov sp,top

    mov si,0
    mov cx,len
    call strupr
    mov ah,4ch
    int 21h
strupr:
;0100 0001 A
;0110 0001 a
s:
    cmp byte ptr ds:[si],61h
    jb s1
    cmp byte ptr ds:[si],7ah
    ja s1
    mov dl,ds:[si]
    and dl,11011111B
    mov ds:[si],dl
s1: 
    inc si
    loop s
    ret
code ends
end start

運行結果

實驗任務5

代碼注釋解析

assume cs:code, ds:data
;輸入7,則屏幕顯示yes
;否則輸出no
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;int 10h 2號功能,設置光標位置
    mov bh, 0;頁號
    mov dh, 24;行號
    mov dl, 70;列號
    int 10h;BIOS中斷例程調用

    cmp al, '7'
    je s1;ZF == ZR 跳轉,相等跳轉
    mov ah, 9;輸出字符串
    mov dx, offset str2;字符串首地址
    int 21h;DOS中斷例程

    jmp over

s1: mov ah, 9;輸出字符串
    mov dx, offset str1;字符串首地址
    int 21h;DOS中斷例程
over:  
    mov ah, 4ch
    int 21h;DOS中斷例程
code ends
end start

運行結果

實驗任務6

實驗子任務1

將例程直接內嵌進task6_1.asm的代碼中了
運行結果如下

中斷和軟中斷的區別

中斷,其實就是中斷源發出中斷信號,CPU暫定當前的程序,轉而去執行其他程序,即改變CS:IP
中斷源有很多,CPU內部的中斷源發出中斷信號,外部設備發出的中斷信號。
硬件中斷指的就是外部設備發出的電信號中斷信號,需要中斷控制器,排隊器等硬件電路實現。
軟中(內)斷就是CPU內部產生的中斷信號,比如除法溢出,或者程序調用中斷例程,感覺和call類似。

實驗子任務2

實現了書本上對於0號中斷例程的修改。

代碼

assume cs:code

code segment
start:
    mov ax,0
    mov es,ax;目的段地址
    mov ax,cs
    mov ds,ax;源段地址
    mov di,200h
    mov si,d0s
    mov cx,d0len

    movd0:;將代碼復制到0:200處
        mov al,ds:[si]
        mov es:[di],al
        inc si
        inc di
        loop movd0
    
    ;設置中斷表,中斷表處於內存中
    ;中斷表ip: 中斷號*4
    ;中斷表cs: 中斷號*4+2
    mov ax,0
    mov ds,ax
    mov word ptr ds:[0],200h
    mov word ptr ds:[2],0


    ;測試例程
    mov ax,1000h
    mov bh,1
    div bh
    ;測試例程

    mov ax,4c00h
    int 21h
d0:
    d0s equ $
    ;將字符串常駐內存
    jmp short d0start
    db "overflow!"
d0start:
    mov ax,cs
    mov ds,ax
    mov si,202h
    mov ax,0b800h
    mov es,ax
    mov di,12*160+36*2
    mov cx,9
s:  mov al,[si]
    mov es:[di],al
    inc si
    add di,2
    loop s

    ;iret;中斷返回,這里不返回,直接調用DOS中斷,返回DOS,不然會卡死
    mov ah,4ch
    int 21h
    d0len equ $-d0s
code ends
end start

運行結果


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM