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-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 //加载寄存器指令,将 pc 加上 offset 72 的内容 (Offset Addressing)加载到 r3 寄存器,也就是 8414 地址的内容,是数据段 i 的初始值 0x11111111 。
    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

ARM 汇编实例_第1张图片

看到汇编只有如图所示,直接返回,

ARM 汇编实例_第2张图片

DS-5 编译优化 -O0 时汇编如下:

ARM 汇编实例_第3张图片

你可能感兴趣的:(ARM)