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