【ARM 裸机】汇编 led 驱动之基本语法

我们要编写的是 ARM 汇编,编译使用的是 gcc 交叉编译器,所以要符合 GNU 语法。

1、汇编指令

汇编由一条条指令构成,ARM 不能直接访问存储器,比如 RAM 中的数据,I.MX6UL 中的寄存器就是 RAM 类型的,我们用汇编来配置 I.MX6UL 寄存器的时候需要借助存储器访问指令,一般先将要配置的值写入到 Rx(x=0~12)寄存器中,然后借助存储器访问指令将 Rx 中的数据写入到 I.MX6UL 寄存器,读取 I.MX6UL 寄存器也是一样的,只是过程相反。

常用的存储器访问指令有两种:LDR 和 STR

LDR 指令

c 复制代码
LDR Rd, [Rn , #offset]  从存储器 Rn+offset 的位置读取数据存放到 Rd 中

LDR 主要用于从存储加载数据到寄存器 Rx 中,LDR 也可以将一个立即数加载到寄存器 Rx 中,LDR 加载立即数的时候要使用"=",而不是"#"。在嵌入式开发中,LDR 最常用的就是读取 CPU 的寄存器值,比如 I.MX6UL 有个寄存器 GPIO1_GDIR,其地址为 0X0209C004,我们现在要读取这个寄存器中的数据,示例代码如下;

c 复制代码
LDR R0, =0X0209C004     将寄存器地址 0X0209C004 加载到 R0 中,即 R0=0X0209C004
LDR R1, [R0]            读取地址 0X0209C004 中的数据到 R1 寄存器中

上述代码就是读取寄存器 GPIO1_GDIR 中的值,读取到的寄存器值保存在 R1 寄存器中,上面代码中 offset 是 0,也就是没有用到 offset 。

STR 指令

c 复制代码
STR Rd, [Rn, #offset]   将 Rd 中的数据写入到存储器中的 Rn+offset 位置

LDR 是从存储器读取数据,STR 就是将数据写入到存储器中,以 I.MX6UL 寄存器GPIO1_GDIR 为例,现在我们要配置寄存器 GPIO1_GDIR 的值为 0X20000002,示例代码如下;

c 复制代码
LDR R0, =0X0209C004     将寄存器地址 0X0209C004 加载到 R0 中,即 R0=0X0209C004
LDR R1, =0X20000002     R1 保存要写入到寄存器的值,即 R1=0X20000002
STR R1, [R0]            将 R1 中的值写入到 R0 中所保存的地址中

LDR 和 STR 都是按照字进行读取和写入的,也就是操作的 32 位数据,如果要按照字节、半字进行操作的话可以在指令"LDR"后面加上 B 或 H,比如按字节操作的指令就是 LDRB 和 STRB,按半字操作的指令就是 LDRH 和 STRH 。

其他指令比如处理器内部数据传输指令(MOV、MRS、MSR等)、压栈和出栈指令(PUSH、POP)、跳转指令(B、BL等)、算数运算指令(ADD、ADC、SUB、SBC、MUL、UDIV、SDIV等)、逻辑运算指令(AND、ORR等)等不一一列举了。

2、LDR、STR 为什么用的是 R0、R1

这就涉及到 Cortex-A 寄存器组了,首先 Cortex-A7 处理器有 9 种处理模式如下图;

ARM 架构提供了 16 个 32 位的通用寄存器(R0 ~ R15)供软件使用,前 15 个(R0~R14)可以用作通用的数据存储,R15 是程序计数器 PC,用来保存将要执行的指令。ARM 还提供了一个当前程序状态寄存器 CPSR 和一个备份程序状态寄存器 SPSR,SPSR 寄存器就是 CPSR 寄存器的备份。

每一种模式可见的寄存器包括 15 个通用寄存器(R0~R14)、一两个程序状态寄存器和一个程序计数器 PC。在这些寄存器中,有些是所有模式所共用的同一个物理寄存器,有一些是各模式自己所独立拥有的。

因为 ARM 指令不能直接读取 RAM 中的数据,必须借助内部的寄存器来完成数据的读取,所以使用 R0、R1、R2等通用寄存器都是可以的。

相关推荐
CodingCos34 分钟前
【ARM 嵌入式 编译系列 10.4.2 -- 查看 bss 段中有哪些内容】
arm开发·gcc bss·bss 段
一叶知秋h38 分钟前
Ubuntu系统的安装参考链接汇总
linux·ubuntu
fictionist39 分钟前
正则表达式篇
linux·运维·服务器·数据库·mysql·正则表达式·c#
孙克旭_44 分钟前
day019-特殊符号、正则表达式与三剑客
linux·运维·正则表达式
Unique2761 小时前
Linux条件变量
linux·开发语言
学习编程的gas1 小时前
Linux基本指令(二)
linux·运维·服务器
阳光九叶草LXGZXJ2 小时前
达梦数据库-学习-21-C 外部函数
linux·运维·c语言·开发语言·数据库·sql·学习
shadowcz0072 小时前
Live Search API :给大模型装了一个“实时搜索引擎”的插件
linux·服务器·前端·数据库·搜索引擎
一个小白5553 小时前
nginx 的反向代理 负载均衡 动静分离 重写
linux·运维·前端·nginx·centos·firefox
0xCC说逆向3 小时前
Windows逆向工程提升之IMAGE_IMPORT_DESCRIPTOR
c语言·汇编·windows·安全·逆向·pe结构