- [qiansanshi] 熟悉的ID,熟悉的事,祝朋友们学习工作愉快 11/04 19:22
- [mywiil] 这里曾经给我们带来了那么多回忆,却不曾想,慢慢的被我们遗忘。 没事的时候,回来看看吧,这里有我 08/31 09:41
- [rotapple] 知道了,这是书后面的实验章节。我还没看到那边 08/29 16:14
- [rotapple] 这是什么书? 08/29 14:54
- [tomato] 怎么都这么伤感! 08/29 09:12
- [tomato] 怎么都这么伤寒! 08/29 09:12
- [rotapple] 感觉只要理解了跳转的过程及ip修改的方式。就不难理解了。 08/16 15:00
- [游客] add al,80h CF=1;OF=1;SF=0;ZF=1;PF=1 你 07/13 16:47
- [游客] 谢谢 很有用 06/23 18:06
- [游客] 你向下跳转的例子显然不符合题意,用7ch向下跳转那就相当与jmp指令的效果了(没有循环),要知道lo 03/26 20:51
- [sgiceleo] 谢谢一直关注我的作业 ,虽说有很多很多不懂的 ,但是看到那么多编程前辈们的鼓励 ,我有信心继续努力! 02/15 10:02
- [oldmtn] 我好久没上了,看到了你的留言. 讨教你一下,你想过深入学习汇编没有,现在搞汇编人很少啊 大多数人 09/28 14:36
- [ym3823078] 来 看看,呵呵 07/22 00:31
- [netbox] 请教一个问题:8根数据总线一次可以传送一个8位二进制数据(即一个字节)。 不是一个数字占一个字 06/23 19:57
- [netbox] 呵呵,感谢你~~光临我的博客!多多指导,。。加油! 06/23 19:50
- [游客] 说汇编难学,我不信。别人说的不算,我得试验一下。 ----------------- 说的好! 03/07 19:38
[2008-10-22 16:46] 检测点13.1(1)转移最大位移求解
首先这里说的是模拟loop指令的功能,这里的“模拟”应该理解为和loop指令的表现形式上是一致的,但是有一定区别,然后我们再来看这个问题。
对这道题基本有四种看法:
第一种人认为:既然是模拟loop指令的功能,那么就应该是和loop指令功能一模一样,既然loop指令的最大转移位移为[-128~127],很容易就 得出int 7ch的最大位移也是一样,即-[128~127]。如果这样想,那这个问题出的就没有多大的意义。
第二种人认为:这里存放跳转范围的寄存器是16位(BX),并且因为转移有向前转移和向后转移,根据以往jmp near ptr 等近转移指令的经验,这里的变化范围应该在[-32768~32767]之间。
第三种人认为:这与以前学习的跳转指令没有太大关系,要想得到具体范围得看具体实现。由于BX的最大值为65535,所以7ch所能进行的最大转移位移为65535。
前三种人大部分都是通过想象得出的结论,然而还有些人根据试验结果得出了更深一层的结论。
我刚做这道题时,很随意的就认为答案应该是FFFFH,但是又感觉没有什么理论依据,于是打开别人的博客,才发现了这五花八门的结果。很多人都对自己的答案不太自信。发现有个人的答案是[-32768~32767],忽然感觉我的答案好像错了(因为后面的评论有人说答案是正确的),但是我始终感觉BX能够表示比32767更大的数,因此转移位移应该比它要大,于是开始试验,由于向上跳转理解起来有困难(总要和有符号数联系起来,可能是个人问题),就写了个简单的向下跳转的例子。
assume cs:code
code segment
start:
mov bx,offset se - offset s
mov cx,3
int 7ch
s:
db 0ffe0H dup(0);
se:
nop
code ends
end start
结果能够正确执行,说明转移位移能够超过32767,所以[-32768~32767]的结果是错误的,于是又写了一个向上跳转的例子,跳转同样正常。
程序如下:
assume cs:code
code segment
start: mov bx,offset s - offset se
mov cx,3
s:
db 0ffe0H dup(0);
int 7ch
se:
nop
code ends
end start
很多人做题这道题时,都受到了以前所学转移指令的影响,没有认真分析7CH的执行过程,段转移和近转移都是根据位移进行计算的,而7CH中实现就是直接修改IP地址,我看了书的附注3,介绍了编译器对jmp指令的处理方法,实际上它是对向上向下转移的最大位移作了限制(实现方法不一样)。
在这里我们假设所进行的都是无符号数运算,可以知道offset s - offset se应该小于0,但实际结果是进行了借位,而使结果与真实结果不符。相当于offset s最高位再加一位变为1, 而offset se最高位也加一位变为0,然后相减得到的值。
当程序执行int 7ch后,此时栈中存放的原ip地址为offset se,而中断程序执行时又会在原有ip地址的基础上加上转移位移即(offset s - offset se),那么最终的值为offset se + (offset s - offset se) = offset s。仍然是原来程序中标号s处,所以能正确返回。而实际的位移就是|offset s - offset se|(绝对值),即offset se - offset s。那么这个绝对值最大为多少呢?按上面的程序所写最大值就是64K(65536)-1(nop指令)-6(前两条指令所占空间)=65529;
所以我的答案是:FFF9H(65529),个人感觉只要能够理解到趋紧于FFFFH(65535)就可以了。在这里,向上跳转感觉理解起来非常费劲,总想跟有符号数运算联系在一起,结果是越想越乱,后来想到上述方法来解释,感觉很好理解,不知有没有漏洞。
看了abcrazy的分析,我发现我的结论有点问题,最大位移应该是FFFFH,程序如下:
assume cs:code
code segment
start:
mov bx,offset start - offset s
db 65530 dup(0)
int 7ch
s:nop
code ends
end start
如果
assume cs:code
code segment
start:
mov bx,offset start - offset s
db 65531 dup(0)
int 7ch
s:
code ends
end start
那么s标号的偏移就为0了。
[ fairyhuang 发表于 2008-10-24 21:46 ]
研究的真深啊,佩服:)
[ lwbfq 发表于 2008-10-25 11:18 ]
不知道哪个答案是对的,只有自己试着摸索了 呵呵
[ 游客 发表于 2009-05-11 22:19 ]
我想过了,还是bx表示的数值范围,因为两个标号都同在一个代码段中,也就是两个数64k范围内做减法运算,因为bx中的值是正值还是负数,可以有我们说了算,但总之还是16比特数;举个例子说明吧,从0-9之间任意选两个值做差运算,你说得到的范围是多少呢?我觉得这题就是这个意思。明白这点就好了!
[ 游客 发表于 2010-12-26 14:42 ]
"按上面的程序所写最大值就是64K(65536)-1(nop指令)-6(前两条指令所占空间)=65529; "楼主这里我觉得有点问题。如果像这样分析,我觉得就不用减nop指令跟前两条指令所占的空间了。除此之外,我觉得向上或者向下跳转的最大位移应该还跟执行int指令时IP入栈得值。反正向上向下能转移的最大位移加起来就是65535.一己之见,还望指正。
[ 游客 发表于 2011-03-26 20:51 ]
你向下跳转的例子显然不符合题意,用7ch向下跳转那就相当与jmp指令的效果了(没有循环),要知道loop指令中loop一定要在标号s的后面!.
如果这个题意义在于说7ch能实现的最大位移,那答案当然是bx能保存的最大值65535,但实际应用7ch去转移时,那就要考虑向上跳和向下跳(向下跳不会循环的哦!),这时由于考虑了向上和向下那偏移范围在[-32768~32767],答案就是32768;
如果题目意思说,用7ch实现loop指令的话,就没必要讨论向下跳,它只能是向上偏移,偏移量必为负数,答案为32768
loop指令只能短转转移,处理方式仍是偏移,
[ rotapple 发表于 2011-08-16 15:00 ]
感觉只要理解了跳转的过程及ip修改的方式。就不难理解了。