|
主题 : : 实验16,有谁能解释的更清楚些啊? [待解决] |
回复[ 6次 ]
点击[ 719次 ] | |
|
|
|
|
[帖 主]
[ 发表时间:2009-07-04 10:12 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:3
注册日期:2009-03-13 16:19 |
我在做实验16的时候遇到了一个和大家一样的问题,就是在用call word ptr table[bx]这句代买调用相关子程序时,不能进行正确的定位,以致发生错误!在论坛里面来看了很多相关度解释,还是觉得很迷茫啊,小弟愚钝的紧,请高人不吝赐教,帮帮小弟,给个更为清楚易懂的解释,在这里先谢谢了!
代码如下:
assume cs:code
code segment
start:mov ax,cs
mov ds,ax
mov si,offset setscreen
mov ax,0
mov es,ax
mov di,200h
mov cx,offset setend-offset setscreen
cld
rep movsb
mov word ptr es:[7ch*4],200h
mov word ptr es:[7ch*4+2],0 设置中断向量表(好像这个地方也有问题)
mov ax,4c00h
int 21h
setscreen:jmp short set
table dw sub1,sub2,sub3,sub4 (这个地方也是有问题)
set:push bx
cmp ah,3
ja setiret
mov bl,ah
mov bh,0
add bx,bx
call word ptr table[bx] (这句代码不能进行正确的定位,但我知道这句话是直接定址表的精髓所在,要怎样修改呢?)
setiret:pop bx
iret
sub1:push ax
push cx
push es
push bx
mov bx,0
mov ax,0b800h
mov es,ax
mov cx,2000
sub1s:mov byte ptr es:[bx],' '
add bx,2
loop sub1s
pop bx
pop es
pop cx
pop ax
ret
sub2:push bx
push es
push cx
mov bx,0b800h
mov es,bx
mov bx,1
mov cx,2000
sub2s:and byte ptr es:[bx],11111000b
or es:[bx],al
add bx,2
loop sub2s
pop cx
pop es
pop bx
ret
sub3:push bx
push es
push cx
mov cl,4
shl al,cl
mov bx,0b800h
mov es,bx
mov bx,1
mov cx,20000
sub3s:and byte ptr es:[bx],10001111b
or es:[bx],al
add bx,2
loop sub3s
pop cx
pop es
pop bx
ret
sub4:push ds
push es
push di
push si
push ax
push cx
push bx
mov bx,0
mov ax,0b800h
mov es,ax
mov di,0
mov ds,ax
mov si,160
cld
mov cx,24
sub4s:push cx
mov cx,160
rep movsb
pop cx
loop sub4s
ret
setend:nop
code ends
end start | | |
|
|
|
|
[第1楼]
[ 回复时间:2009-07-04 17:20 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-05-06 17:58 |
table dw sub1,sub2,sub3,sub4 载入时,sub1,sub2,sub3,sub4 转换为在程序中的偏移,但是复制安装时把这个偏移也照搬过去了,所以偏移错了。 | | |
|
|
|
|
[第2楼]
[ 回复时间:2009-07-05 00:57 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-05-06 17:58 |
table dw sub1,sub2,sub3,sub4
这样只是相对于CS:0的相对偏移
table dw sub1+200H-2eh,sub2+200H-2eh,sub3+200H-2eh,sub4 +200H-2eh
(2E是中断程序前面程序段的总长度)
因为中断程序安装在CS:200H处,所以现在的偏移要在原来的偏移的基础上加200H,再减掉
中断程序前面程序段的总长度(因为中断程序不安装这一部分)。
后面调用这个地址的代码都要+200H-2EH | | |
|
|
|
|
[第3楼]
[ 回复时间:2009-07-08 13:11 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:3
注册日期:2009-03-13 16:19 |
|
|
|
|
|
[第4楼]
[ 回复时间:2009-10-30 19:30 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:2
注册日期:2008-11-29 19:08 |
|
|
|
|
|
[第5楼]
[ 回复时间:2009-10-30 21:27 ]
[引用]
[回复]
[ top ] | |
荣誉值:188
信誉值:4
注册日期:2009-07-05 19:26 |
|
|
|
|
|
[第6楼]
[ 回复时间:2010-05-09 10:02 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-03-04 10:05 |
二楼和五楼的解释都很充分了啊。我的理解是这样的。
其实就是table dw sub1,... 会记录当下子程序的偏移地址,而当中断程序安装到00200后仍然是不变的,但偏偏table dw sub1,...正确的偏移地址应该是0:200段里面的,所以要做两项工作:1、设置sub1+200h(当然其它方法也可以);2、将中断程序提前到start之前,令偏移地址从0开始计算。
多多指教~ | | |
|