. : : Assembly Language : : .  |  首页  |  我提出的问题  |  我参与的问题  |  我的收藏  |  消息中心   |  游客  登录  | 
刷新 | 提问 | 未解决 | 已解决 | 精华区 | 搜索 |
  《汇编语言》论坛 ->INT指令
  管理员: assembly   [回复本贴] [收藏本贴] [管理本贴] [关闭窗口]
主题 : :  检测点13.1  loop例程的最大转移应该是 -32768~32767吧  [待解决] 回复[ 18次 ]   点击[ 1394次 ]  
lxjjoinly
[帖 主]   [ 发表时间:2007-11-08 15:21 ]   [引用]   [回复]   [ top ] 
荣誉值:5
信誉值:3
注册日期:2007-11-05 21:15
assume cs:code
code segment
start: mov ax,code
  mov ds,ax
  mov si,offset lp
  mov ax,0
  mov es,ax
  mov di,200h
  mov cx,offset lpe-offset lp
  cld
  rep movsb
  mov ax,0
  mov es,ax
  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 se-offset s
  mov cx,80
s: mov byte ptr es:[di],'!'
  db 1280 dup (0)         ; 中间分配些单元
  add di,2
  int 7ch
se: nop
  mov ax,4c00h
  int 21h

lp: push bp
  mov bp,sp
  dec cx
  jcxz lpok
  sub [bp+2],bx
lpok: pop bp
  iret
lpe: nop
code ends
end start
以上的一样可以运行,说明可以大于 -128~127
等下去试下不知道可不可以大于16位数据
lxjjoinly
[第1楼]   [ 回复时间:2007-11-08 17:52 ]   [引用]   [回复]   [ top ] 
荣誉值:5
信誉值:3
注册日期:2007-11-05 21:15
没去试,虽然可以加个标号中间多放些数据让他大于16位,但是 IP 是放不下的,我刚学没几天,所以不知道
是不是WIN32的可不可以放32位的,不知道有没有扩展的 ‘EIP’ ?如果有的话应该可以循环32位吧!!呵呵
fishboy
[第2楼]   [ 回复时间:2007-11-08 18:07 ]   [引用]   [回复]   [ top ] 
荣誉值:283
信誉值:0
注册日期:2007-06-26 11:42
你的程序不能说明问题吧!楼主开玩笑了。呵呵。
loop指令执行相当于:
cx--;
if(cx!=0)jmp short 标号。所以,它是短转移,对ip的修改范围为 -128~127 。
楼主是在利用iret修改cs,ip的过程去模拟了一个类似loop的功能。而ip是16位的寄存器,他的存储范围是0~FFFFH,所以,无论你怎修改ip的值,他都会指向一个物理地址CS:IP,这跟楼主想要说的变动的位移好像没什么关系。楼主说的最大转移应该是 -32768~32767是根据指跳转命令的跳转思想的来的,但是,这跟修改ip的值是两个概念,比如说,现在我的ip就是0,我想通过iret来改变IP的值,我可以将IP改成FFFFH啊,那你说他跳转的位移是多少啊?!iret对ip的修改就是直接赋值,不是想jmp那样的根据位移来计算的。
lxjjoinly
[第3楼]   [ 回复时间:2007-11-09 08:23 ]   [引用]   [回复]   [ top ] 
荣誉值:5
信誉值:3
注册日期:2007-11-05 21:15
呵呵,楼上的没看清标题,loop指令当然是短转移。
我说的是王老师书里检测点13.1第1题:
(1)用上面的内容中,我们用7ch中断例程实现loop的功能,则上面的7ch中断例程所能进行的最大转移位移是多少?
我在有个地方看到说是-128~127的短转移。呵呵
iceviewer
[第4楼]   [ 回复时间:2007-11-09 09:23 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:6
注册日期:2007-10-11 10:24
我想是因为对题目的不同理解造成的,就看你怎么理解题意了。
如果说楼上的例题,仅仅是针对这道题来说应该是-32768~32767,
但是因为它提到了实现loop 的功能,那么考虑到为了和loop保持一致,也就是短转移-128~127。
fishboy
[第5楼]   [ 回复时间:2007-11-09 18:48 ]   [引用]   [回复]   [ top ] 
荣誉值:283
信誉值:0
注册日期:2007-06-26 11:42
楼主没有看清我的回答吧。我只是提了一下loop,可从第四行开始我可说的不是loop了。如果顺着楼主和楼上的意思,是ip保证在0~FFFFH范围内的只是-32768~32767这个范围的数么?楼上和楼主再想想吧。
iret对ip的修改是pop ip ,其实相当于 mov ip,ss:[sp],这本来就没有什么跳转位移一说。这根jmp等基于位移的跳转指令对ip的修改方式就是两码事。
lxjjoinly
[第6楼]   [ 回复时间:2007-11-10 08:33 ]   [引用]   [回复]   [ top ] 
荣誉值:5
信誉值:3
注册日期:2007-11-05 21:15
知道了,想了下,IP是不可能为负的。呵呵
fishboy大哥,以后多多指教我们啊。进来我们再聊聊。。。
你上面的我很多还不明白啊,我学汇编才一个星期啊,可能是我理解能力差了点。哈哈哈
我想我上面的只是用另一种方式模拟了 loop,而不应该是等同于loop指令吧
你可以去试下用loop指令从s标号到loop语句中间填些东西让它超过128个字节,那肯定就报错,不能运行的。
但是用上面的方式,你在s标号到实现转移回s 标号中间放些垃圾进去让它超过128个字节还是可以运行啊。。。
那用这个方式实现的循环就不应该还算短循环吧!!!!!!!!!
pankkk2002
[第7楼]   [ 回复时间:2008-02-03 15:59 ]   [引用]   [回复]   [ top ] 
荣誉值:2
信誉值:3
注册日期:2008-01-24 09:40
65535?
若栈中保存的ip为0,而bx=65535,那最大的转移位移就是65535?
yunhai13
[第8楼]   [ 回复时间:2008-04-11 15:00 ]   [引用]   [回复]   [ top ] 
荣誉值:2
信誉值:20
注册日期:2008-02-27 16:26
IP占一个字
所以可以位移2^16,也就是0~65535
limitasm
[第9楼]   [ 回复时间:2008-05-30 16:07 ]   [引用]   [回复]   [ top ] 
荣誉值:9
信誉值:0
注册日期:2008-04-12 14:46
loop 指令转移的范围是-128~127,而书上这个模拟loop的例题的最大位移应该是-32768~32767,个人理解,不对的地方请指教
vizwind
[第10楼]   [ 回复时间:2008-10-16 16:25 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2008-09-15 15:58
-128 - 127说的是loop指令跳转范围,那个模拟的中断例程确实可以跳转-32768 - 32767
lwbfq
[第11楼]   [ 回复时间:2008-10-22 16:22 ]   [引用]   [回复]   [ top ] 
荣誉值:56
信誉值:0
注册日期:2008-01-19 13:58
首先这里说的是模拟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指令的处理方法,实际上它是对向上向下转移的最大位移作了限制(实现方法不一样)。
我的结果:FFF9H(65529)。
个人感觉只要能够理解到趋紧于FFFFH(65535)就可以了。
在这里我们假设所进行的都是无符号数运算,可以知道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;
kelithb
[第12楼]   [ 回复时间:2009-01-20 10:48 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2008-12-12 15:19
(1)
答:所能进行的最大转移位移是128[指向前转移]。因为是实现loop的功能,那就应当遵守loop的使用规则。
<注:关于loop指令的详细介绍请查看书中第172页9.8节的内容。>
zcouyangpeng
[第13楼]   [ 回复时间:2009-02-09 11:05 ]   [引用]   [回复]   [ top ] 
荣誉值:35
信誉值:44
注册日期:2008-09-03 21:36
最大位移超过[-32768,32767],程序不能正确显示字符
aten
[第14楼]   [ 回复时间:2009-04-10 17:16 ]   [引用]   [回复]   [ top ] 
荣誉值:4
信誉值:0
注册日期:2008-12-11 08:43
这帖怎么这么久没人顶呢?都快一年了!
我看了下,很受益呐
我觉得要理解最大位移还是从过程中理解的好,明白原理一切就清楚了!
11楼说:结果能够正确执行,说明转移位移能够超过32767,所以[-32768~32767]的结果是错误的。
我认为不是错误的,[-32768~32767],是用补码表示的。
tangqc13
[第15楼]   [ 回复时间:2009-07-25 22:51 ]   [引用]   [回复]   [ top ] 
荣誉值:2
信誉值:0
注册日期:2009-06-24 14:37
loop指令执行相当于:
cx--;
if(cx!=0)jmp short 标号。所以,它是短转移,对ip的修改范围为 -128~127 。
楼主是在利用iret修改cs,ip的过程去模拟了一个类似loop的功能。而ip是16位的寄存器,他的存储范围是0~FFFFH,所以,无论你怎修改ip的值,他都会指向一个物理地址CS:IP,这跟楼主想要说的变动的位移好像没什么关系。楼主说的最大转移应该是 -32768~32767是根据指跳转命令的跳转思想的来的,但是,这跟修改ip的值是两个概念,比如说,现在我的ip就是0,我想通过iret来改变IP的值,我可以将IP改成FFFFH啊,那你说他跳转的位移是多少啊?!iret对ip的修改就是直接赋值,不是想jmp那样的根据位移来计算的。
------------------
回复:个人觉得上述解释已经把问题说得很清楚了。利用iret修改cs,ip的过程模拟类似loop的功能,和变动的位移没有关系,iret来改变ip的值只是一个直接赋值的过程。
361283028
[第16楼]   [ 回复时间:2010-01-12 00:52 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2010-01-05 19:25
我的理解是,既然它是一个位移,必有正向和反向,因此要用有符号数来表示这个范围。bx是一个十六位的寄存器,那么这个范围就是[-32768~32767].
vs9841
[第17楼]   [ 回复时间:2011-08-01 10:31 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-01-17 12:29
怎么说的那么复杂,其实这个程序是标号s减去int 7ch下一条指令地址se然后在加se得到的s,如下式所示:
s=s-se+se
所以说,这个程序,只要在8086约定的64K(0-ffff)以内,s-se的位移量+其它指令的空间<=64K。
zjkl19
[第18楼]   [ 回复时间:2014-01-24 11:53 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:6
注册日期:2009-07-15 11:17
回复:[第14楼]
------------------
I can't agree more.关键性的问题就是数值使用补码表示的,我觉得11楼概念没搞清楚。
需要登录后才能回帖 -->> 请单击此处登录
    Copyright © 2006-2024   ASMEDU.NET  All Rights Reserved