arm汇编 main函数分析

arm 汇编分析

1. 主要是为了搞清楚原子操作的实现原理。
2. 在 c语言环境下 变量赋值应该是可以被打断。
3. 还有是在c语言中变量赋值操作对应的汇编代码。
4. 原子操作的主要流程 read ---> modify -----> write (RWM )

那么接下来先看一下C 语言代码:

#include 

int func()
{
	int a = 10;
	int b = 0;
	b = a;
	return b;
}

int main()
{
	int a = 10;
	int b = a;
 	b = func();
	printf("a %d,b %d \n",a,b);
	return 0;
}

反汇编之后的汇编代码,

	#反汇编主要这两步
	1.  arm-none-gcc -c main.c -o main.o
	2.  arm-none-objdump -S main.o > main.s
	# 也可以一步到位
	1. arm-none-gcc -S main.c -o main.s 

main.o:     file format elf32-littlearm
Disassembly of section .text:

00000000 :
   0:	e52db004 	push	{fp}		; (str fp, [sp, #-4]!)
   4:	e28db000 	add	fp, sp, #0
   8:	e24dd00c 	sub	sp, sp, #12
   c:	e3a0300a 	mov	r3, #10
  10:	e50b300c 	str	r3, [fp, #-12]
  14:	e3a03000 	mov	r3, #0
  18:	e50b3008 	str	r3, [fp, #-8]
  1c:	e51b300c 	ldr	r3, [fp, #-12]
  20:	e50b3008 	str	r3, [fp, #-8]
  24:	e51b3008 	ldr	r3, [fp, #-8]
  28:	e1a00003 	mov	r0, r3
  2c:	e24bd000 	sub	sp, fp, #0
  30:	e49db004 	pop	{fp}		; (ldr fp, [sp], #4)
  34:	e12fff1e 	bx	lr

@ fp 和 sp 都是栈指针,一个是局部函数类的指针,一个是全局的栈指针,可以着这么理解
00000038 
: 38: e92d4800 push {fp, lr} @ 将fp lr 入栈,此时 sp = sp + 4 + 4 = sp + 8 3c: e28db004 add fp, sp, #4 @ fp = sp + 8 + 4 = sp + 12 40: e24dd008 sub sp, sp, #8 @ sp = sp - 8 @ 对照源码进行分析 r3 此时因该保存的局部变量 a存放的内存地址 44: e3a0300a mov r3, #10 @ sp fp 保持不变 r3 = 10 48: e50b300c str r3, [fp, #-12] @ fp - 12 = r3 , sp 和 fp 保持不变 4c: e51b300c ldr r3, [fp, #-12] @ r3 = fp - 12 , fp 和 sp 保持不变 50: e50b3008 str r3, [fp, #-8] @ fp - 8 = r3 ,fp 和 sp 保持不变 54: ebfffffe bl 0 58: e50b0008 str r0, [fp, #-8] @ r0 函数func的返回值 fp - 8 = r0 @ 这里r2 应该是保存的 变量b 的地址 5c: e51b2008 ldr r2, [fp, #-8] @ r2 = fp - 8,相当于 r2 = r0 60: e51b100c ldr r1, [fp, #-12] @ r1 = fp - 12 64: e59f0010 ldr r0, [pc, #16] ; 7c @ arm 三级流水线 ,如果此时正在执行这条指令,那么此时的pc = 当前地址 + 8, r0 = 7c 68: ebfffffe bl 0 6c: e3a03000 mov r3, #0 70: e1a00003 mov r0, r3 74: e24bd004 sub sp, fp, #4 78: e8bd8800 pop {fp, pc} 7c: 00000000 .word 0x00000000

然后有两个问题:
1. 一个函数内部的局部变量地址是怎么保存的? 是否是保存在某些通用的寄存器中?
2. 汇编中 fp 和 sp 区别?
3. C 语言中赋值操作 : 先把变量的值 从保存变量的内存地址中读出来放到某个寄存器中,然后赋值给保存其他变量地址的寄存器。

你可能感兴趣的:(arm)