一、伪指令

  ARM伪指令有四个,分别是LDR、ADR、ADRL和NOP,下边对其分别介绍。

  1.1 LDR

  LDR 伪指令用于加载 32 位的立即数或一个地址值到指定寄存器 。形式如  LDR{cond} register,=[expr | label_expr],与 ARM 指令的 LDR 相比 , 伪指令的 LDR 的参数有“ =” 号 。LDR有三方面的应用:

  (1)用于加载常量,如 LDR R2, =0xFF0 其等同于MOV R2, #0xFF0 但需要注意的是LDR指令加载常量可以是合法的立即数也可以不是,但是MOV加载数时必须为合法的立即数。

  (2)设置GPIO

        GPIO-BASE EQU 0xe0028000
        ...
        LDR R0, =GPIO-BASE
        LDR R1,=0x00ffff00
        STR R1,[R0,#0x0c]

  (3)加载地址

        ...

        LDR R1,=InitStack

        ...

        InitStack

        MOV R0, LR

        ...

  1.2 ADR与ADRL

  两者都是将基于 PC 相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中 。形如 ADR{cond} register,expr 和LDR不同的是,这里没有等号。两者作用类似,区别在于两者可以加载的数的范围不同,当地址值是字节对齐时 , ADRL取值范围为- - 64K ~ 64K,ADR为- 255 ~ 255 。

  1.3 NOP

  空操作指令,就是什么也不干,静等时间流逝。

  1.4 ARM指令与伪指令的区别

  伪指令经过汇编编译后就不存在了,而指令依旧存在。伪操作只是汇编过程中起作用, , 一旦汇编结束, ,伪操作也就随之消失。另外,ARM 伪指令不属于 ARM 指令集中的指令,是为了编程方便而定义的。

  总结:其实LDR、ADRL、ADR的作用和用法基本类似,主要区别是加载数的范围大小不同,LDR加载范围最大,ADRL次之,ADR最小。另外,使用LDR伪指令时,操作数要带“=”号,ADRL和ADR则不需要。

二、伪操作

  伪操作主要有符号定义、数据定义、指令集类型标识和其他类型四种,下边将进行一一介绍。

2.1 符号定义伪操作

  符号定义伪操作用于定义 ARM 汇编程序中的变量、对变量赋值及定义寄存器的别名等操作。常见的符号定义伪操作有如下几种:

  (1)局部变量定义 LCLA 、 LCLL 及 LCLS

  (2)全局变量定义 GBLA 、 GBLL 及 GBLS

  (3)变量赋值伪操作 SETA 、 SETL 及 SETS

  (4)给通用寄存器列表定义名称RLIST

  A为Arithmetic的首字母,意为定义一个数字变量。L为Logic的首字母,意为定义一个逻辑变量(true或false)。S为String的首字母,意为定义一个字符串变量。举个例子:

        GBLA Test1             ;定义全局数字变量Test1
        Test1 SETA 0xaa          ;Test1=0xaa
        GBLL Test2              ;定义全局逻辑变量Test2
        Test2 SETL {TRUE}     ;Test2=True
        GBLS Test3             ;定义全局字符串变量Test3
        Test3 SETS “Testing”      ;Test3=“Testing”

  RLIST 形式如 name RLIST {registers_list} ,该伪操作用于给一个通用寄存器列表定义名称,使用该伪操作定义的名称可以在 LDM/STM 中使用。再举个例子:

        list RLIST {R0-R2,R6,R8}    ;当你定义一个列表后,以后再用就直接写列表名称就好

        LDMIA R3!,{R0-R2,R6,R8}      ;好处就是当需要多次加载同一寄存器列表时,极大地简化了书写

        LDMIA R3!,list            ;和上边的语句效果一样

2.2 数据定义伪操作

  数据定义伪操作一般用于为特定的数据分配存储单元,同时可完成已分配存储单元的初始化。常见的数据定义伪操作有如下几种:

  (1)DCB 用于分配一片连续的字节存储单元并用指定的数据初始化。

  (2)DCD  用于分配一片连续的存储单元并用指定的数据初始化。

  (3)LTORG  用于声明一个数据缓冲池。

  (4)SPACE 用于分配一片连续的存储区域并将其初始化为0 。

  (5)MAP 用于定义一个结构化的内存表首地址。

  (6)FIELD 用于定义一个结构化的内存表的数据域。

  这六个伪操作中的DCB和DCD会在文末给出一个综合的示例来讲解其用法,这里先从LTORG开始讲。LTORG主要配合LDR伪指令一起使用,我们都知道用MOV指令时,由于ARM分配了12位用来存储立即数,所以并不是所有的立即数数都能被存储,这才有了合法与不合法的立即数之说,而LDR伪指令之所以能加载不合法的立即数的原因就是LTORG存在,使用LDR伪指令时,立即数有多大,你就可以声明一个相应大小的数据缓冲池来存放该立即数。当然你完全不用显式声明,当你不写时,ARM系统会在编译阶段自动为其补上,所以只需了解这个伪操作即可。这里给了一个例子,帮助你了解LTORG 的使用,看不懂可跳过,反正也不太重要。

        LDR  R0,  =0xAABBCCDD
        EOR R1 ,R1,R0
        B  SUB _pro
        LTORG            ;声明一个数据缓冲池用来存储0xAABBCCDD

  SPACE的作用就如上边所说,具体使用例子如下:

        AREA Data,DATA,READWRITE
        DataBuf SPACE 1000
        …

  MAP与FIELD也是一起使用的,它俩有点像C语言中的结构体,具体例子如下,自行理解。
        MAP 0x300         ;定义一个结构化的内存表,首地址固定为0x300,包含4个域
          Fdata1 FIELD 4      ;Fdata1 长度为4字节
          Fdata2 FIELD 8      ;Fdata2 长度为8字节
          Fdata3 FIELD 100    ;Fdata3 长度为 100 字节
          Fdata4 FIELD 200    ;Fdata4 长度为 200 字节

三、指令集类型标识

  指令集类型标识伪操作用来告诉编译器所处理的是32 位的ARM 指令还是16 位的Thumb 指令,实现这一操作的操作符有ARM 、CODE32 、THUMB、CODE16。其中ARM CODE32指示编译器将要处理的是 32 位的 ARM 指令,而THUMB和CODE16指示编译器将要处理的是 16 位的 Thumb 指令。具体例子如下:

          AREA ToThumb,CODE,READONLY
          ENTRY
          ARM                ;注意这里
        start
          ADR R0,into_thumb+1
          BX R0
          THUMB               ;注意这里
          into_thumb
          MOVS R0,#10

          …

四、其他类型伪操作

  下边主要讲四种相对常用又简单的伪操作,由于内容相对简单,具体示例统一在文末的综合示例中给出。

  (1)段属性定义伪操作AREA

  (2)源程序结尾标识END

  (3)声明程序的入口点ENTRY

  (4)定义常量或标号名称EQU

  AREA 用于定义一个代码段或数据段, AREA  伪操作指示汇编器汇编新的代码段或数据段。

  END 伪操作用于通知编译器已经到了源程序的结尾。相当于汉语中的句号吧。

  ENTRY 伪操作用于指定汇编程序的入口点。在一个完整的汇编程序中(一个程序可以包含多个源文件)至少要有一个ENTRY, 但在一个源文件里不能使用多个ENTRY。

  EQU 伪操作用于为程序中的常量、标号等定义一个等效的字符名称。

五、综合示例

  该例子综了以上学习的伪指令和伪操作,主要作用是将src中内容复制到dst中。

ARM伪指令与伪操作的更多相关文章

  1. ARM伪指令,王明学learn

    ARM伪指令 在ARM汇编语言程序中里,有一些特殊指令助记符与指令系统的助记符不同,没有相对应的操作码,通常称这些特殊指令助记符为伪指令,他们所完成的操作称为伪操作.伪指令在元程序中的作用是为完成汇编 ...

  2. ARM汇编初探---汇编代码中都有哪几类指令---ARM伪指令介绍

    要学习一个东西首先要把概念搞清楚,以下仅仅是自己的一些关于汇编的理解. 可运行文件里的01码是机器码,机器码不等于汇编码,尽管机器码能够非常easy翻译成汇编码. 汇编码中包括非常多汇编指令.伪指令和 ...

  3. ARM伪指令

    1.伪指令是什么 ARM伪指令不是ARM指令集中的指令,只是为了编程方便人们定义了伪指令. 在汇编时这些指令将会被等效的ARM指令或arm指令的组合代替. 编程时可以像其他ARM指令一样使用伪指令,区 ...

  4. [国嵌笔记][026][ARM伪指令]

    ARM机器码 1.汇编程序通过汇编器变成机器码,然后才能在ARM处理器上运行 2.ARM机器码是一个32位的数,被分成了多个段,每个段都有各自的含义 3.格式: cond:表示条件(4位) I:表示源 ...

  5. ARM伪指令和协处理器访问指令

    伪指令本身没有对应的机器码 .global声明全局符号,点事GUN汇编的特点 .data定义数据段 .equ DA #0x89 定义宏 .align 4 4字节对齐 mov 指令里的立即数只能是8位的 ...

  6. ARM学习笔记9——ARM汇编汇编语言中的伪指令

    ARN汇编器支持ARM伪指令,这些伪指令在汇编阶段被翻译成ARM或Thumb指令.ARM伪指令包含ADR.ADRL.MOV32和LDR.一.ADR伪指令 1.作用 ADR是小范围地址读取伪指令,基于P ...

  7. 【嵌入式开发】 ARM 汇编 (指令分类 | 伪指令 | 协处理器访问指令)

    作者 : 韩曙亮 博客地址 : http://blog.csdn.net/shulianghan/article/details/42408137 转载请著名出处 本博客相关文档下载 :  -- AR ...

  8. GNU风格 ARM汇编语法指南

    汇编源程序一般用于系统最基本的初始化:初始化堆栈指针.设置页表.操作 ARM的协处理器等.这些初始化工作完成后就可以跳转到C代码main函数中执行. 1.  GNU汇编语言语句格式 任何Linux汇编 ...

  9. ARM学习笔记11——GNU ARM汇编程序设计

    GNU ARM汇编程序设计中,每行的语法格式如下: [<label>:] [<instruction | directive | pseudo-instruction>] @c ...

随机推荐

  1. java基础(11)--封装

    一.java面向对象三大特别: 1.封装 2.继承 3.多态   二.封装的作用 1.属性私有化(private) 2.对外提供简单的入口 如公开的set()与get()方法,并且都不带static ...

  2. 一切皆组件的Flutter,安能辨我是雄雌

    从一开始接触Flutter,相信读者都会铭记一句话,那就是--一切皆组件.今天我们就来体会一下这句话的神奇魔力,我们先从实际的产品需求说起. 我们先来看一个简化的运行图: 我们要实现如上图所示的日期选 ...

  3. JavaScript Set对象

    JavaScript Set对象 Set 用于存储任何类型的唯一值,无论是基本类型还是引用类型. 只有值没有键 严格类型检测存储,字符串数字不等同于数值型数字 存储的值具有唯一性 遍历顺序是添加的顺序 ...

  4. PHP 实例 - AJAX 实时搜索-AJAX Live Search

    PHP 实例 - AJAX 实时搜索 AJAX 可为用户提供更友好.交互性更强的搜索体验. AJAX Live Search 在下面的实例中,我们将演示一个实时的搜索,在您键入数据的同时即可得到搜索结 ...

  5. Python os.chflags() 方法

    概述 os.chflags() 方法用于设置路径的标记为数字标记.多个标记可以使用 OR 来组合起来.高佣联盟 www.cgewang.com 只支持在 Unix 下使用. 语法 chflags()方 ...

  6. luoguP2154 [SDOI2009]虔诚的墓主人

    SDOI2009虔诚的墓主人 喜闻乐见,我终于把此题读懂了..所以可以写了. 其实就是让我们求有多少个十字架 一个十字架的定义为中间有一个空地 周围4个正方向都有k棵树. 不难想到nm的暴力 我们预处 ...

  7. 剑指 Offer 57. 和为s的两个数字

    本题 题目链接 题目描述 我的题解 双指针 思路分析 因为该数组是递增数组,所以我们可以用双指针法. 声明指针left 和 right分别指向数组的头(数组下标为0)和尾(数组下标为length-1) ...

  8. jmeter如何设置全局变量

    场景:性能测试或者接口测试,如果想跨线程引用(案例:A线程组里面的一个输出,是B线程组里面的一个输入,这个时候如果要引用),这个时候你就必须要设置全局变量;全链路压测也需要分不同场景,通常情况,一个场 ...

  9. Pytest单元测试框架-allure测试报告

    Allure Test Report 对于不同的编程语言,有很多很酷的测试框架.不幸的是,它们中只有少数能够提供测试执行输出的良好表示.Qameta软件测试团队正在致力于Allure--一个开源框架, ...

  10. LibSvm流程及java代码测试

    使用libSvm实现文本分类的基本过程,此文参考 使用libsvm实现文本分类 对前期数据准备及后续的分类测试进行了验证,同时对文中作者的分词组件修改成hanLP分词,对数字进行过滤,仅保留长度大于1 ...