ARM基础知识

预备知识

软件
	系统软件
	中间件
	应用软件
硬件
	电源
	输入设备
	输出设备
	存储器
		CPU寄存器(CPU Register)存临时数据、控制设备
		高速缓冲(Cache)主要存热点数据
		内存(RAM)掉电数据丢失(直接寻址)
		硬盘(Hard Disk)掉电数据不会丢失(无法直接寻址)
	总线
	CPU
		物理结构
		CPU组成
			运算器(累加器,乘除使用位移)
			控制器(控制程序的运行)
			存储器
			总线(bus)信息交流通道
		工作原理
			取指令(Fetch)
			翻译指令(Decode)
			执行指令(Execute)
		CPU性能提升
			提升工艺
			Cache
			多ALU(逻辑运算单元)和FPU(浮点运算单元)
			流水线
		架构演进(哈弗)

系统设计

SOC(System on Chip)系统级芯片,是模仿计算机系统,微缩成了一个微系统
AMBA(Advanced Microcontroller Bus Architecture)高级微控制器总线架构
	AHB(高速总线)
	ASB(系统总线)
	APB(外部总线)
	AXI

编程模型

数据和指令类型	
工作模式
	User:非特权模式
	System:特权模式
	FIQ:高优先级中断产生
	IRQ:低优先级中断产生
	Supervisor(SVC):复位或软中断产生
	Abort:存取异常产生
	Undef:执行未定义指令
	Monitor:执行安全监控代码(也是一种特权模式)
异常
大小端
	大端是高字节存放到内存的低地址
	小端是高字节存放到内存的高地址

寄存器组织

通用寄存器
	r1-r12 寄存器:存放任意数据
	r13(sp)stack pointer 寄存器:存放栈顶的地址(栈区)
	r14(lr)link register/return 寄存器:存放返回的地址
	r15(pc)point counter 寄存器:存放下一条指令的地址(跳转指令)(功能类似goto)
cpsr (当前程序状态寄存器)寄存器
spsr (备份程序状态寄存器)寄存器:还原状态

ARM操作指令(最后一个可以为数值)

数据传输指令:mov
		mov r0,#1
算术运算指令:add,sub,mul,adds(加法,若溢出,会将cpsr的溢出位,置1),adc(加法,若溢出,会将cpsr的溢出位加到结果中)
		add r1,r0,r2
		sub r2,r1,r0
		mul r1,r2,r0
位操作指令:and(&),orr(|),eor(^),bic(按位清零)
		and r0,r1,r2
		orr r1,r0,r2
		eor 
		bic r0,r0,r1
跳转指令:b,bl(保存返回地址到lr寄存器)
		b 标签	
比较指令:cmp(比较后存储在cpsr中 NZ)
		cmp r0,r1
		movgt r0,#4
注释:@,/**/

模拟调试流程

编写代码
	.global _start
	_start:
			mov r0,#1
			mov r1,#3
			nop
			nop
编译代码
	arm-linux-gcc test.s -o test.o -c -g
	arm-linux-ld test.o -o test.elf -Ttext=0x0
启动虚拟arm版
	qemu-system-arm -machine xilinx-zynq-a9 -m 256M -serial stdio -kernel test.elf -S -s
调试(可能由于bash编码出现错误,修改bashrc,只保留LA_ALL=C)
	arm-none-linux-gnueabi-gdb test.elf
gdb命令
	target remote 127.0.0.1:1234

立即数

可以直接从指令中得到的数值(转换为二进制,去掉循环的偶数个0,相邻两位去掉,且剩下的数据<=8bits)

伪指令

由编译器拟定的规则,在编译的过程中生成相应的指令(gnu提供)
ldr r3,=0xffff 	@r3 = 0xffff(伪指令)
ldr r0,[r1] 	@r0 = *((int*)r1)(指令)
ldr r0,[r1,#4] 	@r0 = *((int*)r1+4)(指令)
str r0,[r1]		@*((int*)r1) = r0(指令)

.global 	@声明为全局变量,可在外部调用
.text 		@代码段
.data 		@数据
.bss		@全局未初始化变量
buf: .word 1,2,3,4,5 	@int buf[] = {1,2,3,4};
buf: .space 0x100 	@int* buf = malloc(0x100);

ARM的寻址方式

立即数寻址:数据存放在指令中
	mov r0,#1
寄存器寻址:寄存器中存放数据
	mov r0,r1
寄存器偏移寻址:
	mov r0,r1,lsl #3@逻辑左偏移3位(lsl逻辑左移,lsr逻辑右移,asl算术左移,asr算术右移)
寄存器间接寻址:寄存器中存放数据的地址
	ldr r0,[r1]		@取r1地址的值
寄存器基址变址寻址:
	ldr r0,[r1,#4]	@取r1地址+4的值
多寄存器寻址:同时操作多个寄存器
	stmfd sp!,{r0,r1,r2}	@入栈	 ldmfd sp!,{r0,r1,r2}	@出栈	@!:其执行的操作会修改原来的值
相对寻址
堆栈寻址
块拷贝寻址

异常

异常(CPU逻辑运行的一种机制)(类似信号)
	异常和模式的关系:
		模式:异常
		SVC:reset swi
		Abort:data prefetch
		FIQ:fiq
		IRQ:irq
		Undefined:undefined
	
中断处理流程
	中断会触发异常信号,
	CPU捕获异常信号,备份当前状态(在用户态user模式,使用spsr),保存下一条指令的地址(在内核态irq模式,使用lr)(通过使用栈,irq中lr寄存器保存的地址不会改变),并切换到相应的模式(修改cpsr)
	查找异常向量表(存放跳转到相应异常处理函数的指令)(不同异常对应的地址偏移量是固定的)
	跳转到异常处理函数(由CPU内部提供),分配中断处理函数(用户提供),跳转中断处理函数,恢复先前状态,并返回下一条指令的地址(恢复状态和返回指令同时运行)

异常优先级
	Reset
	Data Abort
	FIQ
	IRQ
	Prefetch Abort
	SWI
	Undefined

汇编程序编译流程

arm-linux-gcc sys.s -o sys.o -c -g
arm-linux-ld sys.o main.o -o sys.elf -Ttext=0x41000000
arm-linux-objcopy sys.elf sys.bin -O binary

C汇编混合程序编译流程

arm-linux-gcc sys.s -o sys.o -c -g
arm-linux-gcc main.c -o main.o -c -g
arm-linux-ld sys.o main.o -o sys.elf -T test.lds
arm-linux-objcopy sys.elf sys.bin -O binary

连接文件test.lds(决定sys.o与main.c的连接顺序)
ENTRY(_start)
SECTIONS{
	. = 0x41000000;
	.text : {
		sys.o(.text)
		*(.text)
	}
	.data : {
		*(.data)
	}
	.bss : {
		*(.bss)	
	}
}

中断处理示例(汇编)

.globl _start
_start: /*异常向量表*/
	b	reset
	ldr	pc, _undefined_instruction
	ldr	pc, _software_interrupt
	ldr	pc, _prefetch_abort
	ldr	pc, _data_abort
	ldr	pc, _not_used
	ldr	pc, _irq
	ldr	pc, _fiq
_undefined_instruction: .word _undefined_instruction
_software_interrupt:	.word swi_handler
_prefetch_abort:	.word _prefetch_abort
_data_abort:		.word _data_abort
_not_used:		.word _not_used
_irq:			.word _irq
_fiq:			.word _fiq

stack: .space 16*8  /*stack = malloc(16*8)在内存中开辟栈空间*/
stacktop: .word stack+16*8

stack1: .space 16*8  /*stack1 = malloc(16*8)*/
stacktop1: .word stack1+16*8

buf: .space 16 /*在内存中开辟共享空间*/

reset:
	/*设置模式为svc*/
	mrs	r0, cpsr
	bic	r0, r0, #0x1f  
	orr	r0, r0, #0xd3
	msr	cpsr,r0
	/* 设置异常向量表首地址*/
	ldr	r0, =0x0
	mcr	p15, 0, r0, c12, c0, 0	@Set VBAR
    /*初始化*/
    ldr r0,=stacktop
    ldr sp, [r0]

    /*设置模式为user*/
	mrs	r0, cpsr
	bic	r0, r0, #0x1f  
	orr	r0, r0, #0xd0  @110 10000
	msr	cpsr,r0

    ldr r0,=stacktop1
    ldr sp, [r0]

    bl	_main

_main:
    mov r7, #3
    mov r8, #6

    ldr r0,=buf
    str r7,[r0]
    str r8,[r0,#4]

    bl usr_add
    bl usr_sub

    nop
    nop

usr_add:
    stmfd sp!, {lr}

    mov r1,#1
    ldr r0,=buf
    str r1,[r0,#8]
    
    swi 1
    ldmfd sp!, {pc}

usr_sub:
    stmfd sp!,{lr}

    mov r1,#0
    ldr r0,=buf
    str r1,[r0,#8]

    swi 0
    ldmfd sp!,{pc}

swi_handler:
    stmfd sp!, {lr}

    ldr r0,=buf
    ldr r1,[r0,#8]


    /*ldr r1,[lr,#-4]
    and r1,r1,#0x1*/

    cmp r1,#1
    bleq sys_add
    cmp r1,#0
    bleq sys_sub

    ldmfd sp!, {pc}^ 

sys_add:
    stmfd sp!, {lr}

    ldr r0,=buf
    ldr r7,[r0]
    ldr r8,[r0,#4]

    add r7, r7, r8

    ldmfd sp!, {pc}


sys_sub:
    stmfd sp!, {lr}

    ldr r0,=buf
    ldr r7,[r0]
    ldr r8,[r0,#4]

    sub r7, r7, r8

    ldmfd sp!, {pc}

点灯

.globl _start
_start: 
	b	reset
	ldr	pc, _undefined_instruction
	ldr	pc, _software_interrupt
	ldr	pc, _prefetch_abort
	ldr	pc, _data_abort
	ldr	pc, _not_used
	ldr	pc, _irq
	ldr	pc, _fiq
_undefined_instruction: .word _undefined_instruction
_software_interrupt:	.word _software_interrupt
_prefetch_abort:	.word _prefetch_abort
_data_abort:		.word _data_abort
_not_used:		.word _not_used
_irq:			.word _irq
_fiq:			.word _fiq


stack: .space 16*8  @ stack = malloc(16*8)
stacktop: .word stack+16*8

stack1: .space 16*8  @ stack1 = malloc(16*8)
stacktop1: .word stack1+16*8


reset:
	/*设置模式为svc*/
	mrs	r0, cpsr
	bic	r0, r0, #0x1f  
	orr	r0, r0, #0xd3
	msr	cpsr,r0
	/* 设置异常向量表首地址*/
	ldr	r0, =0x41000000
	mcr	p15, 0, r0, c12, c0, 0	@Set VBAR
    /*初始化*/
    ldr r0,=stacktop
    ldr sp, [r0]

    /*设置模式为user*/
	mrs	r0, cpsr
	bic	r0, r0, #0x1f  
	orr	r0, r0, #0xd0  @110 10000
	msr	cpsr,r0
	
	ldr r0,=stacktop1
    	ldr sp, [r0]

    bl	_main

_main:

    ldr r0,=0x114001E0
    ldr r1,[r0]
    bic r1,r1,#0xf00000
    orr r1,r1,#0x100000
    str r1,[r0]

    ldr r0,=0x114001E4
    ldr r1,[r0]
    bic r1,r1,#0x20
    orr r1,r1,#0x20
    str r1,[r0]

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值