# func.c, source code
######################################################
1 int func(int x)
2 {
3
4 if (__builtin_expect(x, 0))
5 {
6 x += 5;
7 }
8 else
9 {
10 x += 6;
11 }
12
13 return x;
14 }
######################################################
# func.c, X86
######################################################
$ gcc -c -O2 func.c -o func.o
$ objdump -S func.o
func.o: file format elf32-i386
Disassembly of section .text:
00000000
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 8b 45 08 mov 0x8(%ebp),%eax
6: 85 c0 test %eax,%eax
8: 75 07 jne 11
a: 5d pop %ebp
b: b8 06 00 00 00 mov $0x6,%eax
10: c3 ret
11: 5d pop %ebp
12: 83 c0 05 add $0x5,%eax
15: c3 ret
$
這邊可以發現,X86的作法最為直覺,很接近一般人的思路。
######################################################
# func.c, ARM
######################################################
$ arm-linux-gcc -c -O2 func.c -o func.arm.o
$ arm-linux-objdump -S func.arm.o
func.arm.o: file format elf32-littlearm
Disassembly of section .text:
00000000
0: e3500000 cmp r0, #0 ; 0x0
4: 12800005 addne r0, r0, #5 ; 0x5
8: 02800006 addeq r0, r0, #6 ; 0x6
c: e1a0f00e mov pc, lr
$
ARM的理念是善用根據flags條件去決定是否要執行一指令(addne, addeq)
######################################################
# func.c, SPARC
######################################################
$ sparc-linux-gcc -c -O2 func.c -o func.sparc.o
$ sparc-linux-objdump -S func.sparc.o
func.sparc.o: file format elf32-sparc
Disassembly of section .text:
00000000
0: 80 a2 20 00 cmp %o0, 0
4: 12 80 00 03 bne 10
8: 90 02 20 05 add %o0, 5, %o0
c: 90 10 20 06 mov 6, %o0
10: 81 c3 e0 08 retl
14: 01 00 00 00 nop
$
SPARC則利用NPC的特性,於BNE之後先執行ADD再說,如果BNE成立,再補執行mov指令。
No comments:
Post a Comment