ARM GUN基本语法

来源:互联网 发布:ips显示器知乎 编辑:程序博客网 时间:2024/05/01 20:33

GUN注释以“@”开始,或者“/* ……*/”
1.常量定义伪操作.equ或.set
语法格式:
.equ  symbol, expr
.set  symbol, expr
其中:
symbol 为要指定的名称,它可以是以前定义过的符号;
expr 表示数字常量或程序中的标号。

2.常量定义伪操作.equiv
语法格式:
.equiv  symbol, expr
其中:
symbol 为要指定的名称,它不可以是以前定义过的符号;
expr 表示数字常量或程序中的标号。

3.声明全局常量伪操作.global或.globl
语法格式:
.global  symbol
.globl  symbol
其中:
symbol 为要声明的全局变量名称

4.声明外部变量伪操作.extern
语法格式:
.extern  symbol
其中:
 symbol 为要声明的外部变量名称

实现在当前的程序中使用一个在其它文件中声明的外部变量MAIN,可以使用以下语句进行声明:
.extern  MAIN

5.字节定义.byte
语法格式:
.byte  expr {, expr }…
其中:
expr  数字表达式或程序中的标号。

分配一段字节内存单元,并用25, 0x11, 031, ‘x’,0x36进行初始化。
.byte  25, 0x11, 031, ‘x’,0x36

6.半字定义.hword或.short
语法格式:
.hword  expr {, expr }….
.short  expr {, expr }…
其中:
expr  数字表达式或程序中的标号。

分配一段半字内存单元,并用12, 0xFFE0,0xAABB进行初始化。
.hword  12, 0xFFE0,0xAABB
也可以用.short来定义:
.short  12, 0xFFE0,0xAABB

7.字定义.word或.int或.long
语法格式:
.word  expr {, expr }….
.int  expr {, expr }…
.long  expr {, expr }…
其中:
expr  数字表达式或程序中的标号。

8.字符串定义.ascii和.asciz或.string
语法格式:
.ascii expr {, expr }…
.asciz  expr {, expr }…
.string  expr {, expr }…
其中:
expr  表示字符串。

9.双字定义.quad
语法格式:
.quad  expr {, expr }…
其中:
expr  数字表达式。
10.四字定义.octa 
语法格式:
.octa  expr {, expr }…
其中:
expr  数字表达式。

11.单精度浮点数定义.float或.single
语法格式:
.float  expr {, expr }….
.single  expr {, expr }….
其中:
expr  为32位的 IEEE 单精度浮点数。

12.双精度浮点数定义.double
语法格式:
.double  expr {, expr }…
其中:
expr  为32位的 IEEE 单精度浮点数

13.重复内存单元定义.fill
语法格式:
.fill  repeat {, size}{, value}
其中:
repeat 重复填充的次数;
size  每次所填充的字节数;
value 所填充的数据。

14.声明数据缓冲池.ltorg
语法格式
 .ltorg

声明一个数据缓冲池用来存储0xAABBCCDD
LDR R0, = 0xAABBCCDD
EOR R1, R1, R0
B  SUB_pro
.ltorg    @此处定义数据缓冲池,存放0xAABBCCDD

 

段起始声明伪操作
具体的语法格式如下:
.text
.data
.bss

1.条件编译伪操作.if
语法格式:
.if logical_expression
程序代码段A 
{.else
程序代码段B

.endif

2. 宏定义伪操作.macro
语法格式:
.macro
{ macroname {parameter{,parameter}…}
程序代码段
.endm其中: 

3.文件包含伪操作.include
.include伪操作用于将一个源文件包含到当前的源文件中,所包含的文件在.include指令的位置处进行汇编处理。
语法格式:
.include  "file_name"

 

                                                   ARM汇编语言源程序的基本结构

.global _start  /*GNU格式汇编*/
.text
.equ num,20   /*设置将要复制的字数*/
_start: LDR r0,=src /*r0寄存器指向源数据区src*/
       LDR r1,=dst  /*r1寄存器指向目标数据区dst*/
       MOV r2,#num   /*指定将要复制的字数*/
       MOV sp,#0x31000000 /*设置数据栈指针(r13),用于保存工作寄存器数值*/
blockcopy: MOVS r3,r2,LSR #3 /*需要进行的以8个字为单位的复制次 数BEQ copywords 对于剩下不足8个字的数据,跳转到 
                                                         copywords,以字为单位复制*/
       STMFD sp!,{r4-r11} /*保存工作寄存器,压栈*/

octcopy:   LDMIA r0!,{r4-r11} /*从源数据区读取8个字的数*/
                                                  /*据,放到8个寄存器中,并更新目标数据区指针r0*/
       STMIA r1!,{r4-r11} /*将这8个字数据写入到目标数*/ 
                                        /*据区中,并更新目标数据区指针r1*/
       SUBS r3,r3,#1  /*将块复制次数减1*/
       BNE octcopy /*循环,直到完成以8个字为单位的块复制*/      LDMFD sp!,{r4-r11} /*恢复工作寄存器值,出栈*/
copywords: ANDS r2,r2,#7 /*剩下不足8个字的数据的字数*/       BEQ stop /*数据复制完成*/

wordcopy: LDR r3,[r0],#4 /*从源数据区读取1个字的数据,*/
                                            /*放到r3寄存器中,并更新目标数据区指针r0,后索引偏移*/
      STR r3,[r1],#4 /*将这r3中数据写入到目标数据区中*/
                               /*并更新目标数据区指针r1,后索引偏移*/
       SUBS r2,r2,#1 /*将字数减1*/
       BNE wordcopy /*循环,直到完成以字为单位的数据复制*/

stop:  B stop
   
.ltorg /*声明文字池,可以通过ldr指令读取里面的内容*/
src:   
 .LONG 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4
/*定义源数据区src及目标数据区dst*/
dst:
 .LONG 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.end

原创粉丝点击