注册 登录
编程论坛 汇编论坛

王爽汇编 有一段话不能理解

toyix 发布于 2008-08-28 10:19, 2488 次点击
汇编指令        机器代码
mov cx,6       B9 06 00
mov ax,10h     B8 10 00
s:add ax,ax   01 C0
loop s          E2 FC
这段程序装在内存中的不同位置都可正确执行,因为loop s在执行时只涉及s的位移(-4,前移4个字节,补码表示为FCH),而不是s
的地址。如果loop s的机器码中包含得是s的地址,则就对程序段在内存中得偏移地址有了严格得限制,因为机器码中包含的是s的地
址,如果s处的指令不在目的地址处,程序执行就会出错。而loop s 的机器码中包含的是转移的位移,就不存在这个问题了,因为,                           
无论s处的指令的实际地址是多少,loop指令的转移位移是不变的                          我不能明白的是  “就对程序段在内存中得偏移地址有了严格得限制,因为机器码中包含的是s的地址,如果s处的指令不在目的地址处,程序执行就会出错。”这句话 假设包含的是地址 ,程序装在内存中的不同位置,地址也就会不同啊 ,为什么会找不到呢
6 回复
#2
ONEPROBLEM2008-08-28 11:37
我是这样理解的:
这个所谓的包含了地址,是指编译器在编译时,已经得到的值(编译器把它固定下来了),也可以说是直接寻址。再把它装到其它地方当然会出错了。
其实,可能LZ把每一行代码的地址 和 指令中包含的地址 给搞混了。前者会随着装载地方不同而变化,后者(如果不是寄存器寻址或相对寻址)是已经由编译器固定了的。
#3
toyix2008-08-30 00:55
谢谢了,ONEPROBLEM你说的多少我还是能理解的,段内转移是这样,但是我又有个疑问,就是如果是段间转移,他所对应的 机器码就是转移的目的地址啊 ,这个也应该是编译的时候就固定了把,这个就不是位移,难道如果一段程序里面使用了 段间转移的话 ,把着段程序放到内存的不同位置就会出错吗 ,不理解

[[it] 本帖最后由 toyix 于 2008-8-30 07:01 编辑 [/it]]
#4
ONEPROBLEM2008-08-30 22:26
[bo][un]toyix[/un] 在 2008-8-30 00:55 的发言:[/bo]

谢谢了,ONEPROBLEM你说的多少我还是能理解的,段内转移是这样,但是我又有个疑问,就是如果是段间转移,他所对应的 机器码就是转移的目的地址啊 ,这个也应该是编译的时候就固定了把,这个就不是位移,难道如果一段 ...

你说得没错!楼主的研究精神实在令我很佩服、很感动~~
追根究底的精神是一个巨大的动力啊~~~

以下我将发表个人的愚见,希望楼主有所明白:
首先,要知道在8086中,存在有段的大小 64K 的限制,即你的代码组成的一个程序最大不能超过 64K ;当然,除了代码段,你可以安排一个 64K 的栈段,和一个 64K 的数据段。但我们现在就是就代码段而言的。
有了这个认识的前提就好说了。
在你的程序中,实现的所谓段间转移,实质上还是“段”内转移!为什么?因为,你的子程序(或你要转移到的代码处)还是处于本程序内,即64K 中。你仔细观察一下“jmp far ptr 标号”这样的指令吧,这条指令是修改了CS、IP ,但CS的值还是本程序的段地址!而IP却是相对于“jmp far ptr 标号”这条指令的下一条指令的位移!

那么,就没有真正的段间转移了么?有。那就是中断,int 调用 !这才是真正的彻底修改了CS IP的值。而这个中断处理程序的地址却已经是安排好了的。它们就在中断向量表中。

所以,你问:实现段间转移的指令中包含的地址不也是固定了么?是的。情况为二:如果是“假”的段间转移(我发明的说法 ),其实本质上还是包含了位移!如果是中断式的段间转移,那么程序是通过中断号查找中断向量表而实现转移的,如int XXh 就是这样的指令。
#5
toyix2008-09-01 07:17
谢谢 又帮我解答了下 ,可以我感觉  你说的好象有问题,第一   :  jmp far ptr 标号对应 的 机器码对应的就是 目的地址  ,不是偏移。我debug看过了     第二  :你 是说  一个程序代码  段 ,数据段 ,堆栈段  都是只能是 最大为64KB吗?你说的 知识 杂在代码段中的跳转  ,cs当然不会变了 ,你看这个程序     assume cs:code,ds:data,ss:stack
data segment
    a db 8Bh,0C3h,0B8h,00h,4Ch,0CDh,21h
data ends
stack segment b
    b db 8Bh,0C3h,0B8h,00h,4Ch,0CDh,21h
stack ends
code segment
 start:mov ax,1111h
       mov bx,2222h
   
      ;jmp far ptr a
     jmp far ptr b
      
     
code ends
end start代码段   可以 跳转到数据段和堆栈段  然后执行。
#6
ONEPROBLEM2008-09-02 23:41
你说的也有道理。
#7
stop12042013-09-08 21:03
可用 shr  shl ip  来解决-.-
1