彙編語言-第三版-王爽-第15章 外中斷-第16章 直接定址表

P280:在屏幕中間依次顯示a~z, 顯示過程中,按下ESC鍵後,改變顯示顏色

P283:在DOS下,按F1鍵後改變當前屏幕的顯示顏色,其他的鍵照常處理

P293:以十六進制的形式顯示給定的字節型數據

P295:計算sin(x) x=0 30 60 90 120 150 180


* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 

第15章  P280:在屏幕中間依次顯示a~z, 顯示過程中,按下ESC鍵後,改變顯示顏色

; DATE: 20190621
; DESCRIPTION: 在屏幕中間依次顯示a~z, 顯示過程中,按下ESC鍵後,改變顯示顏色
;
; 已知:int 9爲BIOS提供的一箇中斷例程,用來進行基本的鍵盤輸入處理

assume cs:code

stack segment
    db 128 dup (0)
stack ends

data segment
    dw 0, 0
data ends

code segment
start:
    mov ax, stack
    mov ss, ax
    mov sp, 128     ; ss:sp
    
    mov ax, data
    mov ds, ax
    
    mov ax, 0
    mov es, ax
    
    push es:[9*4]
    pop ds:[0]
    push es:[9*4+2] ; 使用棧,
    pop ds:[2]      ; 將原來的int 9中斷例程的入口地址保存在ds:0、ds:0單元中
    
    cli     ; 設置IF標誌位爲0,不響應可屏蔽中斷
    mov word ptr es:[9*4], offset int9
    mov es:[9*4+2], cs  ; 在中斷向量表中設置新的int 9中斷例程的入口地址
    sti     ; 設置IF標誌位爲1,恢復響應可屏蔽中斷

; ------ 在屏幕中間依次顯示a~z ------ 
    mov ax, 0b800H
    mov es, ax
    mov ah, 'a'
s:
    mov es:[160*12+40*2], ah
    call delay
    inc ah
    cmp ah, 'z'
    jna s
    
    mov ax, 0 
    mov es, ax 
    
    push ds:[0]
    pop es:[9*4]
    push ds:[2]
    pop es:[9*4+2] ; 將中斷向量表中int 9中斷例程的入口恢復爲原來的地址
    
    mov ax, 4c00H
    int 21H

; ------ 循環延時 ------     
delay:
    push ax
    push dx
    mov dx, 02H ; 循環20000H次,根據自己機器的速度調整循環次數
    mov ax, 0 
s1:
    sub ax, 1 
    sbb dx, 0
    cmp ax, 0 
    jne s1 
    cmp dx, 0 
    jne s1 
    pop dx 
    pop ax 
    ret

; ------ 以下爲新的 int 9 中斷例程 ------    
int9:
    push ax 
    push bx 
    push es 
    
    in al, 60H ; 從端口60H讀出鍵盤的輸入
    
    pushf   ; 標誌寄存器入棧
    ; 進入中斷例程後,IF和TF都已經置0,沒必要再進行設置
    ;pushf
    ;pop bx 
    ;and bh, 11111100B ; IF和TF爲標誌寄存器的第9位和第8位
    ;push bx 
    ;popf               ; IF=0, TF=0
    call dword ptr ds:[0]   ; 調用原來的int 9中斷例程
            ; call dword ptr: CS、IP入棧; (IP)=(ds)*16+0、(CS)=(ds)*16+2
    
    cmp al, 1   ; 按下ESC鍵產生的掃描碼爲1
    jne int9ret
    
    mov ax, 0b800H
    mov es, ax
    inc byte ptr es:[160*12+40*2+1] ; 將屬性值加1,改變顏色
int9ret:
    pop es
    pop bx
    pop ax
    iret
    
code ends
end start

 

 


* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 

第15章  P283:在DOS下,按F1鍵後改變當前屏幕的顯示顏色,其他的鍵照常處理

; DATE: 20190622
; DESCRIPTION: 在DOS下,按F1鍵後改變當前屏幕的顯示顏色,其他的鍵照常處理
;
; 已知:int 9爲BIOS提供的一箇中斷例程,用來進行基本的鍵盤輸入處理
assume cs:code

stack segment
    db 128 dup (0)
stack ends

code segment
start:
    mov ax, stack
    mov ss, ax
    mov sp, 128         ; ss:sp
    
    push cs
    pop ds
    mov si, offset int9 ; ds:si指向源地址
    
    mov ax, 0
    mov es, ax
    mov di, 204H        ; es:di指向目的地址
    
    ; 將新int 9中斷例程安裝在0:204開始處
    mov cx, offset int9end - offset int9 ; cx傳輸長度
    cld         ; 將DF標誌位置0,即傳輸方向爲正
    rep movsb   ; 從ds:si複製到es:di
    
    ; 將原int 9中斷例程的入口地址保存到0:200單元
    ; 所以,程序二次執行將出錯
    push es:[9*4]
    pop es:[200H]
    push es:[9*4+2]
    pop es:[202H]
    
    ; 將新int 9中斷例程的入口地址保存到中斷向量表
    cli     ; 將IF標誌位置0,不響應可屏蔽中斷
    mov word ptr es:[9*4], 204H
    mov word ptr es:[9*4+2], 0
    sti     ; 將IF標誌位置1,響應可屏蔽中斷
    
    mov ax, 4c00H
    int 21H
    
int9:
    push ax
    push bx
    push cx
    push es
    
    in al, 60H  ; 從端口60H讀出鍵盤的輸入
    
    pushf       ; 標誌寄存器入棧
    call dword ptr cs:[200H] ; 當此中斷例程執行時(CS)=0
    
    cmp al, 3bH     ; F1鍵的掃描碼爲3bH
    jne int9ret

    ; 改變當前屏幕的顯示顏色,即從b800H開始的4000Bytes中的所有奇地址單元
    mov ax, 0b800H
    mov es, ax
    mov bx, 1
    mov cx, 2000
s:  inc byte ptr es:[bx]
    add bx, 2
    loop s 
    
int9ret:
    pop es
    pop cx
    pop bx
    pop ax
    iret
int9end:
    nop
code ends
end start    

 

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 

第16章  P293:以十六進制的形式顯示給定的字節型數據

; DATE: 20190622
; DESCRIPTION: 以十六進制的形式顯示給定的字節型數據
;   用al傳送要顯示的數據
;   查表

showbyte:
    jmp short show
table db '0123456789ABCDEF' ; 字符表

show:
    push bx
    push es
    
    mov ah, al
    mov cl, 4
    shr ah, 4           ; 右移4位,ah中得到高4位的值
    and al, 00001111B   ; al爲低4位的值
    
    mov bl, ah
    mov bh, 0
    mov ah, table[bx]   ; 用高4位的值作爲table偏移,取得對應的字符
    
    mov bl, al
    mov bh, 0
    mov al, table[bx]   ; 用低4位的值作爲table偏移,取得對應的字符
    
    mov bx, 0b800H      ; 顯示緩衝區
    mov es, bx
    mov es:[12*160+40*2], ax
    
    pop es
    pop bx
    ret

 


* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 

第16章  P295:計算sin(x) x=0 30 60 90 120 150 180

; DATE: 20190622
; DESCRIPTION: 計算sin(x) x=0 30 60 90 120 150 180
;   用ax傳送角度
;   查表

showsin:
    jmp short show
table   dw ag0, ag30, ag60, ag90, ag120, ag150, ag180 ; 偏移地址表

ag0     db '0', 0
ag30    db '0.5', 0
ag60    db '0.866', 0
ag90    db '1', 0
ag120   db '0.866', 0
ag150   db '0.5', 0
ag180   db '0', 0

show:
    push bx
    push es
    push di
    
    mov bx, 0b800H
    mov es, bx
    
    ; 用角度值/30作爲table偏移,取得對應的偏移地址,放在bx中
    mov ah, 0
    mov bl, 30
    div bl
    mov bl, al
    mov bh, 0
    add bx, bx
    mov bx, table[bx]
    
    mov di, 12*160+40*2
shows:
    mov ah, cs:[bx]
    cmp ah, 0 
    je showret
    mov es:[di], ah
    inc bx
    add di, 2
    jmp short shows 
showret:
    pop di
    pop es
    pop bx
    ret

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章