嵌入式系统开发学习:20-1 ARM汇编程序设计

目标:

学习掌握ARM公司开发工具支持的汇编程序设计语法,规则。

ARM汇编程序设计:

ARM汇编程序设计语法与汇编器有一定关系,不同的汇编工具语法会略有不同,比如ARM公司的开发工具和GNU的gcc for ARM汇编语法略有不同,但指令集方面还是一致的。

采用汇编语言编程缺点有:

1、 汇编语法不通用,代码移植性差

2、 编码效率低下

那为什么还需要汇编编程呢?

1、 有些功能只有使用汇编实现:比如关闭中断、开启中断、修改状体寄存器,部分CPU的初始化代码,异常处理程序等等

2、 可以使用汇编优化代码的效率,当然是你水平很高的情况下,否则你写代码不一定比编译器产生的代码效率高。

3、 掌握汇编编程对某些高级语言特性理解会更加深刻,比如大家都知道 C语言局部变量在栈上,如果没学过汇编也只能记住,反之如果学习了汇编的压栈,出栈指令,对栈进行过操作,使用栈传递过参数(数据)等,就会对局部变量在栈上理解更深刻。当然了不会汇编一样可以做软件开发。

ARM汇编编程语法:

1、 汇编语言编程,汇编源码文件通常以 .s或者 .asm结尾,ARM汇编以.s或者.S结尾。头文件一般以 .inc结尾,也可以.h结尾。

2、 汇编源文件和C语言类似,都是以行为单位,每行结构如下:

{;comment}

label:可选,标号,表示代码或者数据的起始位置,标号顶个写,前面不能有空格。

:可选,ARM指令、伪操作、伪指令三者中的一种,同时使用一种,三选一。

;comment:可选,注释。

代码示例如下:

其中:

1、 AREA、ENTRY、END属于ARM汇编伪操作。

2、 start,stop属于标号

3、 mov、add、b是ARM指令

4、 每行一条语句

5、 指令,伪指令,伪操作不能顶个写

6、 一行代码太长可以使用 \ 续行

7、 指令、伪指令、伪操作寄存器名可以大写,也可以小写,但不能大小写混写

ARM汇编标号命名:

标号分为全局标号和局部标号,局部标号只在某段范围内起作用。

1、 标号命名可以由字母、数字、下划线构成。

2、 除了局部标号外,不能由数字开头。

3、 区分大小写(大小写敏感)。

4、 除局部标号外,在其作用范围内,必须唯一。

ARM汇编寄存器命名:

ARM汇编伪操作:

ARM汇编工具支持的汇编伪操作包括符号定义伪操作、数据定义伪操作、汇编信息报告控制伪操作、汇编代码控制伪操作、文件包含伪操作、指令集类型标识伪操作以及其他功能伪操作等。

段定义伪操作:

段定义属性(attr):

段定义伪操作示例:

ARM指令集选择伪操作:

代码示例:

AREA Init,CODE,READONLY

……

CODE32 ;告诉编译器其后为32位的ARM指令

LDR R0,=NEXT+1 ;将跳转地址放入寄存器R0

BX R0 ;跳转并切换到Thumb工作状态

……

CODE16 ;告诉编译器其后为16位的Thumb指令

NEXT LDR R3,=0x3FF

……

END ;程序结束

END伪操作:

表示源文件结束,文件中END后面的内容不会被汇编器汇编。

ENTRY指定程序入口点伪操作:

通常用于指定程序入口起始地址,链接调试时会用到,不用ENTRY用其他方法也可以达到该效果。

全局标号声明伪操作:

示例:

AREA Init,CODE,READONLY

EXPORT Stest

Stest

MOV R0,R1

……

END

标号导出EXPORTAS伪指令:

标号导入/外部标号引用伪指令:

ARM变量定义伪操作:

ARM中变量是指其值在程序的运行过程中可以改变的量。ARM/Thumb汇编程序所支持的变量有三种。

变量赋值伪操作:

变量定义赋值代码示例:

GBLA TestA ;声明一个局部的数字变量 TestA

TestA SETA 0xaa ;将该变量赋值为0xaa

GBLL TestL ;声明一个局部的逻辑变量 TestL

TestL SETL ;将该变量赋值为真

GBLS TestS ;定义一个局部的字符串变量TestS

TestS SETS “Testing” ;将该变量赋值为"Testing"

GBLA objectsize

objectsize SETA oxff

SPACE objectsize

编译时的变量替换:

变量替换代码示例:

; straightforward substitution

GBLS add4ff

;

add4ff SETS "ADD r4,r4,#0xFF" ; set up add4ff

$add4ff.00 ; invoke add4ff

; this produces

ADD r4,r4,#0xFF00

; elaborate substitution

GBLS s1

GBLS s2

GBLS fixup

GBLA count

;

count SETA 14

s1 SETS "a$$b$count" ; s1 now has value a$b0000000E

s2 SETS "abc"

fixup SETS "|xy$s2.z|" ; fixup now has value |xyabcz|

|C$$code| MOV r4,#16 ; but the label here is C$$code

ARM中的常量:

代码示例:

Str DCB “This is a test!”;结尾没有NULL

C_string DCB "C_string",0

Num DCB 1,2,3,4,5

AREA Mydata, DATA,READWRITE

DCB 255 ;字节定义使内存单元不能字对齐

Data3 DCDU 1,5,20 ;

内建变量使用示例:

IF = "4T“

IF = 32

IF

IF

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180204A0PU2O00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励