C 中for 循环语句执行顺序之我是汇编

20 篇文章 0 订阅

for(i = 0; i < 10; i ++)

这样的for 语句可能再基础不过,可是理解不清楚还是容易犯错误。

现在我用ARM 汇编指令分析一下这样的语句到底是怎么执行的(当你看C代码不知道代码到底是怎么执行的时候,要么查C标准,要么看熟悉的ARM 汇编)。

测试用例:

/*
 ============================================================================
 Name        : while.c
 Author      : qiang
 Version     :
 Copyright   : Your copyright notice
 Description : Hello World in C, Ansi-style
 ============================================================================
 */

#include <stdio.h>
#include <stdlib.h>

int main(void) {
	int i = 0;

	for(i = 0; i < 10; ++i) {
		printf("i = %d \n", i);
	}

	puts("!!!Hello World!!!"); /* prints !!!Hello World!!! */
	return EXIT_SUCCESS;
}

编译成ARM 可执行文件,

$ android_native_gcc -o while -g while.c

这里我设置了bash alias,

alias android_native_gcc='arm-linux-androideabi-gcc --sysroot=/home/qiang/wrwork/android/android-ndk-r9/platforms/android-18/arch-arm'

还有务必加上 -g 调试选项,不然之后反汇编的时候即使再怎么加上 -S 选项,C语言的代码也出不来的。


反汇编:

$ arm-linux-androideabi-objdump -d -S while > while.S

下面就可以研究一下 ARM  汇编了:

while:     file format elf32-littlearm


Disassembly of section .plt:

0000824c <__libc_init@plt-0x14>:
    824c:	e52de004 	.word	0xe52de004
    8250:	e59fe004 	.word	0xe59fe004
    8254:	e08fe00e 	.word	0xe08fe00e
    8258:	e5bef008 	.word	0xe5bef008
    825c:	00001d88 	.word	0x00001d88

00008260 <__libc_init@plt>:
    8260:	e28fc600 	.word	0xe28fc600
    8264:	e28cca01 	.word	0xe28cca01
    8268:	e5bcfd88 	.word	0xe5bcfd88

0000826c <__cxa_atexit@plt>:
    826c:	e28fc600 	.word	0xe28fc600
    8270:	e28cca01 	.word	0xe28cca01
    8274:	e5bcfd80 	.word	0xe5bcfd80

00008278 <printf@plt>:
    8278:	e28fc600 	.word	0xe28fc600
    827c:	e28cca01 	.word	0xe28cca01
    8280:	e5bcfd78 	.word	0xe5bcfd78

00008284 <puts@plt>:
    8284:	e28fc600 	.word	0xe28fc600
    8288:	e28cca01 	.word	0xe28cca01
    828c:	e5bcfd70 	.word	0xe5bcfd70

Disassembly of section .text:

00008290 <_start>:
    8290:	e59fc05c 	ldr	ip, [pc, #92]	; 82f4 <_start+0x64>
    8294:	e92d4800 	push	{fp, lr}
    8298:	e59f3058 	ldr	r3, [pc, #88]	; 82f8 <_start+0x68>
    829c:	e28db004 	add	fp, sp, #4
    82a0:	e24dd010 	sub	sp, sp, #16
    82a4:	e08fc00c 	add	ip, pc, ip
    82a8:	e79c3003 	ldr	r3, [ip, r3]
    82ac:	e50b3014 	str	r3, [fp, #-20]
    82b0:	e59f3044 	ldr	r3, [pc, #68]	; 82fc <_start+0x6c>
    82b4:	e28b0004 	add	r0, fp, #4
    82b8:	e79c3003 	ldr	r3, [ip, r3]
    82bc:	e50b3010 	str	r3, [fp, #-16]
    82c0:	e59f3038 	ldr	r3, [pc, #56]	; 8300 <_start+0x70>
    82c4:	e3a01000 	mov	r1, #0
    82c8:	e79c3003 	ldr	r3, [ip, r3]
    82cc:	e50b300c 	str	r3, [fp, #-12]
    82d0:	e59f302c 	ldr	r3, [pc, #44]	; 8304 <_start+0x74>
    82d4:	e79c3003 	ldr	r3, [ip, r3]
    82d8:	e50b3008 	str	r3, [fp, #-8]
    82dc:	e59f3024 	ldr	r3, [pc, #36]	; 8308 <_start+0x78>
    82e0:	e79c2003 	ldr	r2, [ip, r3]
    82e4:	e24b3014 	sub	r3, fp, #20
    82e8:	ebffffdc 	bl	8260 <__libc_init@plt>
    82ec:	e24bd004 	sub	sp, fp, #4
    82f0:	e8bd8800 	pop	{fp, pc}
    82f4:	00001d38 	.word	0x00001d38
    82f8:	ffffffec 	.word	0xffffffec
    82fc:	fffffff0 	.word	0xfffffff0
    8300:	fffffff4 	.word	0xfffffff4
    8304:	fffffff8 	.word	0xfffffff8
    8308:	fffffffc 	.word	0xfffffffc

0000830c <atexit>:
    830c:	e59f2008 	ldr	r2, [pc, #8]	; 831c <atexit+0x10>
    8310:	e3a01000 	mov	r1, #0
    8314:	e08f2002 	add	r2, pc, r2
    8318:	eaffffd3 	b	826c <__cxa_atexit@plt>
    831c:	00001ce4 	.word	0x00001ce4

00008320 <main>:
 */

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    8320:	e92d4800 	push	{fp, lr}
    8324:	e28db004 	add	fp, sp, #4
    8328:	e24dd008 	sub	sp, sp, #8
	int i = 0;
    832c:	e3a03000 	mov	r3, #0
    8330:	e50b3008 	str	r3, [fp, #-8]

	for(i = 0; i < 10; ++i) {
    8334:	e3a03000 	mov	r3, #0
    8338:	e50b3008 	str	r3, [fp, #-8]
    833c:	ea000007 	b	8360 <main+0x40>
		printf("i = %d \n", i);
    8340:	e59f3044 	ldr	r3, [pc, #68]	; 838c <main+0x6c>
    8344:	e08f3003 	add	r3, pc, r3
    8348:	e1a00003 	mov	r0, r3
    834c:	e51b1008 	ldr	r1, [fp, #-8]
    8350:	ebffffc8 	bl	8278 <printf@plt>
#include <stdlib.h>

int main(void) {
	int i = 0;

	for(i = 0; i < 10; ++i) {
    8354:	e51b3008 	ldr	r3, [fp, #-8]
    8358:	e2833001 	add	r3, r3, #1
    835c:	e50b3008 	str	r3, [fp, #-8]
    8360:	e51b3008 	ldr	r3, [fp, #-8]
    8364:	e3530009 	cmp	r3, #9
    8368:	dafffff4 	ble	8340 <main+0x20>
		printf("i = %d \n", i);
	}

	puts("!!!Hello World!!!"); /* prints !!!Hello World!!! */
    836c:	e59f301c 	ldr	r3, [pc, #28]	; 8390 <main+0x70>
    8370:	e08f3003 	add	r3, pc, r3
    8374:	e1a00003 	mov	r0, r3
    8378:	ebffffc1 	bl	8284 <puts@plt>
	return EXIT_SUCCESS;
    837c:	e3a03000 	mov	r3, #0
}
    8380:	e1a00003 	mov	r0, r3
    8384:	e24bd004 	sub	sp, fp, #4
    8388:	e8bd8800 	pop	{fp, pc}
    838c:	00000060 	.word	0x00000060
    8390:	00000040 	.word	0x00000040

ARM 指令记不清的话翻看一下 ARM+System+Developers+Guide-Designing+and+Optimizing+System+Software.pdf


其中, [Rd] 表示的是以 Rd 寄存器中的值为地址的memory 中的内容。


That's all !  Enjoy ARM assembly, Enjoy C !!!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值