ARM 汇编实例
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-littlearmDisassembly of section .plt:000082e8 <__libc_init@plt-0x14>: 82e8:e52de004 push{lr}; (str lr, [sp, #-4]!) 82ec:e59fe004 ldrlr, [pc, #4]; 82f8 82f0:e08fe00e addlr, pc, lr 82f4:e5bef008 ldrpc, [lr, #8]! 82f8:00001cf0 strdeqr1, [r0], -r0000082fc <__libc_init@plt>: 82fc:e28fc600 addip, pc, #0, 12 8300:e28cca01 addip, ip, #4096; 0x1000 8304:e5bcfcf0 ldrpc, [ip, #3312]!; 0xcf000008308 <__cxa_atexit@plt>: 8308:e28fc600 addip, pc, #0, 12 830c:e28cca01 addip, ip, #4096; 0x1000 8310:e5bcfce8 ldrpc, [ip, #3304]!; 0xce800008314 <__register_atfork@plt>: 8314:e28fc600 addip, pc, #0, 12 8318:e28cca01 addip, ip, #4096; 0x1000 831c:e5bcfce0 ldrpc, [ip, #3296]!; 0xce0Disassembly of section .text:00008320 <_start>: 8320:e1a0000d movr0, sp 8324:eaffffff b8328 <_start_main>00008328 <_start_main>: 8328:e92d4800 push{fp, lr} 832c:e1a0b00d movfp, sp 8330:e24dd010 subsp, sp, #16 8334:e59f1030 ldrr1, [pc, #48]; 836c <_start_main+0x44> 8338:e28d3004 addr3, sp, #4 833c:e79f1001 ldrr1, [pc, r1] 8340:e58d1008 strr1, [sp, #8] 8344:e59f1024 ldrr1, [pc, #36]; 8370 <_start_main+0x48> 8348:e79f1001 ldrr1, [pc, r1] 834c:e58d1004 strr1, [sp, #4] 8350:e59f101c ldrr1, [pc, #28]; 8374 <_start_main+0x4c> 8354:e79f1001 ldrr1, [pc, r1] 8358:e58d100c strr1, [sp, #12] 835c:e3a01000 movr1, #0 8360:e59f2010 ldrr2, [pc, #16]; 8378 <_start_main+0x50> 8364:e79f2002 ldrr2, [pc, r2] 8368:ebffffe3 bl82fc <__libc_init@plt> 836c:00001c94 .word0x00001c94 8370:00001c8c .word0x00001c8c 8374:00001c84 .word0x00001c84 8378:00001c78 .word0x00001c780000837c <__atexit_handler_wrapper>: 837c:e3500000 cmpr0, #0 8380:012fff1e bxeqlr 8384:e12fff10 bxr000008388 : 8388:e1a01000 movr1, r0 838c:e59f000c ldrr0, [pc, #12]; 83a0 8390:e59f200c ldrr2, [pc, #12]; 83a4 8394:e08f0000 addr0, pc, r0 8398:e08f2002 addr2, pc, r2 839c:eaffffd9 b8308 <__cxa_atexit@plt> 83a0:ffffffe0 .word0xffffffe0 83a4:00001c60 .word0x00001c60000083a8 : 83a8:e59f3004 ldrr3, [pc, #4]; 83b4 83ac:e08f3003 addr3, pc, r3 83b0:eaffffd7 b8314 <__register_atfork@plt> 83b4:00001c4c .word0x00001c4c000083b8 :int main() { 83b8:e52db004 push{fp}; (str fp, [sp, #-4]!) 83bc:e28db000 addfp, sp, #0 83c0:e24dd014 subsp, sp, #20 int i = 0x11111111; 83c4:e59f3048 ldrr3, [pc, #72]; 8414 83c8:e50b3008 strr3, [fp, #-8] int j = 0x22222222; 83cc:e59f3044 ldrr3, [pc, #68]; 8418 83d0:e50b300c strr3, [fp, #-12] int k = 0; 83d4:e3a03000 movr3, #0 83d8:e50b3010 strr3, [fp, #-16] if (i > j) { 83dc:e51b2008 ldrr2, [fp, #-8] 83e0:e51b300c ldrr3, [fp, #-12] 83e4:e1520003 cmpr2, r3 83e8:da000002 ble83f8 k = i; 83ec:e51b3008 ldrr3, [fp, #-8] 83f0:e50b3010 strr3, [fp, #-16] 83f4:ea000001 b8400 } else { k = j; 83f8:e51b300c ldrr3, [fp, #-12] 83fc:e50b3010 strr3, [fp, #-16] } return 0; 8400:e3a03000 movr3, #0} 8404:e1a00003 movr0, r3 8408:e24bd000 subsp, fp, #0 840c:e49db004 pop{fp}; (ldr fp, [sp], #4) 8410:e12fff1e bxlr 8414:11111111 .word0x11111111 8418:22222222 .word0x22222222
下面看下 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 时汇编如下:
更多相关文章
- Android平台上优秀的开源项目
- GitHub 优秀的 Android(安卓)开源项目
- 【Android】文件读写操作(含SDCard的读写)
- 【Android(安卓)应用开发】GitHub 优秀的 Android(安卓)开源项目
- 【Android(安卓)volley】Android库Volley的使用介绍
- 【android测试】值得学习的android测试知识连接
- android获取经纬度和地方名称
- Android(安卓)获取内存信息
- android linker (1) —— __linker_init()