汇编语言-第三版-王爽-第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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值