- [mywiil] 我没用书上的入栈出栈写,就是先看看不用书上的方法能做出来否? ============== 不错 09/19 09:24
- [njutyangxiao] 谢谢你的指导 09/18 17:00
- [younggay] 嗯,应该说理解的没问题。 09/18 15:41
- [njutyangxiao] 检测点16.1的题目是中是这样定义的: a dw 1,2,3,4,5,6,7,8 b dd 09/16 11:23
- [njutyangxiao] 嗯,谢谢指导 09/16 11:22
- [wsrf] assume伪指令指定了段中标号与相应段寄存器的联系。 09/16 09:46
- [wsrf] 没有问题,不过源代码中 a db 1,2,3,4,5,6,7,8 b dw 0 怎么 09/16 09:43
- [njutyangxiao] 谢谢,keep moving! 09/16 09:06
- [njutyangxiao] 谢谢你的指导 09/16 09:05
- [njutyangxiao] 谢谢你的指导 09/16 09:05
[2009-09-14 14:12] 检测点15.1
题目(一):仔细分析一下上面的int9中断例程,看看是否可以精简?
对于程序段:
pushf
pushf
pop ax
and ah,11111100b
push ax
popf
call dword ptr ds:[0]
可以精简为:
___(1)_____
___(2)_____
解答:因为是在int9中调用原来的int 9中断例程,而在我们进入int9这个中断程序时要做以下步骤:
(1_1)取得中断类型码N;
(1_2)标志寄存器入栈,TF=0、IF=0;
(1_3)CS、IP入栈;
(1_4)(IP)=(N*4),(CS)=(N*4+2)。
当做完以上步骤再来执行程序。在执行程序得 过程中需要调用原来的int 9中断例程。所以也要进行相应的设置:
(2_1)取得中断类型码N;
(2_2)标志寄存器入栈,TF=0、IF=0;
(2_3)CS、IP入栈;
(2_4)(IP)=(N*4),(CS)=(N*4+2)。
但是我们知道在(1_2)时已经把tf、if设置为0 。所以(2_2)这一步的设置tf、if为0可以省略掉了.所以可以精简为:
(1):pushf
(2):call dword ptr ds:[0]
题目(二):仔细分析上面的程序中的主程序,看看有什么潜在问题?
在主程序中,如果在执行设置int 9中断例程的段地址和偏移地址的指令之间发生了键盘中断,则cpu将转去一个错误的地址执行,将发生错误。着处这样的程序段,改写他们,排除潜在的问题。
源代码:
assume cs:codesg
stacksg segment
db 128 dup(0)
stacksg ends
datasg segment
dw 0,0
datasg ends
codesg segment
start:
mov ax,stacksg
mov ss,ax
mov sp,128
mov ax,datasg
mov ds,ax
mov ax,0
mov es,ax
push es:[9*4]
pop ds:[0]
push es:[9*4+2]
pop ds:[2]
mov word ptr es:[9*4],offset int9
mov es:[9*4+2],cs
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]
mov ax,4c00h
int 21h
;;;;;;;;;;;;delay;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
delay:
push ax
push dx
mov ax,0
mov dx,0ffffh
s1:
sub ax,1
sbb dx,0
cmp ax,0
jne s1
cmp dx,0
jne s1
pop dx
pop ax
ret
;;;;;;;;;;int9;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
int9:
push ax
push bx
push es
in al,60h
pushf
pushf
pop bx
and bh,11111100b
push bx
popf
call dword ptr ds:[0]
cmp al,1
jne int9ret
mov ax,0b800h
mov es,ax
inc byte ptr es:[160*12+40*2+1]
int9ret:
pop es
pop bx
pop ax
iret
codesg ends
end start
分析:也就是在执行这两条指令时:
mov word ptr es:[9*4],offset int9
mov es:[9*4+2],cs
可能会发生错误,建设执行了mov word ptr es:[984】,offset int9这句指令后,接收到了键盘中断,那么cpu就要相应中断,就要设置cs、ip,但是这时ip的值是改变了,但是cs的值却还没有来得及改变。则此时cs:ip将会指向一个既不是新int 9中断例程的入口处,也不是指向旧int9中断例程的入口处。这时肯定会引起错误。所以我们要把屏蔽掉键盘中断。即先要设置if=0。执行完之后再恢复这两条指令后再将其设置为1。
所以上面的两条指令应该改为:
cli
mov word ptr es:[9*4],offset int9
mov es:[9*4+2],cs
sti
效果见上图
对于程序段:
pushf
pushf
pop ax
and ah,11111100b
push ax
popf
call dword ptr ds:[0]
可以精简为:
___(1)_____
___(2)_____
解答:因为是在int9中调用原来的int 9中断例程,而在我们进入int9这个中断程序时要做以下步骤:
(1_1)取得中断类型码N;
(1_2)标志寄存器入栈,TF=0、IF=0;
(1_3)CS、IP入栈;
(1_4)(IP)=(N*4),(CS)=(N*4+2)。
当做完以上步骤再来执行程序。在执行程序得 过程中需要调用原来的int 9中断例程。所以也要进行相应的设置:
(2_1)取得中断类型码N;
(2_2)标志寄存器入栈,TF=0、IF=0;
(2_3)CS、IP入栈;
(2_4)(IP)=(N*4),(CS)=(N*4+2)。
但是我们知道在(1_2)时已经把tf、if设置为0 。所以(2_2)这一步的设置tf、if为0可以省略掉了.所以可以精简为:
(1):pushf
(2):call dword ptr ds:[0]
题目(二):仔细分析上面的程序中的主程序,看看有什么潜在问题?
在主程序中,如果在执行设置int 9中断例程的段地址和偏移地址的指令之间发生了键盘中断,则cpu将转去一个错误的地址执行,将发生错误。着处这样的程序段,改写他们,排除潜在的问题。
源代码:
assume cs:codesg
stacksg segment
db 128 dup(0)
stacksg ends
datasg segment
dw 0,0
datasg ends
codesg segment
start:
mov ax,stacksg
mov ss,ax
mov sp,128
mov ax,datasg
mov ds,ax
mov ax,0
mov es,ax
push es:[9*4]
pop ds:[0]
push es:[9*4+2]
pop ds:[2]
mov word ptr es:[9*4],offset int9
mov es:[9*4+2],cs
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]
mov ax,4c00h
int 21h
;;;;;;;;;;;;delay;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
delay:
push ax
push dx
mov ax,0
mov dx,0ffffh
s1:
sub ax,1
sbb dx,0
cmp ax,0
jne s1
cmp dx,0
jne s1
pop dx
pop ax
ret
;;;;;;;;;;int9;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
int9:
push ax
push bx
push es
in al,60h
pushf
pushf
pop bx
and bh,11111100b
push bx
popf
call dword ptr ds:[0]
cmp al,1
jne int9ret
mov ax,0b800h
mov es,ax
inc byte ptr es:[160*12+40*2+1]
int9ret:
pop es
pop bx
pop ax
iret
codesg ends
end start
分析:也就是在执行这两条指令时:
mov word ptr es:[9*4],offset int9
mov es:[9*4+2],cs
可能会发生错误,建设执行了mov word ptr es:[984】,offset int9这句指令后,接收到了键盘中断,那么cpu就要相应中断,就要设置cs、ip,但是这时ip的值是改变了,但是cs的值却还没有来得及改变。则此时cs:ip将会指向一个既不是新int 9中断例程的入口处,也不是指向旧int9中断例程的入口处。这时肯定会引起错误。所以我们要把屏蔽掉键盘中断。即先要设置if=0。执行完之后再恢复这两条指令后再将其设置为1。
所以上面的两条指令应该改为:
cli
mov word ptr es:[9*4],offset int9
mov es:[9*4+2],cs
sti
效果见上图
评论次数(2) |
浏览次数(613) |
类型(汇编作业) |
收藏此文 |