汇编编译器(masm.exe)对jmp的相关处理

1、向前转移
s:  :
    :
    :
jmp  s ( jmp  short  s、jmp  near  ptr  s、jmp  far  ptr  s )

    编译器中有一个地址计数器(AC ) ,编译器在编译程序过程中,每读到一个字节AC就加一。当编译器遇到一些伪操作的时候,也会根据具体情况使AC增加,如db、dw 等。
在向前转移时,编译器可以 在读到标号s 后记下AC 的值as在读到jmp … s 后记下AC的值aj 。编译器可以用 as – aj 算出位移量disp
此时,编译器作如下处理:
(1)如果 disp ∈[128,127 ] ,则不管汇编指令格式是:
jmp  s
jmp  short  s
jmp  near  ptr  s
jmp  far  ptr  s

中的哪一种,都将它转变为jmp  short  s 所对应的机器码。
jmp  sbort  s 所对应的机器码格式为:EB disp(占两个字节)
编译,连接以下程序,用Debug 进行反汇编查看。

assume  cs : code
code  segment
s:  jmp  s
    jmp  short  s
    jmp  near  ptr  s
    jmp  far  ptr  s
code  ends
end  s

(2) 如果disp∈[32765,32767] ,则:
对于jmp  short  s 将产生编译错误;
对于jmp  s、jmp  near  ptr  s 将产生 jmp  near  ptr  s 所对应的机器码;
jmp  near  ptr  s 所对应的机器码格式为;E9 disp (占3 个字节)
对于jmp  far  ptr  s 将产生相应的编码;
jmp  far  ptr  s 所对应的机器码格式为:EA 偏移地址 : 段地址(占5 个字节)
编译,连接以一下程序:

assume  cs : code
code  segment
s:  db 100 dup (0b8h , 0 , 0 )      ; db 100 dup (0 , 0 , 0 )
    ;jmp  short  s       ; 超过short能表示的8位范围
start:
    jmp  s
    jmp  near  ptr  s
    jmp  far  ptr  s
code  ends
end  s

编译中将产生错误,错误是由jmp  short  s 引起的,去掉jmp  short  s 后再编译就可通过。用Debug 进行反汇编查看。
PJC301fT1bDSzY6llmat0qDg1XUM82wdoS1oB6Nkbaq7kp3R+NzxXq2aL2pLTo3yLlMqea4ocXYnSK1neB8uM0iUNDDgAAAABQzF+ki1tZF4CvqwAAAABJRU5ErkJggg==


//db 100 dup (0 , 0 , 0 ) 
4HaRMgR5RqLqEAAAAASUVORK5CYII=

GIAgHSYRwEAkA+9GAAgH3oxAEA+9GIAgHzoxQAA+dCLAQDy+R9P3fbrokGoMgAAAABJRU5ErkJggg==

suraZ6A3NBAAAAAASUVORK5CYII=
//100 dup (0b8h , 0 , 0 )
qJqiOXXEf6iapzz1wAAAAAAAAAAAAAwA38D6T69uGxI7nyAAAAAElFTkSuQmCC
// 拷贝的是指令代码
+oMX6ARgIeaejQEAAAAAwOcvqknY+9oO+gEAAAAASUVORK5CYII=

0+a00Qppey9j+wgBQlbmr8yQAAAABJRU5ErkJggg==




2、向后转移
jmp  s  (jmp  short  s、jmp  near  ptr  s、jmp  far  ptr  s)
          :
          :
s:        :

    在这种情况下, 编译器先读到jmp … s 指令。由于它还没有读到标号 s ,所以此时还不能确定标号s 处的AC 值。也就是说,编译器不能确定位移量disp 的大小。此时, 编译器将 jmp … s 指令都当作jmp  short  s 来读取记下jmp … s 指令的位置和AC的值aj 并作如下处理
对于jmp  short  s ,编译器生成EB 和1 个nop 指令(相当于预留1 个字节的空间,存放8位disp );
对于jmp  s 和jmp  near  ptr  s ,编译器生成EB 和两个nop指令(相当于预留两个字节的空问,存放16 位disp ) ;
对十jmp  far  ptr  s ,编译器生成EB 和4 个nop 指令(相当于预留4 个字节的空间,存放段地址和偏移地址)。
    做完以上处理后, 编译器继续工作,当向后读到标号s 时,记下AC 的值as ,并计算出转移的位移量:disp = as – aj
此时,编译器作如下处理:
(1)当disp ∈[ –128 ,127]时,不管指令格式是:

jmp  short  s
jmp  s
jmp  near  ptr  s
jmp  far  ptr  s

中的哪一种,都在前面记下的jmp … s 指令位置处添上jmp  short  s 对应的机器码(格式为:EB disp)。
注意:此时,对于jmp  s 和jmp  near  ptr  s 格式,在机器码EB disp后还有1 条nop 指令;对于jmp  far  ptr  s 格式,在机器码 EB disp 后还有3 条nop 指令。
编译,连接以下程序,用Debug 进行反汇编查看。

assume  cs : code
code  segment
begin:        
        jmp  short  s
        jmp  s
        jmp  near  ptr  s
        jmp  far  ptr  s
s:        
        mov  ax,0
code  ends
end  begin

(2) 当disp ∈[ –32768 ,32767]时,则:
对于jmp  short  s ,将产生编译错误;
对于jmp  s 、jmp  near  ptr  s ,在前面记下的 jmp … s 指令位置处添上 jmp near ptr s 所对应的机器码(格式为:E9 disp)
对于 jmp far ptr s 在前面记下的jmp … s 指令位置处添上对应的代码。
编译,连接以下程序:

assume  cs : code
code  segment
begin:
        ;jmp  short  s       ; 超过short能表示的8位范围
        jmp  s
        jmp  near  ptr  s
        jmp  far  ptr  s
        db  100  dup  ( 0b8h , 0 , 0 )
s:  
        mov  ax,2
code  ends
end  begin


在编译中将产生错误,错误是由jmp  short  s 引起的,去掉jmp  short  s 后再编译就可通过。用Debug 进行反汇编查看。
Uap+kSP1Wqbt3fuo3fLrvXyYF5Xeys9vLPQvKV3uX1bD6v67Y5YvCDLvTvXLKjbX7556v2jsD8OjGf140OprBH7ylCU+3jlLfblbqEGV6vmvA+q5CqW+G4ov90N35RJ8B2ln9bBgAAACD7B23JEYfC2p4tAAAAAElFTkSuQmCC// EB09,09是编译到后面标号s处再从新填写disp 8Ik6AePzfkAPY1v8AP6OQ3tyLv8QAAAAASUVORK5CYII=// 目标地址的偏移都是0137,disp第一个时0134,第二个是0131;


转载于:https://www.cnblogs.com/meihao1203/p/7930956.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值