ARM汇编指令学习---基于启动文件startup.S分析

本文主要是基于启动文件startup.s对ARM汇编指令进行学习分析。

以 . 开头一般是伪汇编/操作指令,形如:
.section伪操作来定义一个段,形如:
.section .testsection //定义一个testsection段
汇编系统预定义了一些段名:
.text:代码段
.data:初始化数据段
.bss:未初始化的数据段
.rodata:只读数据段

.global:定义一个全局符号,通常是为ld使用。例子如下:

.global _start
_start:  //_start符号,汇编器在翻译汇编程序时会计算每个数据对象和每条指令的地址,当看到这样一个符号定义时,就把它后面一条指令的地址作为这个符号所代表的地址
ldr r0, =0x12 @r0=0x12
//.global 是伪操作,表示_start 是一个全局标号且是一个符号(Symbol),符号在汇编程序中代表一个地址,可以用在指令中,汇编程序经过汇编器的处理之后,所有的符号都被替换成它所代表的地址值

注:" : "前的为标号
常见的伪操作:

.byte 定义单字节数据,比如.byte 0x12.short 定义双字节数据,比如.short 0x1234.long 定义一个 4 字节数据,比如.long 0x12345678.equ 赋值语句,格式为:.equ 变量名,表达式,比如.equ num, 0x12,表示 num=0x12//相当于#define num 0x12
.align 数据字节对齐,比如:.align 4 表示 4 字节对齐。
.end 表示源文件结束。
.global 定义一个全局符号,格式为:.global symbol,比如:.global _start。
.if ... .else ... .endif 条件预编译
.abort 停止汇编
.include 指定的头文件, 可以把一个汇编常量定义放在头文件中,比如:.include "file"

注:伪汇编指令不是真正的指令,并没有与之对应的的机器码,不会被执行。伪指令所起的作用主要是对汇编过程进行控制,只用于汇编过程中为汇编程序提供汇编信息。

常用伪操作指令
AREA
AREA伪操作用于定义一个段,该段从此开始,到下一个AREA结束。
AREA伪指令用于定义一个代码段或数据段。其中,段名若以数字开头,则该段名需用“|”括起来,如:|1_test|

示例1:AREA ConstData, DATA, READONLY
含义:ConstData作为段名表示这个是常量段,但实际上没什么意义,叫什么都行。DATA和READONLY是段的属性,前者表示该区域为数据,后者表示该区域仅可读(常量)
示例2:AREA StaticData, DATA, READWRITE
含义:READWRITE属性表示该区域可读可写
示例3:AREA text, CODE, READONLY
含义:用于放置各种函数
示例4:AREA STACK, NOINIT, READWRITE, ALIGN=3 
含义:堆栈段,未初始化,允许读写,8字节边界对齐

SPACE
伪指令用于分配一片连续的存储区域并初始化为0 。其中,表达式为要分配的字节数。
DataSpace SPACE 100 //分配连续100字节的存储单元并初始化为0
SPACE Stack //分配栈空间
SPACE Heap //分配堆空间

__initial_sp
标号,代表堆栈顶部地址

ALIGN
ALIGN 4
ALIGN 4用于使当前位置按4字节对齐,使该文件存储在设备中时按4字节对齐,便于CPU快速访问AREA Init ,CODE ,READONLY ,ALIEN=3 ;指定后面的指令为8 字节对齐。
指令序列 //8字节对齐
END

END
用于通知编译器已经到了源程序的结尾
AREA Init ,CODE ,READONLY
……
END ;指定应用程序的结尾

PRESERVE8
伪操作用于指定当前文件保存数据至堆栈时按八字节对齐

THUMB
用于指示编译器该文件使用Thumb指令集

EQU
格式:EQU 表达式 { ,类型 }
Stack EQU 0x00002000 //定义栈的大小,相当于#define stack 0x00002000
Heap EQU 0x00000000 //定义堆的大小
Addr EQU 0x55 ,CODE32 ; 定义Addr的值为0x55 ,且该处为32位的ARM指令

EXPORT/GLOBAL
EXPORT 标号{[WEAK]}
EXPORT __Vectors
EXPORT:在程序中声明一个全局的标号__Vectors,该标号可在其他的文件中引用
EXPORT 命令声明一个符号,可由链接器用于解释各个目标和库文件中的符号引用,相当于声明了一个全局变量。

IMPORT
IMPORT 标号{[WEAK]}
声明标号来自外部文件,跟 C 语言中的 EXTERN 关键字类似
IMPORT uart0_interrupt //引入UART0中断
IMPORT tick_interrupt //引入systick中断

EXTERN
EXTERN 标号{[WEAK]}
类似IMPORT,但后续未应用则不将其加入到当前源文件的符号表
注:IMPORT和EXTERN区别是:IMPORT指示的标号均会被加入到当前源文件的符号表中,而EXTERN指定的标号不将其加入到当前源文件的符号表

ENTRY
ENTRY伪指令用于指定汇编程序的入口点。在一个完整的汇编程序中至少要有一个ENTRY,当有多个ENTRY时,程序的真正入口点由链 接器指定,但在一个源文件里最多只能有一个ENTRY(可以没有)。
AREA Init ,CODE ,READONLY
ENTRY ; 指定应用程序的入口点

DCD
以字为单位分配一片连续的字存储单元并用指定的表达式初始化,分配的字存储单元是以字对齐。

PROC
定义子程序,与 ENDP 成对使用,表示子程序结束

WEAK
弱定义,如果外部文件声明了一个标号,则优先使用外部文件定义的标号,如果外部文件没有定义也不出错。

CODE16\CODE32
指示汇编器将后面的指令解释为16位的Thumb指令或32位的ARM指令

RN
格式:名称 RN 表达式
给寄存器定义一个别名,方便记忆该寄存器的功能
Temp RN R0 ;这之后可以通过别名Temp使用寄存器R0

GET/INCLUDE
将一个源文件(.s)包含到当前的源文件中,并将被包含的源文件在当前位置进行汇编处理。可以使用 INCLUDE代替GET
GET 文件名

你可能感兴趣的:(c/c++基础编程知识,开发语言)