[004] [ARM

您所在的位置:网站首页 arm使用的是哪种指令集成的程序语言 [004] [ARM

[004] [ARM

2024-07-17 08:59| 来源: 网络整理| 查看: 265

ARM Contents ARM汇编语言基础· 基本语法 指令后缀 ARM编译器与GCC·· 译器语法差异 ARM UAL模拟器VisUAL·· 常用指令集 存储器访问指令 数据操作指令 跳转指令 ARM杂项指令 伪指令 CMSIS内核接口函数··

Cortex­M0、Cortex-M0+和Cortex-M1处理器只支持多数16位指令和部分32位指令,Cortex-M3支持的32位指令更多。Cortex-M4处理器支持剩下的SIMD等DSP提升指令集可选的浮点指令。

image-20220312223223876

▲ Cortex-M处理器的指令集 1 ARM汇编语言基础 1.1 基本语法 标号 操作码{cond}{S} 操作数1, 操作数2, … ;注释 标号:可选,必须顶格写,作用是让汇编器计算程序转移的地址(可以是C函数名)cond:可选,即指令执行条件,如果不写则使用默认条件AL(无条件执行)。S:可选,表示指令执行后,会修改PSR寄存器操作码:即指令助记符,前面必须至少有一个空格操作数:第1个操作数一般为本指令的执行结果存储处。形成操作数的有效地址的方法称为操作数的寻址方式,分为: 隐含寻址:不是明显地给出操作数的地址。而是在指令中隐含着操作数的地址立即寻址:立即寻址方式的操作数,即操作数本身即为地址,即立即数,必须以#开头,且立即数不能作为指令中的第一操作数(目的操作数),如:MOV R1, #'A'。(寄存器)直接寻址:在指令中直接给出有效地址,操作数的地址是直接给出的,如:LDR R0, R1,将源寄存器R1的地址加载到目的寄存器R0(寄存器)间接寻址:操作数中存放的值作为其有效地址,此时必须在操作数两端加方括号 [],如:LDR R0, [R1],将源寄存器R1中保存的值加载到目的寄存器R0中(类似C指针)相对寻址:相对当前指令的地址(程序计数器PC中的内容±常量)寄存器偏移寻址:当第2操作数是寄存器偏移方式时,第2个寄存器操作数在与第1个操作数结合之前,选择进行移位操作。如:MOV R0, R2, LSL #3,将R2的左移3位,结果放入R0,即R0 = R2 * 8基址寻址:将基址寄存器的内容与指令中给出的偏移量相加,形成操作数的有效地址,基址寻址用于访问基址附近的存储单元,常用于查表,数组操作,功能部件寄存器访问等。如:LDR R2, [R3,#0x0F]将R3中的值+0x0f作为地址,加载到R2中多寄存器寻址(块拷贝寻址):一次可以传送几个寄存器值。如:LDMIA R1!,{R2-R7,R12},将R1单元中的数据读出到R2-R7,R12,R1自动+1(!);STMIA R0!,{R3-R6,R10};将R3-R6, R10 中的数据保存到R0指向的地址,R0自动+1。(使用多寄存器寻址指令时,寄存器子集的顺序时由小到大的顺序排列,连续的寄存器可用-连接,否则,用,分隔书写。)堆栈寻址:栈操作。 注释:;开头

注意:

立即数不可以是任意数值,必须由一个8位的常数循环移位偶数位得到,如:8位数0xbe左移8位 -> 0x0000 be00。可以使用伪指令操作立即数。绝大多数16位指令只能访问R0-R7;32位Thumb-2指令则可以随意访问R0-R15。 1.2 指令后缀

image-20220307014919667

▲ 指令后缀

具体的条件码为:

image-20220308225519021

▲ 条件码表 对于Thumb指令集,只有转移指令(B指令)才可随意使用。而对于其它指令,CM3引入了IF-THEN指令块,在这个块中才可以加后缀,且必须加以后缀。S后缀可以与条件后缀一起使用。

image-20220308160530841

▲ CPSR寄存器条件标志位

ARM内部寄存器

条件码应用示例:

C代码 if (a > b) a++; else b++; 对应的ARM指令(R0-a, R1-b)

image-20220307214221517

▲ UAL模拟器VisUAL运行结果 1.3 ARM编译器与GCC编译器语法差异

参考:ARM编译器和GNU ARM编译器之间的差异

image-20220307022400986

▲ GUN与ARM汇编器语法差异 armasm即为ARM汇编编译器语法GUN即为GCC汇编编译器语法

ARM 系列目前支持三大主流的工具链,即ARM RealView (armcc), IAR EWARM (iccarm), and GNU Compiler Collection (gcc).

在core_cm3.h中有如下定义:

/* define compiler specific symbols */ \#if defined ( __CC_ARM ) \#define __ASM __asm /*!< asm keyword for armcc */ \#define __INLINE __inline /*!< inline keyword for armcc */ \#elif defined ( __ICCARM__ ) \#define __ASM __asm /*!< asm keyword for iarcc */ \#define __INLINE inline /*!< inline keyword for iarcc. Only avaiable in High optimization mode! */ \#define __nop __no_operation /*!< no operation intrinsic in iarcc */ \#elif defined ( __GNUC__ ) \#define __ASM asm /*!< asm keyword for gcc */ \#define __INLINE inline /*!< inline keyword for gcc \#endif 1.4 ARM UAL模拟器VisUAL

官方手册

1.4.1 内存映射

image-20220307203750724

▲ VisUAL 内存映射

不模拟外设

较低的内存地址是用来保存指令的,因此程序计数器PC从地址0x0处的指令1开始。

执行期间,指令执行内存区域(Instruction Memory Execute Accesss)不可读写,即为ROM。(这是软件的局限,实际ROM区域只读)

指令执行内存区域默认大小0x10000字节,允许模拟16,384行代码

VisUAL 支持两种内存访问模式: Open 和 Strict。

在Open访问模式下,所有数据内存地址都具有读/写访问权限(默认启用)在Strict访问模式下,只有使用 DCD、 DCB 或 FILL 指令定义的明确数据内存地址才具有写访问权,其他地址只有读访问权限。 1.4.2 支持的指令

image-20220307205857683

▲ List of Supported Instructions

在软件中可以鼠标点击指令,然后按ctrl+space查看用法:

image-20220307210122759

▲ VisUAL软件指令帮助

关于指令的限制参考:instructions note

2 常用指令集

指令语法中带有{}的表示可选!

2.1 存储器访问指令 名字功能LDR从存储器中加载(Load)字到一个寄存器(Register)中LDRH从存储器中加载半(Half)字到一个寄存器中LDRB从存储器中加载字节(Byte)到一个寄存器中LDRSH从存储器中加载半字,再经过带符号扩展后存储一个寄存器中LDRSB从存储器中加载字节,再经过带符号扩展后存储一个寄存器中STR把一个寄存器按字存储(Store)到存储器中STRH把一个寄存器存器的低半字存储到存储器中STRB把一个寄存器的低字节存储到存储器中LDMIA加载多个字,并且在加载后自增基址寄存器STMIA存储多个字,并且在存储后自增基址寄存器PUSH压入多个寄存器到栈中POP从栈中弹出多个值到寄存器中

STR&LDR示例:

MOV R0, #0x20000 MOV R1, #0x08 MOV R2, #0x34 STR R2, [R0] ; R2的值存到R0所示地址 STR R2, [R0, #4] ; R2的值存到R0+4所示地址 STR R2, [R0, #8]! ; R2的值存到R0+8所示地址, R0=R0+8 STR R2, [R0, R1] ; R2的值存到R0+R1所示地址 STR R2, [R0, R1, LSL #4] ; R2的值存到R0+(R1


【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3