C语言的条件控制语句,在汇编里说白了就是通过对ZF零标志位进行判断,然后由跳转指令来实现逻辑分支。
1 条件语句if
int main(void)
{
int a;
if(a)
return 1;
else
return 0;
}
反汇编代码如下
080483b4 <main>:
80483b4: 55 push %ebp
80483b5: 89 e5 mov %esp,%ebp
80483b7: 83 ec 10 sub $0x10,%esp
80483ba: 83 7d fc 00 cmpl $0x0,-0x4(%ebp)
80483be: 74 07 je 80483c7<main+0x13>
80483c0: b8 01 00 00 00 mov $0x1,%eax
80483c5: eb 05 jmp 80483cc<main+0x18>
80483c7: b8 00 00 00 00 mov $0x0,%eax
80483cc: c9 leave
80483cd: c3 ret
80483ce: 90 nop
80483cf: 90 nop
代码简析:cmpl比较a值是否为0,如果状态寄存器的zero标志位为0则je到地址80483c7;如果不为0则正常退出是eax为1然后jmp跳转地址到80483cc
2 条件语句case
int main(void)
{
int a;
switch(a)
{
case 0:
return 0;
default:
return 1;
}
}
反汇编objdump
080483b4 <main>:
80483b4: 55 push %ebp
80483b5: 89 e5 mov %esp,%ebp
80483b7: 83 ec 10 sub $0x10,%esp
80483ba: 8b 45 fc mov -0x4(%ebp),%eax
80483bd: 85 c0 test %eax,%eax
80483bf: 75 07 jne 80483c8<main+0x14>
80483c1: b8 00 00 00 00 mov $0x0,%eax
80483c6: eb 05 jmp 80483cd<main+0x19>
80483c8: b8 01 00 00 00 mov $0x1,%eax
80483cd: c9 leave
80483ce: c3 ret
三个case 条件
int main(void)
{
inta=1;
switch(a)
{
case 0:
return 0;
case 1:
return -1;
default:
return 1;
}
}
反汇编objdump
080483b4 <main>:
80483b4: 55 push %ebp
80483b5: 89 e5 mov %esp,%ebp
80483b7: 83 ec 10 sub $0x10,%esp
80483ba: c7 45 fc 01 00 00 00 movl $0x1,-0x4(%ebp)
80483c1: 8b 45 fc mov -0x4(%ebp),%eax
80483c4: 85 c0 test %eax,%eax
80483c6: 74 07 je 80483cf<main+0x1b>
80483c8: 83 f8 01 cmp $0x1,%eax
80483cb: 74 09 je 80483d6<main+0x22>
80483cd: eb 0e jmp 80483dd<main+0x29>
80483cf: b8 00 00 00 00 mov $0x0,%eax
80483d4: eb 0c jmp 80483e2<main+0x2e>
80483d6: b8 ff ff ff ff mov $0xffffffff,%eax
80483db: eb 05 jmp 80483e2<main+0x2e>
80483dd: b8 01 00 00 00 mov $0x1,%eax
80483e2: c9 leave
80483e3: c3 ret
3 Case语句有无break汇编比较
有break语句
int main(void)
{
int a;
switch(a)
{
case 0:
a =1;
break;
default:
a =0;
break;
}
returna;
}
有break语句,反汇编objdump
080483b4 <main>:
80483b4: 55 push %ebp
80483b5: 89 e5 mov %esp,%ebp
80483b7: 83 ec 10 sub $0x10,%esp
80483ba: 8b 45 fc mov -0x4(%ebp),%eax
80483bd: 85 c0 test %eax,%eax
80483bf: 75 09 jne 80483ca<main+0x16>
80483c1: c7 45 fc 01 00 00 00 movl $0x1,-0x4(%ebp)
80483c8: eb 07 jmp 80483d1<main+0x1d>
80483ca: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp)
80483d1: 8b 45 fc mov -0x4(%ebp),%eax
80483d4: c9 leave
80483d5: c3 ret
无break语句
int main(void)
{
int a;
switch(a)
{
case 0:
a =1;
default:
a =0;
}
returna;
}
无break语句,反汇编objdump
080483b4 <main>:
80483b4: 55 push %ebp
80483b5: 89 e5 mov %esp,%ebp
80483b7: 83 ec 10 sub $0x10,%esp
80483ba: 8b 45 fc mov -0x4(%ebp),%eax
80483bd: 85 c0 test %eax,%eax
80483bf: 75 07 jne 80483c8<main+0x14>
80483c1: c7 45 fc 01 00 00 00 movl $0x1,-0x4(%ebp)
80483c8: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp)
80483cf: 8b 45 fc mov -0x4(%ebp),%eax
80483d2: c9 leave
80483d3: c3 ret
从上面对比可以看出缺少break的语句,汇编缺少了一条跳转到出口的语句
80483c8: eb07 jmp 80483d1<main+0x1d>