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 <note_end+0xf8>
    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 <atexit>:
    8388:	e1a01000 	mov	r1, r0
    838c:	e59f000c 	ldr	r0, [pc, #12]	; 83a0 <atexit+0x18>
    8390:	e59f200c 	ldr	r2, [pc, #12]	; 83a4 <atexit+0x1c>
    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 <pthread_atfork>:
    83a8:	e59f3004 	ldr	r3, [pc, #4]	; 83b4 <pthread_atfork+0xc>
    83ac:	e08f3003 	add	r3, pc, r3
    83b0:	eaffffd7 	b	8314 <__register_atfork@plt>
    83b4:	00001c4c 	.word	0x00001c4c

000083b8 <main>:
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 <main+0x5c>
    83c8:	e50b3008 	str	r3, [fp, #-8]
  int j = 0x22222222;
    83cc:	e59f3044 	ldr	r3, [pc, #68]	; 8418 <main+0x60>
    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 <main+0x40>
    k = i;
    83ec:	e51b3008 	ldr	r3, [fp, #-8]
    83f0:	e50b3010 	str	r3, [fp, #-16]
    83f4:	ea000001 	b	8400 <main+0x48>
  } 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 <main>:
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 <main+0x5c> //加載寄存器指令,將 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 <main+0x60>
    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 <main+0x40> // 跳轉指令
    k = i;
    83ec:    e51b3008     ldr    r3, [fp, #-8] // i
    83f0:    e50b3010     str    r3, [fp, #-16] // 將 i 的值賦給 k
    83f4:    ea000001     b    8400 <main+0x48>
  } 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 時彙編如下:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章