目录
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卡烧录命令