正常情况下,指令是按照顺序执行的,跳转指令会导致程序的执行切换到一个新位置。
 
 
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 //比较x和y
 
 
       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 04,04就是相对地址偏移,表示跳转到本条指令的下一条指令的地址加上这个偏移(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 //比较x和y
 
 
       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