织梦CMS - 轻松建站从此开始!

罗索实验室

当前位置: 主页 > 基础技术 > C/CPP专题 >

ARM汇编伪指令

落鹤生 发布于 1970-01-01 08:00 点击:次 
在ARM汇编语言程序里,有一些特殊指令助记符,这些助记符与指令系统的助记符不同,没有相对应的操作码,通常称这些特殊指令助记符为伪指令,他们所完成 的操作称为伪操作。伪指令在源程序中的作用是为完成汇编程序作各种准备工作的,这些伪指令仅在汇编过程中起作用,一
TAG:

在ARM汇编语言程序里,有一些特殊指令助记符,这些助记符与指令系统的助记符不同,没有相对应的操作码,通常称这些特殊指令助记符为伪指令,他们所完成 的操作称为伪操作。伪指令在源程序中的作用是为完成汇编程序作各种准备工作的,这些伪指令仅在汇编过程中起作用,一旦汇编结束,伪指令的使命就完 成。     
       在ARM 的汇编程序中,有如下几种伪指令:8a4ab69fd5343e39fbd0019fcf4585cd、数据定义伪指令汇编控制伪指令宏指令以及其他伪指令

一、符号定义(Symbol Definition)伪指令    
符号定义伪指令用于定义ARM 汇编程序中的变量、对变量赋值以及定义寄存器的别名等操作。    
常见的符号定义伪指令有如下几种:   
    — 用于定义全局变量的GBLA 、GBLL 和GBLS 。   
    — 用于定义局部变量的LCLA 、LCLL 和LCLS 。   
    — 用于对变量赋值的SETA 、SETL 、SETS 。   
    — 为通用寄存器列表定义名称的RLIST 。    
1、GBLA、GBLL 和GBLS   
    语法格式:   
    GBLA (GBLL 或GBLS )全局变量名   
    GBLA 、GBLL 和GBLS 伪指令用于定义一个ARM 程序中的全局变量,并将其初始化。其中:   
    GBLA 伪指令用于定义一个全局的数字变量,并初始化为0 ;   
    GBLL 伪指令用于定义一个全局的逻辑变量,并初始化为F(假);   
    GBLS 伪指令用于定义一个全局的字符串变量,并初始化为空;   
    由于以上三条伪指令用于定义全局变量,因此在整个程序范围内变量名必须唯一。   
    使用示例:   
    GBLA Test1 ;           定义一个全局的数字变量,变量名为Test1。   
    Test1 SETA 0xaa ;   将该变量赋值为0xaa。   
    GBLL Test2 ;            定义一个全局的逻辑变量,变量名为Test2。   
    Test2 SETL {TRUE} ;将该变量赋值为真。   
    GBLS Test3 ;             定义一个全局的字符串变量,变量名为Test3。   
    Test3 SETS “Testing” ;将该变量赋值为"Testing”。  

2、LCLA、LCLL 和LCLS   
    语法格式:   
    LCLA (LCLL 或 LCLS )局部变量名   
    LCLA 、LCLL 和LCLS 伪指令用于定义一个ARM 程序中的局部变量,并将其初始化。其中:   
    LCLA伪指令用于定义一个局部的数字变量,并初始化为0 ;   
    LCLL伪指令用于定义一个局部的逻辑变量,并初始化为F(假);   
    LCLS伪指令用于定义一个局部的字符串变量,并初始化为空;   
    以上三条伪指令用于声明局部变量,在其作用范围内变量名必须唯一。   
    使用示例:   
    LCLA Test4 ;            声明一个局部的数字变量,变量名为Test4。  
    Test3 SETA 0xaa ;   将该变量赋值为0xaa。   
    LCLL Test5 ;             声明一个局部的逻辑变量,变量名为Test5。   
    Test4 SETL {TRUE} ;将该变量赋值为真。   
    LCLS Test6 ;             定义一个局部的字符串变量,变量名为Test6。   
    Test6 SETS “Testing” ;将该变量赋值为 "Testing”。   

3、SETA、SETL 和SETS   
    语法格式:   
    变量名 SETA (SETL 或 SETS )表达式   
    伪指令 SETA 、SETL 、SETS 用于给一个已经定义的全局变量或局部变量赋值。   
    SETA伪指令用于给一个数学变量赋值;   
    SETL伪指令用于给一个逻辑变量赋值;   
    SETS伪指令用于给一个字符串变量赋值;   
    其中,变量名为已经定义过的全局变量或局部变量,表达式为将要赋给变量的值。   
    使用示例:   
    LCLA Test3 ;             声明一个局部的数字变量,变量名为Test3。   
    Test3 SETA 0xaa ;    将该变量赋值为0xaa。   
    LCLL Test4 ;             声明一个局部的逻辑变量,变量名为Test4。   
    Test4 SETL {TRUE} ;将该变量赋值为真。   

4 、RLIST   
    语法格式:   
    名称 RLIST { 寄存器列表 }   
    RLIST伪指令可用于对一个通用寄存器列表定义名称,使用该伪指令定义的名称可在ARM 指令 LDM/STM中使用。在LDM/STM指令中,列表中的寄存器访问次序为根据寄存器的编号由低到高,而与列表中的寄存器排列次序无关。   
    使用示例:   
    RegList RLIST {R0-R5 ,R8 ,R10} ;将寄存器列表名称定义为RegList ,可在ARM指令LDM/STM中通过该名称访问寄存器列表。   

二、数据定义(Data Definition)伪指令    
数据定义伪指令一般用于为特定的数据分配存储单元,同时可完成已分配存储单元的初始化。    
常见的数据定义伪指令有如下几种:   
    — DCB 用于分配一片连续的字节存储单元并用指定的数据初始化。   
    — DCW(DCWU)用于分配一片连续的半字存储单元并用指定的数据初始化。   
    — DCD (DCDU)用于分配一片连续的字存储单元并用指定的数据初始化。   
    — DCFD(DCFDU)用于为双精度的浮点数分配一片连续的字存储单元并用指定的数据初始化。   
    — DCFS(DCFSU)用于为单精度的浮点数分配一片连续的字存储单元并用指定的数据初始化。   
    — DCQ(DCQU)用于分配一片以8字节为单位的连续的存储单元并用指定的数据初始化。   
    — SPACE 用于分配一片连续的存储单元。   
    — MAP 用于定义一个结构化的内存表首地址。   
    — FIELD 用于定义一个结构化的内存表的数据域。   
1、DCB   
    语法格式:   
    标号 DCB 表达式   
    DCB伪指令用于分配一片连续的字节存储单元并用伪指令中指定的表达式初始化。其中,表达式可以为0~255的数字或字符串。DCB 也可用“=”代替。   
    使用示例:   
    Str DCB “This is a test” ;分配一片连续的字节存储单元并初始化。
   
2、DCW(或DCWU)   
    语法格式:
    标号 DCW (或DCWU) 表达式   
    DCW(或DCWU)伪指令用于分配一片连续的半字存储单元并用伪指令中指定的表达式初始化。   
    其中,表达式可以为程序标号或数字表达式。  
    用DCW分配的字存储单元是半字对齐的,而用DCWU分配的字存储单元并不严格半字对齐。   
    使用示例:   
    DataTest DCW 1 ,2 ,3 ;分配一片连续的半字存储单元并初始化。    

3、DCD(或DCDU)   
    语法格式:   
    标号 DCD(或DCDU) 表达式   
    DCD(或DCDU)伪指令用于分配一片连续的字存储单元并用伪指令中指定的表达式初始化。其中,表达式可以为程序标号或数字表达式。DCD也可用"&” 代替。   
    用DCD分配的字存储单元是字对齐的,而用DCDU分配的字存储单元并不严格字对齐。   
    使用示例:   
    DataTest DCD 4 ,5 ,6 ;分配一片连续的字存储单元并初始化。
   
4、DCFD(或DCFDU)   
    语法格式:   
    标号 DCFD(或DCFDU) 表达式   
    DCFD(或DCFDU)伪指令用于为双精度的浮点数分配一片连续的字存储单元并用伪指令中指定的表达式初始化。每个双精度的浮点数占据两个字单元。用DCFD分配的字存储单元是字对齐的,而用DCFDU分配的字存储单元并不严格字对齐。   
    使用示例:   
    FDataTest DCFD 2E115 ,-5E7 ;分配一片连续的字存储单元并初始化为指定的双精度数。    

5、DCFS(或DCFSU)   
    语法格式:   
    标号 DCFS(或DCFSU) 表达式   
    DCFS(或DCFSU)伪指令用于为单精度的浮点数分配一片连续的字存储单元并用伪指令中指定的表达式初始化。每个单精度的浮点数占据一个字单元。用DCFS分配的字存储单元是字对齐的,而用DCFSU分配的字存储单元并不严格字对齐。   
    使用示例:   
    FDataTest DCFS 2E5 ,-5E -7 ;分配一片连续的字存储单元并初始化为指定的单精度数。    

6、DCQ(或DCQU)   
    语法格式:   
    标号 DCQ(或DCQU) 表达式   
    DCQ(或DCQU)伪指令用于分配一片以8个字节(双字)为单位的连续存储区域并用伪指令中指定的表达式初始化。 用DCQ分配的存储单元是字对齐的,而用DCQU 分配的存储单元并不严格字对齐。   
    使用示例:   
    DataTest DCQ 100 ;分配一片连续的存储单元并初始化为指定的值。
   
7、SPACE   
    语法格式:   
    标号 SPACE 表达式   
    SPACE伪指令用于分配一片连续的存储区域并初始化为0 。其中,表达式为要分配的字节数。   
    SPACE也可用“ ”代替。   
    使用示例:   
    DataSpace SPACE 100 ;分配连续100字节的存储单元并初始化为0 。    

8、MAP   
    语法格式:   
    MAP 表达式 { ,基址寄存器 }   
    MAP伪指令用于定义一个结构化的内存表的首地址。MAP也可用“”代替。   
    表达式可以为程序中的标号或数学表达式,基址寄存器为可选项,当基址寄存器选项不存在时,表达式的值即为内存表的首地址,当该选项存在时,内存表的首地址为表达式的值与基址寄存器的和。   
    MAP伪指令通常与FIELD伪指令配合使用来定义结构化的内存表。   
    使用示例:   
    MAP 0x100 ,R0 ;定义结构化内存表首地址的值为0x100+R0 。
   
9、FILED   
    语法格式:   
    标号 FIELD 表达式   
    FIELD伪指令用于定义一个结构化内存表中的数据域。FILED 也可用“#”代替。   
    表达式的值为当前数据域在内存表中所占的字节数。   
    FIELD伪指令常与MAP伪指令配合使用来定义结构化的内存表。MAP伪指令定义内存表的首地址,FIELD伪指令定义内存表中的各个数据域,并可以为每个数据域指定一个标号供其他的指令引用。   
    注意MAP和FIELD伪指令仅用于定义数据结构,并不实际分配存储单元。   
    使用示例:   
    MAP 0x100 ; 定义结构化内存表首地址的值为0x100。   
    A FIELD 16 ; 定义A的长度为16字节,位置为0x100。   
    B FIELD 32 ; 定义B的长度为32字节,位置为0x110。   
    S FIELD 256 ;定义S的长度为256字节,位置为0x130。   

三、汇编控制(Assembly Control)伪指令    
汇编控制伪指令用于控制汇编程序的执行流程,常用的汇编控制伪指令包括以下几条:   
    — IF 、ELSE 、ENDIF   
    — WHILE 、WEND   
    — MACRO 、MEND   
    — MEXIT
1、IF、ELSE、ENDIF   
    语法格式:   
    IF 逻辑表达式   
    指令序列 1   
    ELSE   
    指令序列 2   
    ENDIF   
    IF 、ELSE 、ENDIF伪指令能根据条件的成立与否决定是否执行某个指令序列。当IF后面的逻辑表达式为真,则执行指令序列1 ,否则执行指令序列2 。其中,ELSE及指令序列2可以没有,此时,当IF后面的逻辑表达式为真,则执行指令序列1 ,否则继续执行后面的指令。   
    IF 、ELSE 、ENDIF伪指令可以嵌套使用。   
    使用示例:   
    GBLL Test ;声明一个全局的逻辑变量,变量名为Test   
    IF Test = TRUE   
    指令序列 1   
    ELSE   
    指令序列 2   
    ENDIF    

2、WHILE、WEND   
    语法格式:   
    WHILE 逻辑表达式   
    指令序列   
    WEND   
    WHILE 、WEND伪指令能根据条件的成立与否决定是否循环执行某个指令序列。当WHILE后面的逻辑表达式为真,则执行指令序列,该指令序列执行完毕后,再判断逻辑表达式的值,若为真则继续执行,一直到逻辑表达式的值为假。   
    WHILE 、WEND伪指令可以嵌套使用。   
    使用示例:   
    GBLA Counter ;   声明一个全局的数学变量,变量名为Counter   
    Counter SETA 3 ;由变量Counter 控制循环次数   
    ……   
    WHILE Counter < 10   
    指令序列   
    WEND    

3、MACRO、MEND   
    语法格式:   
    $ 标号 宏名 $ 参数 1 ,$ 参数 2 ,……   
    指令序列   
    MEND   
    MACRO 、MEND伪指令可以将一段代码定义为一个整体,称为宏指令,然后就可以在程序中通过宏指令多次调用该段代码。其中,$标号在宏指令被展开时,标号会被替 换为用户定义的符号,宏指令可以使用一个或多个参数,当宏指令被展开时,这些参数被相应的值替换。   
    宏指令的使用方式和功能与子程序有些相似,子程序可以提供模块化的程序设计、节省存储空间并提高运行速度。但在使用子程序结构时需要保护现场,从而增加了系统的开销,因此,在代码较短且需要传递的参数较多时,可以使用宏指令代替子程序。   
    包含在MACRO和MEND之间的指令序列称为宏定义体,在宏定义体的第一行应声明宏的原型(包含宏名、所需的参数),然后就可以在汇编程序中通过宏名来 调用该指令序列。在源程序被编译时,汇编器将宏调用展开,用宏定义中的指令序列代替程序中的宏调用,并将实际参数的值传递给宏定义中的形式参数。   
    MACRO、MEND伪指令可以嵌套使用。   

4、MEXIT   
    语法格式:   
    MEXIT   
    MEXIT用于从宏定义中跳转出去。  

四、其他常用的伪指令    
还有一些其他的伪指令,在汇编程序中经常会被使用,包括以下几条:    
    — AREA
    — ALIGN   
    — CODE16 、CODE32   
    — ENTRY   
    — END   
    — EQU   
    — EXPORT (秩名)

本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net]
本文出处:dzkf 作者:秩名 原文
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容