. : : Assembly Language : : .  |  首页  |  我提出的问题  |  我参与的问题  |  我的收藏  |  消息中心   |  游客  登录  | 
刷新 | 提问 | 未解决 | 已解决 | 精华区 | 搜索 |
  《汇编语言》论坛 ->INT指令
  管理员: assembly   [回复本贴] [收藏本贴] [管理本贴] [关闭窗口]
主题 : :  关于检测点13.1中7ch中断的最大转移位移的实验验证 (推荐大家都看看)  [待解决] 回复[ 8次 ]   点击[ 1025次 ]  
sleepinglion
[帖 主]   [ 发表时间: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
efan
[第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个字节没有放入代码
因此~坐等高手解释~
betterpursuel
[第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呢?这个就不明白了,望高手解释
betterpursuel
[第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
betterpursuel
[第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
vs9841
[第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。
vs9841
[第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。
ltoiii
[第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)在代码段好像不能用。就不知该怎么测试了。
ltoiii
[第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个字节。
需要登录后才能回帖 -->> 请单击此处登录
    Copyright © 2006-2024   ASMEDU.NET  All Rights Reserved