32位汇编语言学习笔记(7)--跳转指令



正常情况下,指令是按照顺序执行的,跳转指令会导致程序的执行切换到一个新位置。

jmp跳转指令是无条件跳转指令。

可以是直接跳转,即跳转指令的目的地址通常由标号指明。也可以是间接跳转:

jmp *%eax //eax值作为跳转目的地址。

jmp *(%eax) //eax指向的内存中保存的地址值作为跳转目的地址。

 

有条件跳转指令如下:

je Label //相等跳转

jz Label //je相同

jne Label //不相等跳转

jnz Label //jne相同

js Label //负数跳转

jns Label //非负数跳转

jg Label //有符号大于跳转

jnle Label //jg相同

jge Label //有符号大于等于跳转

jnl //jge相同

jl Label //有符号小于跳转

jnge Label //jl相同

jle Label //有符号小于等于跳转

jng Label //jle相同

ja Label //无符号大于跳转

jnbe Label //ja相同

jae Label //无符号大于等于跳转

jnb //jae相同

jb Label //无符号小于跳转

jnae Label //jb相同

jbe Label //无符号小于等于跳转

jna Label //jbe相同

 

示例:

int absdiff(int x, int y)

{

   if (x < y)

         returny - x;

   else

         returnx - y;

}

 

gcc -O1 -S -m32 abs_diff1.c

absdiff:

       pushl   %ebp

       movl    %esp, %ebp

       movl    8(%ebp), %edx //edx = x

       movl    12(%ebp), %eax //eax = y

       cmpl    %eax, %edx //比较xy

       jge     .L2 //x >=y,跳转到L2

       subl    %edx, %eax //eax = y -x

       jmp     .L4 //跳转到L4

.L2:

       subl    %eax, %edx //edx = x -y

       movl    %edx, %eax //eax = edx =x-y

.L4:

       popl    %ebp

       ret

 

gcc -O1 -m32 -c abs_diff1.c

objdump -d abs_diff1.o

 

abs_diff1.o:     file format elf32-i386

 

Disassembly of section .text:

 

00000000 <absdiff>:

  0:   55                      push   %ebp

  1:   89 e5                   mov    %esp,%ebp

  3:   8b 55 08                mov    0x8(%ebp),%edx

  6:   8b 45 0c                mov    0xc(%ebp),%eax

  9:   39 c2                   cmp    %eax,%edx

  b:   7d 04                   jge    11 <absdiff+0x11>

  d:   29 d0                   sub    %edx,%eax

  f:   eb 04                   jmp    15 <absdiff+0x15>

 11:   29 c2                   sub    %eax,%edx

 13:   89 d0                   mov    %edx,%eax

 15:   5d                      pop    %ebp

 16:   c3                      ret   

内容基本相同,只是跳转的标号变成了相对地址:

b:  7d 0404就是相对地址偏移,表示跳转到本条指令的下一条指令的地址加上这个偏移(0xd+0x4=0x11)。

f:  eb 04,同理,表示跳转到(0x11+0x4=0x15)

 

int gotodiff(int x, int y)

{

   int rval;

 

   if (x < y)

         gotoless;

   rval = x - y;

   goto done;

 less:

   rval = y - x;

 done:

   return rval;

}

gcc -O1 -S -m32 abs_diff_goto.c

gotodiff:

       pushl   %ebp

       movl    %esp, %ebp

       movl    8(%ebp), %edx//edx = x

       movl    12(%ebp), %eax //eax = y

       cmpl    %eax, %edx //比较xy

       jl      .L2 //x<y跳转到L2

       subl    %eax, %edx //edx = x - y

       movl    %edx, %eax //eax = edx =x-y

       jmp     .L4 //跳转到L4

.L2:

       subl    %edx, %eax //eax = y - x

.L4:

        popl   %ebp

       ret

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值