马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 奥普瓯江 于 2019-3-27 16:43 编辑
(1)仔细分析一下上面的int 9 中断例程, 看看是否可以精简一下?
其实在我们的int 9 中断例程中, 模拟int 指令调用原int 9 中断例程的程序段是可以精简的, 因为在进入中断例程后, IF 和 TF都已经置0,没有必要在进行设置了。
对于程序段:
pushf
pushf
pop ax
and ah, 11111100b
push ax
popf
call dword ptr ds:[0]
可以精简为: pushf ;因为下面的返回中call模拟int 9h 程序返回时需要 寄存器数据,所以这里需要向栈中输入一个cf寄存器数据供下面call中的iret返回使用
call dword ptr ds:[0] ;这个是必须有的所以他不能动模拟int 9 程序
原程序如下:assume cs:code, ds:data_1, ss:stack
data_1 segment
dw 0,0
data_1 ends
stack segment
db 128 dup (0)
stack ends
code segment
start:
mov ax, data_1 ;数据段
mov ds, ax
mov si, 0
mov ax, stack ;栈定义 ,这里定义不定义栈其实无所谓,因为编译器会自动定义栈位ffff
mov ss, ax
mov sp, 128
mov ax, 0
mov es, ax
;把int 9h中断限量表中的地址传给数据段0、1和2、3, 这样中断限量表中的int 9h 中断就不会消失了,他的地址一致会储存在数据段中随时让我们可以调用
push es:[9 * 4] ;低位为偏移地址
pop ds:[0] ;ds低位为偏移地址储存
push es:[9 * 4 + 2] ;高位为段地址
pop ds:[2] ;ds高位为短地址储存
mov word ptr es:[9 * 4], offset int9 ;偏移地址
mov word ptr es:[9 * 4 + 2], cs ;短地址每个地址占两个字节一共4个字节
mov ax, 0b800h
mov es, ax
mov ah, 'a'
s:
mov byte ptr es:[160 * 12 + 40 * 2], ah
inc ah
call jump_1
cmp ah, 'z'
jna s
;把中断向量表中的地址恢复成初始地址
mov ax, 0
mov es, ax
push word ptr ds:[0]
pop word ptr es:[9 * 4]
push word ptr ds:[2]
pop word ptr es:[9 * 4 + 2]
mov ax, 4c00h
int 21h
jump_1:
push ax
push dx
mov ax, 0
mov dx, 1000h
jump_2:
sub ax, 1
sbb dx, 0
cmp ax, 0 ;内循环
jne jump_2
cmp dx, 0 ;外循环
jne jump_2
pop dx
pop ax
ret
int9:
push ax
push es
push ds
pushf
pushf
pop ax
and ax, 11111100b
push ax
popf
call dword ptr ds:[0]
in al, 60h
cmp al, 1
jne good
inc byte ptr es:[160 * 12 + 40 * 2 + 1]
good:
pop ds
pop es
pop ax
iret
code ends
end start
int 9临时模拟图示这个是自己看的
|