#include
void f(int a)
{
switch(a) {
case 0: printf("zero\n");
break;
case 1: printf("one\n");
break;
case 2: printf("two\n");
break;
default: printf("something unknown\n");
break;
}
}
int main()
{
f(2);
}
#if 0
如果仅从汇编代码入手,无法判断上述函数是一个判断表达式较少的switch()语句、还是一组if语句。
确实可以认为,switch()语句是一种旨在简化大量嵌套if()语句设计的语法。
mov eax, [esp-4]
sub exa, 0
这两条指令可以检查EAX的值是否是零。如果EAX的值是零,ZF会被置1(也就是说0-0=1,这就可以提前设置ZF标志位),并会触发第一条条件转移
指令JE。如果EAX的值仍然不是零,则不会触发第一条转移指令。
做"eax=eax-1"的运算,若计算结果是零则做相应输出。
在把字符串指针存储到变量a之后,函数使用JMP调用printf。在调用printf函数的时候,调用方函数而没有使用常规的call指令。
这点不难释:调用方函数把参数推送入栈之后,的确通常通过CALL指令调用其他函数。这种情况下,CALL会把返回地址推送入栈、并通过
无条件转移的手段启用被调用方函数。
#endif
#if 0
/*
* intel
*/
0000000000001149 :
1149: f3 0f 1e fa endbr64
114d: 55 push %rbp
114e: 48 89 e5 mov %rsp,%rbp
1151: 48 83 ec 10 sub $0x10,%rsp
1155: 89 7d fc mov %edi,-0x4(%rbp)
1158: 83 7d fc 02 cmpl $0x2,-0x4(%rbp)
115c: 74 30 je 118e
115e: 83 7d fc 02 cmpl $0x2,-0x4(%rbp)
1162: 7f 38 jg 119c
1164: 83 7d fc 00 cmpl $0x0,-0x4(%rbp)
1168: 74 08 je 1172
116a: 83 7d fc 01 cmpl $0x1,-0x4(%rbp)
116e: 74 10 je 1180
1170: eb 2a jmp 119c
1172: 48 8d 3d 8b 0e 00 00 lea 0xe8b(%rip),%rdi # 2004 <_IO_stdin_used+0x4>
1179: e8 d2 fe ff ff callq 1050
117e: eb 29 jmp 11a9
1180: 48 8d 3d 82 0e 00 00 lea 0xe82(%rip),%rdi # 2009 <_IO_stdin_used+0x9>
1187: e8 c4 fe ff ff callq 1050
118c: eb 1b jmp 11a9
118e: 48 8d 3d 78 0e 00 00 lea 0xe78(%rip),%rdi # 200d <_IO_stdin_used+0xd>
1195: e8 b6 fe ff ff callq 1050
119a: eb 0d jmp 11a9
119c: 48 8d 3d 6e 0e 00 00 lea 0xe6e(%rip),%rdi # 2011 <_IO_stdin_used+0x11>
11a3: e8 a8 fe ff ff callq 1050
11a8: 90 nop
11a9: 90 nop
11aa: c9 leaveq
11ab: c3 retq
00000000000011ac :
11ac: f3 0f 1e fa endbr64
11b0: 55 push %rbp
11b1: 48 89 e5 mov %rsp,%rbp
11b4: bf 02 00 00 00 mov $0x2,%edi
11b9: e8 8b ff ff ff callq 1149
11be: b8 00 00 00 00 mov $0x0,%eax
11c3: 5d pop %rbp
11c4: c3 retq
11c5: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
11cc: 00 00 00
11cf: 90 nop
/*
* arm
*/
000000000040055c :
40055c: a9be7bfd stp x29, x30, [sp, #-32]!
400560: 910003fd mov x29, sp
400564: b9001fa0 str w0, [x29, #28]
400568: b9401fa0 ldr w0, [x29, #28]
40056c: 7100041f cmp w0, #0x1
400570: 54000120 b.eq 400594 // b.none
400574: 7100081f cmp w0, #0x2
400578: 54000160 b.eq 4005a4 // b.none
40057c: 7100001f cmp w0, #0x0
400580: 540001a1 b.ne 4005b4 // b.any
400584: 90000000 adrp x0, 400000 <_init-0x3e8>
400588: 911a8000 add x0, x0, #0x6a0
40058c: 97ffffb1 bl 400450
400590: 1400000d b 4005c4
400594: 90000000 adrp x0, 400000 <_init-0x3e8>
400598: 911aa000 add x0, x0, #0x6a8
40059c: 97ffffad bl 400450
4005a0: 14000009 b 4005c4
4005a4: 90000000 adrp x0, 400000 <_init-0x3e8>
4005a8: 911ac000 add x0, x0, #0x6b0
4005ac: 97ffffa9 bl 400450
4005b0: 14000005 b 4005c4
4005b4: 90000000 adrp x0, 400000 <_init-0x3e8>
4005b8: 911ae000 add x0, x0, #0x6b8
4005bc: 97ffffa5 bl 400450
4005c0: d503201f nop
4005c4: d503201f nop
4005c8: a8c27bfd ldp x29, x30, [sp], #32
4005cc: d65f03c0 ret
00000000004005d0 :
4005d0: a9bf7bfd stp x29, x30, [sp, #-16]!
4005d4: 910003fd mov x29, sp
4005d8: 52800040 mov w0, #0x2 // #2
4005dc: 97ffffe0 bl 40055c
4005e0: 52800000 mov w0, #0x0 // #0
4005e4: a8c17bfd ldp x29, x30, [sp], #16
4005e8: d65f03c0 ret
4005ec: 00000000 .inst 0x00000000 ; undefined
#endif