Linux进阶-ARM_V7架构和ARM常用汇编指令

目录

运行模式

寄存器组

通用寄存器

程序状态寄存器

系统寄存器

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协处理器:内存、缓存、中断等。

ARM常用汇编指令

汇编格式:
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

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

SDK移植

引入SDK头文件

devices/MCIMX6Y2/MCIMX6Y2.h:记录外设寄存器及其相关操作

//需添加
#include <core_ca7.h>
#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:记录引脚复用及其相关操作

准备C语言环境

bss段清零

初始化栈指针(sp)

链接脚本引入:指定链接地址、起始代码在text段的位置,其它段的位置。

http://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html mono/ld.html

SECTIONS{
    .=XXX    //链接起始地址
    .段名
    {
        xxx
        *(.段名)
    }
    ...
}

Makefile修改

兼容.s汇编文件

添加编译程序命令

添加sd卡烧录命令

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值