目录
运行模式
寄存器组
通用寄存器
程序状态寄存器
系统寄存器
ARM常用汇编指令
汇编点亮LED
User(USR):用户模式。linux系统用户进程,资源访问受限。
System(SYS):系统模式。linux内核,共用寄存器,资源自由访问。
IRQ:一般中断模式。硬件产生中断信号。
FIQ:快速中断模式。时间紧急的中断,高速信号的传输、采集。
Supervisor(SVC):管理模式。默认模式,系统初始化,软中断。
Abort(ABT):数据访问终止模式。非法访问地址或寄存器、段错误。
Undef(UND):未定义指令模式。程序跑飞、篡改。
Monitor:用于用户安全扩展模式。
Hyp:用于虚拟化扩展。
r0~r3:用来传递函数参数、暂存数据。
r4~r11:用来保存被调函数的局部变量、暂存数据。
r12:记录函数调用过程中上一次sp指针的值。
r13(sp):函数堆栈寄存器。
r14(lr):记录函数返回地址。
r15(pc):程序计数器。
cpsr:该寄存器包含运算标志位、中断禁止位、当前运行模式标志等一些状态位以及一些控制位。
spsr:发生异常切换模式时,将cpsr复制到发生异常的模式下的spsr。
cp15协处理器:内存、缓存、中断等。
汇编格式:
label:instruction @ comment
label:标号
instruction:具体汇编指令
comment:注释内容
bin文件组成:
.text段:代码文本
.rodata段:只读变量,如const修饰的变量
.data段:非零的全局变量、静态变量
.bss段:零值的全局变量、静态变量
.comment段:存放注释
.section段:自定义段
例如:.section .vector
常用伪操作:
.global:定义全局变量
例如:.global _start
.align:字节对齐
例如:.align 2
寄存器间数据传输:
mov:寄存器数据(或者是立即数)拷贝到另一个寄存器。
例如:mov r0,r1 r1寄存器的值拷贝到r0寄存器
mov r0,#0x12 0x12的值赋值给r0寄存器
mrs:读程序状态寄存器
例如:mrs r0,cpsr
msr:写程序状态寄存器
例如:msr cpsr,r0
mrc:读cp15协处理器
mcr:写cp15寄存器
内存与寄存器数据传输:
ldr:把内存数据(或者是立即数)加载到寄存器
例如:ldr r0,=0x80000000
ldr r1,[r0] []表示指针,将r0指向的值赋值给r1
str:把寄存器数据写入到内存
例如:ldr r0,=0x80000000
str r1,[r0] 把r1寄存器的值写入到r0
压栈和出栈
push:把寄存器列表存入栈中
例如:push {r0~r3,r12}
pop:从栈中恢复寄存器列表
例如:pop {r0~r3,r12}
跳转
b:跳转到目标地址
例如:b main
bl:跳转到目标地址,并把当前pc指针值保存在lr寄存器中
例如:bl main
算术运算指令
add:加法运算
例如:add r1,r2,r3 r2+r3的值赋值给r1,以下用法类似
add r1,r2 r1+r2的值赋值给r1,以下用法类似
sub:减法运算
例如:sub r1,r2,r3
mul:乘法运算
例如:mul r1,r2,r3
udiv:除法运算
例如:udiv r1,r2,r3
逻辑运算
and:与
例如:and r1,r2,r3
orr:或
例如:orr r1,r2,r3
bic:位清除
例如:bic r1,r2,r3
led.s文件
.global _start
_start:
@使能GPIO时钟,CCM_CCGR1寄存器
ldr r0,=0x20c406c
ldr r1,=0x3<<26
str r1,[r0]
@设置引脚复用为GPIO,IOMUXC_SW_MUX_CTL_PAD_XXX寄存器
ldr r0,=0x20e006c
ldr r1,=0x0101
str r1,[r0]
@设置引脚属性(上下拉、速率、驱动能力),SW_PAD_CTL_PAD_GPIO1_IO04寄存器
ldr r0,=0x20e02f8
ldr r1,=0x10b0
str r1,[r0]
@控制GPIO引脚输出低电平,GPIOx_DR寄存器
ldr r0,=0x0209c004
ldr r1,=0x1<<4
str r1,[r0]
@控制GPIO引脚,GPIOx_GDIR寄存器
ldr r0,=0x0209c000
ldr r1,=0x0<<4
str r1,[r0]
程序编译:
下载裸机的gcc编译器:sudo apt-get install gcc-arm-none-eabi
编译汇编文件为可重定位文件led.o:arm-none-eabi-gcc -c led.s -o led.o
把重定向文件链接起来,得到可执行程序(elf文件):arm-none-eabi-ld -Ttext 0x80000000 led.o -o led.elf
把elf文件去掉冗余的段和elf头,得到纯净的bin文件:arm-none-eabi-objcopy -O binary led.elf led.bin
给bin文件添加6ull特殊的头部信息(IVT+boot data+DCD),并烧录到SD卡:./mkimage.sh led.bin
devices/MCIMX6Y2/MCIMX6Y2.h:记录外设寄存器及其相关操作
//需添加
#include
#include "system_MCIMX6Y2.h"
#define __O volatile
#define __IO volatile
#define __I volatile const
#define uint32_t unsigned int
#define uint16_t unsigned short
#define uint8_t unsigned char
devices/MCIMX6Y2/drivers/fsl_iomuxc.h:记录引脚复用及其相关操作
bss段清零
初始化栈指针(sp)
http://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html mono/ld.html
SECTIONS{
.=XXX //链接起始地址
.段名
{
xxx
*(.段名)
}
...
}
兼容.s汇编文件
添加编译程序命令
添加sd卡烧录命令