|
主题 : : 关于检测点13.1中7ch中断的最大转移位移的实验验证 (推荐大家都看看) [待解决] |
回复[ 8次 ]
点击[ 1025次 ] | |
|
|
|
|
[帖 主]
[ 发表时间:2010-08-08 00:12 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2010-07-13 23:22 |
经过本人实验验证,我认为:应该是65536. 程序可以正常运行
不知是否正确,还请大家帮忙批评指正。不胜感激!
而且经过我多番修改dup 65424 dup(0)中的65242的值,发现65242是上限,超过这个数就会出现“25.ASM(50): warning A4102: Segment near (or at) 64K limit”的错误,即已经超过了段的最大长度了,可明明从0BB7:FFDC到0BB7:FFFF都是被0填充的,应该还能存放代码的啊,为什么不能再大于65424了呢?我百思不得其解,希望大家也能思考一下。谢谢!
验证代码如下:
assume cs:code
code segment
start:
mov ax,cs
mov ds,ax
mov si,offset lp
mov ax,0
mov es,ax
mov di,200h
mov cx,offset lpend-offset lp
cld
rep movsb ;安装中断程序
mov word ptr es:[7ch*4],200h
mov word ptr es:[7ch*4+2],0 ;设置中断向量表
mov ax,0b800h
mov es,ax
mov di,160*12
mov bx,offset s-offset se
mov cx,80
s:
db 65424 dup(0)
mov byte ptr es:[di],'!'
add di,2
int 7ch
se: nop
mov ax,4c00h
int 21h
;以下为中断程序
lp:
push bp
mov bp,sp
dec cx
jcxz lpret
add [bp+2],bx
lpret:
pop bp
iret
lpend:
nop
code ends
end start
debug结果如下:
(1)
C:\>debug 25.exe
-u
0BB7:0000 8CC8 MOV AX,CS
0BB7:0002 8ED8 MOV DS,AX
0BB7:0004 BED0FF MOV SI,FFD0
0BB7:0007 B80000 MOV AX,0000
0BB7:000A 8EC0 MOV ES,AX
0BB7:000C BF0002 MOV DI,0200
0BB7:000F B90B00 MOV CX,000B
0BB7:0012 FC CLD
0BB7:0013 F3 REPZ
0BB7:0014 A4 MOVSB
0BB7:0015 26 ES:
0BB7:0016 C706F0010002 MOV WORD PTR [01F0],0200
0BB7:001C 26 ES:
0BB7:001D C706F2010000 MOV WORD PTR [01F2],0000
-u
0BB7:0023 B800B8 MOV AX,B800
0BB7:0026 8EC0 MOV ES,AX
0BB7:0028 BF8007 MOV DI,0780
0BB7:002B BB6700 MOV BX,0067
0BB7:002E B95000 MOV CX,0050
0BB7:0031 0000 ADD [BX+SI],AL
0BB7:0033 0000 ADD [BX+SI],AL
0BB7:0035 0000 ADD [BX+SI],AL
0BB7:0037 0000 ADD [BX+SI],AL
0BB7:0039 0000 ADD [BX+SI],AL
0BB7:003B 0000 ADD [BX+SI],AL
0BB7:003D 0000 ADD [BX+SI],AL
0BB7:003F 0000 ADD [BX+SI],AL
0BB7:0041 0000 ADD [BX+SI],AL
(2)
0BB7:0041 0000 ADD [BX+SI],AL
-u ffb0
0BB7:FFB0 0000 ADD [BX+SI],AL
0BB7:FFB2 0000 ADD [BX+SI],AL
0BB7:FFB4 0000 ADD [BX+SI],AL
0BB7:FFB6 0000 ADD [BX+SI],AL
0BB7:FFB8 0000 ADD [BX+SI],AL
0BB7:FFBA 0000 ADD [BX+SI],AL
0BB7:FFBC 0000 ADD [BX+SI],AL
0BB7:FFBE 0000 ADD [BX+SI],AL
0BB7:FFC0 0026C605 ADD [05C6],AH
0BB7:FFC4 2183C702 AND [BP+DI+02C7],AX
0BB7:FFC8 CD7C INT 7C
0BB7:FFCA 90 NOP
0BB7:FFCB B8004C MOV AX,4C00
0BB7:FFCE CD21 INT 21
-u
0BB7:FFD0 55 PUSH BP
0BB7:FFD1 8BEC MOV BP,SP
0BB7:FFD3 49 DEC CX
0BB7:FFD4 E303 JCXZ FFD9
0BB7:FFD6 015E02 ADD [BP+02],BX
0BB7:FFD9 5D POP BP
0BB7:FFDA CF IRET
0BB7:FFDB 90 NOP
0BB7:FFDC 0000 ADD [BX+SI],AL
0BB7:FFDE 0000 ADD [BX+SI],AL
0BB7:FFE0 0000 ADD [BX+SI],AL
0BB7:FFE2 0000 ADD [BX+SI],AL
0BB7:FFE4 0000 ADD [BX+SI],AL
0BB7:FFE6 0000 ADD [BX+SI],AL
0BB7:FFE8 0000 ADD [BX+SI],AL
0BB7:FFEA 0000 ADD [BX+SI],AL
0BB7:FFEC 0000 ADD [BX+SI],AL
0BB7:FFEE 0000 ADD [BX+SI],AL | | |
|
|
|
|
[第1楼]
[ 回复时间:2011-05-18 13:15 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-04-28 10:55 |
楼主所说的问题我也发现了(不过楼主的帖子内容没说清楚,一会65424一会65242)
我写了一个简单的验证程序
assume cs:code
code segment
start:
db 65495 dup(0)
mov ax,4c00h
int 21h
code ends
end start
发现65495是能编译通过的最大值
然后debug发现
0EE2:FFD0 0000 ADD [BX+SI],AL
0EE2:FFD2 0000 ADD [BX+SI],AL
0EE2:FFD4 0000 ADD [BX+SI],AL
0EE2:FFE6 00B80100 ADD [BX+SI+4C00],AH
0EE2:FFDA CD21 INT 21
0EE2:FFDC 0000 ADD [BX+SI],AL
0EE2:FFDE 0000 ADD [BX+SI],AL
0EE2:FFE0 0000 ADD [BX+SI],AL
同样是FFDC之后的全是0
也就是说程序保证FFDC后面的40个字节没有放入代码
因此~坐等高手解释~ | | |
|
|
|
|
[第2楼]
[ 回复时间:2011-05-29 15:34 ]
[引用]
[回复]
[ top ] | |
荣誉值:8
信誉值:0
注册日期:2010-11-07 17:01 |
楼主和一楼的答案其实是一样的,那就是65500,也就是一个code段的最大长度;为什么说你们是一样的呢?
code segment.......code ends的所有程序都算上,那就是楼主的65424+76=65500;一楼的code段中的程序长度为65495+5=65500(因为 mov ax,4c00h ,int 21h这两句一共占有5个字节 );其实还有另一种方法可以知道代码段程序的长度,那就是进入debug后,看看cx的值,便可知到了;楼主和一楼的cx值都是FFDCH既65500,
理论上code段的最大长度应该为65536,可是实际确实65500呢?这个就不明白了,望高手解释 | | |
|
|
|
|
[第3楼]
[ 回复时间:2011-05-29 15:51 ]
[引用]
[回复]
[ top ] | |
荣誉值:8
信誉值:0
注册日期:2010-11-07 17:01 |
把楼主的安装int 7ch和调用int 7ch的程序分开执行,楼主先把你的loop安装程序安装好,然后再执行下面的程序,可以db 65471 dup(0) 设置这么大空间,总之,整个程序段的大小仍是65500,
assume cs:code
code segment
start:
mov ax,0b800h
mov es,ax
mov di,160*12
mov bx,offset s-offset se
mov cx,80
s:
;在debug中最大是65455,在65456时就不能执行了,但是在65424时无警告,在65425时有警告的; 在dos中65424能执行打了就不行了;
db 65471 dup(0) ; db 65471 dup(0)
mov byte ptr es:[di],'!'
add di,2
int 7ch ;相当于进行loop
se: nop
mov ax,4c00h
int 21h
code ends
end start | | |
|
|
|
|
[第4楼]
[ 回复时间:2011-05-29 15:52 ]
[引用]
[回复]
[ top ] | |
荣誉值:8
信誉值:0
注册日期:2010-11-07 17:01 |
把楼主的安装int 7ch和调用int 7ch的程序分开执行,楼主先把你的loop安装程序安装好,然后再执行下面的程序,可以db 65471 dup(0) 设置这么大空间,总之,整个程序段的大小仍是65500,
assume cs:code
code segment
start:
mov ax,0b800h
mov es,ax
mov di,160*12
mov bx,offset s-offset se
mov cx,80
s:
db 65471 dup(0) ; db 65471 dup(0)
mov byte ptr es:[di],'!'
add di,2
int 7ch ;相当于进行loop
se: nop
mov ax,4c00h
int 21h
code ends
end start | | |
|
|
|
|
[第5楼]
[ 回复时间:2011-07-31 14:36 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-01-17 12:29 |
这一题中int 7ch使用加减法的方式来实现loop的方式的。用标号s处的地址减去int 7ch 下一条指令的地址se然后在加上se的地址方法,来回到s地址的。如下面的公式所示:
s-se+se=s
那么据此式就可以推算只要总的程序占用在64KB(0-FFFF)以内,应该都可以正常找到的。
因为8086约定段最大为64KB。 | | |
|
|
|
|
[第6楼]
[ 回复时间:2011-07-31 14:36 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2009-01-17 12:29 |
这一题中int 7ch使用加减法的方式来实现loop的方式的。用标号s处的地址减去int 7ch 下一条指令的地址se然后在加上se的地址方法,来回到s地址的。如下面的公式所示:
s-se+se=s
那么据此式就可以推算只要总的程序占用在64KB(0-FFFF)以内,应该都可以正常找到的。
因为8086约定段最大为64KB。 | | |
|
|
|
|
[第7楼]
[ 回复时间:2012-12-10 16:32 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2008-04-23 14:04 |
转移位移受2个因素限制:代码段大小,bx数据长度。取2者小的那个。
代码段大小上面讨论过了。
这里讨论bx数据长度:
mov bx,offset s - offset se
这里s<se,所以理论上bx取负,有符号数有一位用于符号位,数值范围是:-32768~-?(取决于s和se标号之间语句长度),则最大转移位移取绝对值32768(真实值要比32768还小因为s和se标号之间语句长度是大于0的,无论如何它要比65500这个数小近一半)。
所以,如果要针对检测点13.1进行实验验证,不能简单的加个数据段,而要在s和se标号之间加入代码,看代码长度到达多少时出现异常。但db xxx dup(0)在代码段好像不能用。就不知该怎么测试了。 | | |
|
|
|
|
[第8楼]
[ 回复时间:2012-12-10 16:56 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2008-04-23 14:04 |
。。。
mov bx,offset s-offset se
mov cx,80
s:
db 65424 dup(0)
mov byte ptr es:[di],'!'
add di,2
int 7ch
se: nop
按照LZ的代码,我用emu8086,跟踪看了一下,无论db XXX dup(0)这里XXX取多少(甚至把这句删除),都不会影响bx的值(都是FFF7),它是二进制的1111 1111 1111 0111,按补码转原码后:为1001即为9,也即s和se标号之间语句长度是9.分别为:
mov byte ptr es:[di],'!' ;1-4
add di,2 ;5-7
int 7ch ;8-9
共9个字节。 | | |
|