ARM NDK 下载地址:
https://dl.google.com/android/repository/android-ndk-r20-linux-x86_64.zip
main.c
int main() {
int i = 0x11111111;
int j = 0x22222222;
int k = 0;
if (i > j) {
k = i;
} else {
k = j;
}
return 0;
}
在Android 工程中使用 arm toolchain,
arm-linux-androideabi-gcc --sysroot=~/Downloads/android-ndk-r20/platforms/android-29/arch-arm/ -o main -g main.c
反汇编成汇编语言,arm-linux-androideabi-objdump -d -S main > main.S
main: file format elf32-littlearm
Disassembly of section .plt:
000082e8 <__libc_init@plt-0x14>:
82e8: e52de004 push {lr} ; (str lr, [sp, #-4]!)
82ec: e59fe004 ldr lr, [pc, #4] ; 82f8
82f0: e08fe00e add lr, pc, lr
82f4: e5bef008 ldr pc, [lr, #8]!
82f8: 00001cf0 strdeq r1, [r0], -r0
000082fc <__libc_init@plt>:
82fc: e28fc600 add ip, pc, #0, 12
8300: e28cca01 add ip, ip, #4096 ; 0x1000
8304: e5bcfcf0 ldr pc, [ip, #3312]! ; 0xcf0
00008308 <__cxa_atexit@plt>:
8308: e28fc600 add ip, pc, #0, 12
830c: e28cca01 add ip, ip, #4096 ; 0x1000
8310: e5bcfce8 ldr pc, [ip, #3304]! ; 0xce8
00008314 <__register_atfork@plt>:
8314: e28fc600 add ip, pc, #0, 12
8318: e28cca01 add ip, ip, #4096 ; 0x1000
831c: e5bcfce0 ldr pc, [ip, #3296]! ; 0xce0
Disassembly of section .text:
00008320 <_start>:
8320: e1a0000d mov r0, sp
8324: eaffffff b 8328 <_start_main>
00008328 <_start_main>:
8328: e92d4800 push {fp, lr}
832c: e1a0b00d mov fp, sp
8330: e24dd010 sub sp, sp, #16
8334: e59f1030 ldr r1, [pc, #48] ; 836c <_start_main+0x44>
8338: e28d3004 add r3, sp, #4
833c: e79f1001 ldr r1, [pc, r1]
8340: e58d1008 str r1, [sp, #8]
8344: e59f1024 ldr r1, [pc, #36] ; 8370 <_start_main+0x48>
8348: e79f1001 ldr r1, [pc, r1]
834c: e58d1004 str r1, [sp, #4]
8350: e59f101c ldr r1, [pc, #28] ; 8374 <_start_main+0x4c>
8354: e79f1001 ldr r1, [pc, r1]
8358: e58d100c str r1, [sp, #12]
835c: e3a01000 mov r1, #0
8360: e59f2010 ldr r2, [pc, #16] ; 8378 <_start_main+0x50>
8364: e79f2002 ldr r2, [pc, r2]
8368: ebffffe3 bl 82fc <__libc_init@plt>
836c: 00001c94 .word 0x00001c94
8370: 00001c8c .word 0x00001c8c
8374: 00001c84 .word 0x00001c84
8378: 00001c78 .word 0x00001c78
0000837c <__atexit_handler_wrapper>:
837c: e3500000 cmp r0, #0
8380: 012fff1e bxeq lr
8384: e12fff10 bx r0
00008388 :
8388: e1a01000 mov r1, r0
838c: e59f000c ldr r0, [pc, #12] ; 83a0
8390: e59f200c ldr r2, [pc, #12] ; 83a4
8394: e08f0000 add r0, pc, r0
8398: e08f2002 add r2, pc, r2
839c: eaffffd9 b 8308 <__cxa_atexit@plt>
83a0: ffffffe0 .word 0xffffffe0
83a4: 00001c60 .word 0x00001c60
000083a8 :
83a8: e59f3004 ldr r3, [pc, #4] ; 83b4
83ac: e08f3003 add r3, pc, r3
83b0: eaffffd7 b 8314 <__register_atfork@plt>
83b4: 00001c4c .word 0x00001c4c
000083b8 :
int main() {
83b8: e52db004 push {fp} ; (str fp, [sp, #-4]!)
83bc: e28db000 add fp, sp, #0
83c0: e24dd014 sub sp, sp, #20
int i = 0x11111111;
83c4: e59f3048 ldr r3, [pc, #72] ; 8414
83c8: e50b3008 str r3, [fp, #-8]
int j = 0x22222222;
83cc: e59f3044 ldr r3, [pc, #68] ; 8418
83d0: e50b300c str r3, [fp, #-12]
int k = 0;
83d4: e3a03000 mov r3, #0
83d8: e50b3010 str r3, [fp, #-16]
if (i > j) {
83dc: e51b2008 ldr r2, [fp, #-8]
83e0: e51b300c ldr r3, [fp, #-12]
83e4: e1520003 cmp r2, r3
83e8: da000002 ble 83f8
k = i;
83ec: e51b3008 ldr r3, [fp, #-8]
83f0: e50b3010 str r3, [fp, #-16]
83f4: ea000001 b 8400
} else {
k = j;
83f8: e51b300c ldr r3, [fp, #-12]
83fc: e50b3010 str r3, [fp, #-16]
}
return 0;
8400: e3a03000 mov r3, #0
}
8404: e1a00003 mov r0, r3
8408: e24bd000 sub sp, fp, #0
840c: e49db004 pop {fp} ; (ldr fp, [sp], #4)
8410: e12fff1e bx lr
8414: 11111111 .word 0x11111111
8418: 22222222 .word 0x22222222
下面看下 main 函数用到的汇编:
000083b8
int main() {
83b8: e52db004 push {fp} ; (str fp, [sp, #-4]!) // 将当前 fp 压栈
83bc: e28db000 add fp, sp, #0 // 将当前 sp 加上 立即数 0,结果保存到 fp
83c0: e24dd014 sub sp, sp, #20 // 将sp 减去 立即数 20,结果写到 sp,这个是因为 ARM 满递增栈,向下增长(高地址向低地址),在栈上预留 20 个字节的内存,给 int i, j , m ,k 用。函数中定义的局部变量是在栈上分配内存。
int i = 0x11111111;
83c4: e59f3048 ldr r3, [pc, #72] ; 8414
83c8: e50b3008 str r3, [fp, #-8] // 将 r3 的值 用 set register 指令,存储到 fp + (-8) offset 的内存中去(Offset Addressing),fp 指向 栈顶,-8 之后是栈上 为 i 分配的内存地址
int j = 0x22222222;
83cc: e59f3044 ldr r3, [pc, #68] ; 8418
83d0: e50b300c str r3, [fp, #-12] // j
int k = 0;
83d4: e3a03000 mov r3, #0
83d8: e50b3010 str r3, [fp, #-16] // k
if (i > j) {
83dc: e51b2008 ldr r2, [fp, #-8]
83e0: e51b300c ldr r3, [fp, #-12]
83e4: e1520003 cmp r2, r3 // i j 大小比较
83e8: da000002 ble 83f8
k = i;
83ec: e51b3008 ldr r3, [fp, #-8] // i
83f0: e50b3010 str r3, [fp, #-16] // 将 i 的值赋给 k
83f4: ea000001 b 8400
} else {
k = j;
83f8: e51b300c ldr r3, [fp, #-12]
83fc: e50b3010 str r3, [fp, #-16]
}
return 0;
8400: e3a03000 mov r3, #0
}
8404: e1a00003 mov r0, r3
8408: e24bd000 sub sp, fp, #0
840c: e49db004 pop {fp} ; (ldr fp, [sp], #4) // Post-Index Addressing
8410: e12fff1e bx lr
8414: 11111111 .word 0x11111111 // 数据段
8418: 22222222 .word 0x22222222
20190716 追加:
评论里面没法加图片,还是有必要追加上ARM DS-5 把 O3 打开以后看到的执行情况:
首先配置编译选项,指定优化为 -O3
看到汇编只有如图所示,直接返回,
DS-5 编译优化 -O0 时汇编如下: