《ARM裸机》2--ARM体系结构和汇编指令

目录

一、可编程器件的编程原理

 二、指令集对CPU的意义

三、RISC和CISC的区别 

四、统一编址、独立编址、哈弗结构、冯诺依曼结构

五、寄存器(***重点***)

六、内存映射

七、CPU和外部存储器的接口 

八、iMX6ULL的启动:

          1.启动方式的选择

        2.设备选择

        3.IMX6ULL映像文件 

九、ARM的编程模式和7种工作模式

        1.基本设定

        2.工作模式

十、ARM的37个寄存器       

        1.CPSR(current program status register)程序状态寄存器

        2.PC(r15)程序控制寄存器

十一、ARM的异常处理方式

        1.异常

       2. 异常向量表

        3.总结 

十二、ARM汇编指令集(一)

        1.指令与伪指令

        2.两种风格的ARM指令

十三、ARM汇编指令集(二)

        1.ARM汇编特点1:LDR/STR架构

        2.ARM汇编特点2:8种寻址方式

        3.ARM汇编特点3:指令后缀 

        4.ARM汇编特点4:条件执行后缀。 

        5.ARM汇编特点5:多级指令流水先 

十四、ARM汇编指令集(三)

        1.常见的ARM指令

        1.1 mov和mvn的用法

        1.2算法运算指令

         1.3逻辑指令

        1.4比较指令

         1.5乘法指令

        1.6前导零计数

      2. cpsr访问指令

         3.跳转指令

        4.访问指令

        5.立即数(#前缀)

         6.软中断指令

十五、ARM汇编指令集(四)

         1. 协处理器cp15操作指令

十六、ARM汇编指令集(五)

        1.为什么需要多寄存器访问指令

         2.八种后缀

        3.四种栈

        4.!和^的作用 

十七、ARM汇编指令集——伪指令

        1.伪指令的意义

         2.gnu汇编中的一些符号

        3.常用的伪指令

        4.偶尔用的伪指令

        5.最重要的伪指令

        6.adr和ldr


一、可编程器件的编程原理

        1.电子器件的发展方向

(1)模拟器件->数字器件

(2)ASIC->可编程器件

可编程器件的特点:

  • CPU在固定频率的时钟控制下节奏运行。
  • CPU可以通过总线读取外部存储设备中的二进制指令集,然后解码执行。
  • 这些可以被CPU解码执行的二进制指令集是CPU设计的时候确定的。
  • CPU一个节拍只能做一个动作,比如读一条指令、解释一条指令、或者执行一条指令。

        2.编程及进行过程

《ARM裸机》2--ARM体系结构和汇编指令_第1张图片

        烧录到Flash里面。 


 二、指令集对CPU的意义

        1.汇编语言和C等高级语言的差异

        (1)汇编难写,C好写
        (2)汇编无可移植性,C语言有一定可移植性,Java等更高级语言移植性更强。ARM写                   的就只能在AMR机器上跑,换成Intel就会完全用不了。
        (3)汇编语言效率最高,C语言次之,Java等更高级语言效率更低。
        (4)汇编不适合完成大型复杂的项目,更高级语言更适合完成更大、更复杂的项目。

        汇编适合用在那个短小精悍、至关重要、很在意效率,又不在意实现难度的地方

        2.汇编语言的本质

        (1)汇编的实质是机器指令(机器码)的助记符,是一种低级符号语言。
        (2)机器指令集是一款CPU的编程特征,是这款CPU的设计者制定的。CPU的内部电路设计就是为了实现这些指令集的功能。机器指令集就好象CPU的API接口一样。

        (3)汇编器会把助记符翻译成(101010)的机器码。

        3.编程语言的发展过程

        纯机器码编程->汇编语言->C语言编程->C++->Java C#等->脚本。


三、RISC和CISC的区别 

        1.CSIC

        (1)complex instruction set computer复杂指令
        (2)CISC体系的设计理念是用最少的指令来完成任务(譬如计算乘法只需要一条MUL指令即可),因此CISC的CPU本身设计复杂、工艺复杂,但好处是编译器好设计C出现较早,至今Intel还一直采用CISC设计。给上层提供的指令集也更多。

        2.RSIC

        (1)Reduced Instruction-Set Computer精简指令集CPU。

        (2)RISC的设计理念是让软件来完成具体的任务,CPU本身仅提供基本功能指令集。因此RISC CPU的指令集中只有很少的指令,这种设计相对于CISC,CPU的设计和工艺简单了,但是编译器的设计变难了。

        比如同意一个乘加过程,CSIC只需要一个指令就完成了,因为它内部有实现这个功能的电路。而CSIC可能就需要好几步,一步乘,一步加,如果还没有乘法电路,还得用好几步加法指令。


四、统一编址、独立编址、哈弗结构、冯诺依曼结构

        1.IO和内存统一编址

        内存是程序的运行场所,内存和CPU之间通过总线连接,CPU通过一定的地址来访问具体内存单元。
        lO (input and output)是输入输出接口,是CPU和其他外部设备(如串口、LCD、触摸屏、LED等)之间通信的道路。一般的IO就是指CPU的各种内部或外部外设。且这里将统一编址,IO就是指的IO的寄存器。

        (1)内存的访问方式                                                                                                       

  • 内存通过CPU的地址总线来寻址定位,然后通过CPU数据总线来读写。
  • CPU的地址总线的位数是CPU设计时确定的,因此一款CPU所能寻址的范围是一定的,而内存是需要占用CPU的寻址空间的。
  • 内存与CPU的这种总线式连接方式是一种直接连接,优点是效率高访问快,缺点是资源  有限,扩展性差。

        (2)IO的访问方式

  • IO指的是与CPU连接的各种外设
  • CPU访问各种外设有2种方式:一种是类似于访问内存的方式,即把外设的寄存器当作一个内存地址来读写,从而以访问内存相同的方式来操作外设,叫IO与内存统一编址方式;另一种是使用专用的CPU指令来访问某种特定外设,叫IO与内存独立编址

        IO和内存统一编址:但实际可能只有例如32位地址总线的CPU,最大支持4G的内存,1到两个G给内存,有一部分就留给IO。

        (3)对比

  • 由于内存访问频率高,因此采用总线式连接,直接地址访问,效率最高。
  • IO与内存统一编址方式,优势是lO当作内存来访问,编程简单;缺点是lO也需要占用一   定的CPU地址空间,而CPU的地址空间是有限资源。
  • IO与内存独立编织方式,优势是不占用CPU地址空间,缺点是编程模式复杂。

        2.冯诺依曼结构与哈弗结构

        (1)冯诺依曼结构

                程序和数据都放在内存中,且不彼此分离。例如:Intel。

        (2)哈弗结构

                程序和数据分开独立放在不同的内存块中,彼此完全分离的结构称为哈佛结构。嵌入式多哈弗结构。

        (3)优劣对比

  • 冯诺依曼结构中程序和数据不区分的放在一起,因此安全和稳定性是个问题,好处是处理起来简单。
  • 哈佛结构中程序(一般放在ROM、flash中,操作系统可以让程序不可写)和数据(一般放在RAM中)独立分开存放,因此好处是安全和稳定性高,缺点是软件处理复杂一些(需要统一规划链接地址等)

  • 五、寄存器(***重点***)

        软件编程控制硬件的关键—————寄存器

        1.寄存器

  • 寄存器属于CPU外设的硬件部分。
  • CPU可以像访问内存一样访问寄存器。
  • 寄存器是CPU的硬件设计者指定的,目的是留作外设被编程控制的“活动开关”。
  • 正如汇编指令集是CPU的编程接口API一样,寄存器是外设硬件的软件编程接口API。使用软件编程控制某一硬件,其实就是编程读写该硬件的寄存器。

        2.寄存器操作

  • 编程操作寄存器类似于访问内存。
  • 寄存器中每个bit位都有特定含义,因此编程操作时需要位操作。
  • 单个寄存器位宽一般和CPU的位宽一样,以实现最佳访问效率。

        3.两类寄存器

  • SoC中有2类寄存器:通用寄存器SFR
  • 通用寄存器(ARM中有37个)是CPU的组成部分,CPU的很多活动都需要通用寄存器的支持和参与。
  • SFR (special function register,特殊功能寄存器)不在CPU中,而存在于CPU的外设中,我们通过访问外设的SFR来编程操控这个外设,这就是硬件编程控制的方法。

六、内存映射

        1.什么时内存映射?

  • S5PV210属于ARM Cortex-A8架构,32位CPU,CPU设计时就有32根地址线&32根数据线。
  • 32根地址线决定了CPU的地址空间为4G(4G个编号,如4G的房间号),那么这4G空间如何分配使用?这个问题就是内存映射问题(地址映射)。

        2.一些专业术语

ROM:read only memory 只读存储器,比如flash。顺序存储,(注意,只读的意思时,                  CPU不能直接通过总线对ROM进行写操作,ROM有写的API)。
RAM: ramdom access memory 随机访问存储器。
lROM:internal rom内部ROM,指的是集成到SoC内部的ROM。
lRAM:internal ram内部RAM,指的是集成到SoC内部的RAM
DRAM:dynamic ram动态RAM。
SRAM: static ram静态RAM。
SROM

ONENAND/NADN

SFR:special function register

详细了解:(8条消息) ROM、RAM、IROM、IRAM、DRAM、SRAM、Flash介绍_长弓的坚持的博客-CSDN博客https://blog.csdn.net/wordwarwordwar/article/details/84932107

七、CPU和外部存储器的接口 

        1.内存和外存

内存:内部存储区(RAM)。用来运行程序的,例如(DRAM、SRAM、DDR)。

外存:外部存储器(ROM)。用来存储东西的,例如(硬盘、Flash(Nand、iNand……U               盘、SSD)、光盘)。


CPU连接内存和外存的方法时不一样的。内存需要直接地址访问,所以时通过地址总线&数据总线的总线方式访问方式连接(好处是直接访问,随机访问;坏处是占用CPU的地址空间,大小受限);外存时通过CPU的外存接口来连接的(好处是不占用CPU的地址空间,坏处是,访问速度没有总线式快,访问时序较复杂)

         SoC常用外存:

Flash

NorFlash:总线式访问,一般接到SROM bank,一般用来启动。BIOS其实就是NorFlash。


NandFlash:分为SLC(容量小,访问稳定、价格高)和MLC(容量大、不稳定、价格低)

eMMC/iNand/moviNand: eMMC(embeded MMC),iNand是sanDisk公司出产的                                                         eMMC,moviNand是三星公司出产的eMMc

oneNAND:三星出的一种Nand

SD卡/TF卡/MMC卡

eSSD


SATA硬盘(机械式访问、磁存储原理、SATA是接口)

八、iMX6ULL的启动:

《ARM裸机》2--ARM体系结构和汇编指令_第2张图片

        阅读芯片手册,6ULL的启动支持:

The boot ROM supports these boot devices:

  • NOR flash
  • NAND flash
  • OneNAND flash
  • SD/MMC
  • Serial (SPI) NOR flash and EEPROM
  • QuadSPI (QSPI) flash

        当开发板上电视,CPU会去执行boot ROM(96kb)里的代码,选择启动方式、设备、设置参数。

          1.启动方式的选择

BOOT的处理过程是发生在I.MX6U芯片上电以后,芯片会根据BOOT_MODE[1:0]的设置来选择BOOT方式。BOOT_MODE[1:0]的值是可以改变的,有两种方式,一种是改写eFUSE(熔丝),一种是修改相应的GPIO高低电平。第一种修改eFUSE的方式只能修改一次,后面就不能在修改了,所以我们不使用。我们使用的是通过修改BOOT_MODE[1:0]对应的GPIO高低电平来选择启动方式,所有的开发板都使用的这种方式,I.MX6U有一个BOOT_MODE1引脚和BOOT_MODE0引脚,这两个引脚对应这BOOT_MODE[1:0]

《ARM裸机》2--ARM体系结构和汇编指令_第3张图片

         00表示从FUSE启动,01表示从串口下载,10表示内部BOOT(sd卡等)启动,11表示保留。

        2.设备选择

I.MX6U同样提供了eFUSE和GPIO配置两种,eFUSE就不讲解了。我们重点看如何通过GPIO来选择启动设备,因为所有的I.MX6U开发板都是通过GPIO来配置启动设备的。正如启动模式由BOOT_MODE[1:0]来选择一样,启动设备是通过BOOT_CFG1[7:0]、BOOT_CFG2[7:0]和BOOT_CFG4[7:0]这24个配置IO这24个配置IO刚好对应着LCD的24根数据线LCD_DATA0~LCDDATA23,当启动完成以后这24个IO就可以作为LCD的数据线使用。

《ARM裸机》2--ARM体系结构和汇编指令_第4张图片

         因为一些引脚接地,和默认的值(BOOT_MODE 10,GPIO选择设备),我们只需要选择控制部分的引脚。

《ARM裸机》2--ARM体系结构和汇编指令_第5张图片

         基于100ASK_IMX6ULL 开发板:

《ARM裸机》2--ARM体系结构和汇编指令_第6张图片


        3.IMX6ULL映像文件 

        I.MX6U不能直接烧写编译生成的.bin文件,我们需要在.bin文件前面添加一些头信息构成满足I.MX6U需求的最终可烧写文件,I.MX6U的最终可烧写文件组成如下:

《ARM裸机》2--ARM体系结构和汇编指令_第7张图片

        (1) load.imx最前面的就是IVT和Boot Data,IVT包含了镜像程序的入口点、指向DCD的指针和一些用作其它用途的指针。

        (2)

        (3)DCD是包含在程序映像(ROM外部)中的配置信息。内存及外存的配置信息。

      (4)用户代码

                      烧写时,使用imxdownload软件添加信息,生成.imx文件。


九、ARM的编程模式和7种工作模式

        1.基本设定

(1)32位架构。

        byte :8bites              Halfword:16bites(2byte)                 Word:32bites(4 byte)

(2)大部分ARM core提供:

          ——ARM指令集(32-bit)

          ——Thumb指令集(16-bit)

          ——Thumb2指令集(16&32bit)

        2.工作模式

(1)User:非特权模式(用户模式),大部分任务执行在这种模式。


(2)FRQ:当一个高优先级(fast)中断产生时将会进入这种模式。

(3)IRQ:当一个低优先级(normal)中断产生时将会进入这种模式。

(4)Supervisor:当复位或软中断指令执行时将会进入这种模式。

(5)Abort:当存取异常时将会进入这种模式。

(6)Undef:当执行未定义指令时会进入这种模式。

(7)System:使用和User模式相同寄存器集的特权模式。

        1时用户模式,加六个特权模式,其中2~6是异常模式。

  • 除User(用户模式))是Normal(普通模式)外,其他6种都是Privilege(特权模式)。
  • Privilege中除Sys模式外,其余5种为异常模式。
  • 各种模式的切换,可以是程序员通过代码主动切换(通过写CPSR寄存器);也可以是CPU在某些情况下自动切换。
  • 各种模式下权限和可以访问的寄存器不同。

操作系统在System模式下运行,发生中断进入到FIQ、IRQ,引导的时候在Supervisor模式,用户进程在User模式。

        为什么要设计这些模式:

  • CPU是硬件,OS是软件,软件的设计要依赖硬件的特性,硬件的设计要考虑软件需要,便于实现软件特性。
  • 操作系统有安全级别要求,因此CPU设计多种模式是为了方便操作系统的多种角色安全等级需要。

十、ARM的37个寄存器       

《ARM裸机》2--ARM体系结构和汇编指令_第8张图片

        (1)每种模式最多能看到18个寄存器,但是每种都有自己特有的寄存器,虽然名字一样,                     但是所指的寄存器不一样。

        (2)比如对r14来说,在ARM中有六个叫这个名字的寄存器,但是在每一种模式下,只有一                   个特定对应的寄存器 。

        (3)寄存器的切换是自动的,只要切换了模式,寄存器就自动切换了。

        (4)System模式和User模式一样。

  • ARM共有37个寄存器,都是32位长度。
  • 37个寄存器中30个为“通用”型,1个固定用作PC,一个固定用作CPSR,5个固定用作5种异常模式下的SPSR。

        1.CPSR(current program status register)程序状态寄存器

《ARM裸机》2--ARM体系结构和汇编指令_第9张图片

  •  CPSR中各个bit位表明了CPU的某些状态信息,这些信息非常重要,和后面学到的汇编指令息息相关(譬如BLE指令中的E就和CPSR中的Z标志位有关)。
  • CPSR中的I、F位和开中断、关中断有关。
  • CPSR中的mode位(bit4~bit0共5位)决定了CPU的工作模式,在uboot代码中会使用汇编进行设置。

        2.PC(r15)程序控制寄存器

  • PC(Program control register)为程序指针,PC指向哪里,CPU就会执行哪条指令(所以程序跳转时就是把目标地址代码放到PC中)。
  • 整个CPU中只有一个PC(CPSR也只有一个,但SPSR有5个)。

十一、ARM的异常处理方式

        1.异常

  • 正常工作之外的流程都叫异常。
  • 异常会打断正在执行的工作,并且一般我们希望异常处理完成后继续回来执行原来的工作。
  • 中断是异常的一种。

        FIQ、IRQ是中断,Supervisor是软中断。

异步的        靠中断实现                

同步的        靠同步时钟实现

       2. 异常向量表

  • 所有的CPU都有异常向量表,这是CPU设计时就设定好的,是硬件决定的。
  • 当异常发生时,CPU会自动动作(PC跳转到异常向量处处理异常,有时伴有一些辅助动作)
  • 异常向量表是硬件向软件提供的处理异常的支持。

《ARM裸机》2--ARM体系结构和汇编指令_第10张图片

        3.总结 

  • 异常处理中有一些是硬件自动做的,有一些是程序员需要自己做的。需要搞清楚哪些是需要自己做的,才知道如何写代码。
  • 以上说的是CPU设计时提供的异常向量表,一般称为一级向量表。有些CPU为了支持多个中断,还会提供二级中断向量表,处理思路类似于这里说的一级中断向量表。

十二、ARM汇编指令集(一)

        1.指令与伪指令

  • (汇编)指令是CPU机器指令的助记符,经过编译后会得到一串10组成的机器码,可以由CPU读取执行。
  • (汇编)伪指令本质上不是指令(只是和指令一起写在代码中),它是编译器环境提供的,目的是用来指导编译过程,经过编译后伪指令最终不会生成机器码。

        2.两种风格的ARM指令

  • ARM官方的ARM汇编风格:指令一般用大写、Windows中IDE开发环境(如ADS、MDK等)常用。如: LDR R0, [R1]。
  • GNU风格的ARM汇编:指令一般用小写字母、linux中常用。如:ldr r0, [r1]。

十三、ARM汇编指令集(二)

        1.ARM汇编特点1:LDR/STR架构

  • ARM采用RISC架构,CPU本身不能直接读取内存,而需要先将内存中内容加载入CPU中通用寄存器中才能被CPU处理。
  • ldr(load register)指令将内存内容加载入通用寄存器。
  • str(store register)指令将寄存器内容存入内存空间中。
  • ldr/str组合用来实现 ARM CPU和内存数据交换。

        2.ARM汇编特点2:8种寻址方式

《ARM裸机》2--ARM体系结构和汇编指令_第11张图片

        3.ARM汇编特点3:指令后缀 

同一指令经常附带不同后缀,变成不同的指令。经常使用的后缀有:

  • B(byte)功能不变,操作长度变为8位
  • H(half word)功能不变,长度变为16位
  • S(signed)功能不变,操作数变为有符号 。如 ldr ldrb ldrh ldrsb ldrsh
  • S(S标志)功能不变,影响CPSR标志位。如 mov和movs        movs r0, #0(mov的CPSR的Z位不影响,CPSR的Z位则被置为1)。

        4.ARM汇编特点4:条件执行后缀。 

《ARM裸机》2--ARM体系结构和汇编指令_第12张图片

        5.ARM汇编特点5:多级指令流水先 

《ARM裸机》2--ARM体系结构和汇编指令_第13张图片

注意PC的位置 

十四、ARM汇编指令集(三)

        1.常见的ARM指令

  • 数据传输指令            mov mvn
  • 算术指令                   add sub rsb adc sbc rsc
  • 逻辑指令                   and orr eor bic
  • 比较指令                   cmp cmn tst teq
  • 乘法指令                   mvl mla umull umlal smull smlal
  • 前导零计数               clz

        1.1 mov和mvn的用法

mov  r1,  r0        把寄存器r0的数据传输给寄存器r1,这里是两个寄存器不可以是内存。

mov  r1,  #0xff    把立即数0xff赋值给寄存器r1。

mvn的用法和mov的用法一样,区别是mov是原封不动的传递,而mvn是按位取反后传递。

比如:r1 = 0x000000ff,然后mov r0 , r1后,r0 = 0xff,但是mvn r0, r1后,r1 = 0xffffff00

        1.2算法运算指令

写的时候分析

         1.3逻辑指令

and        逻辑与

orr          逻辑或

eor        逻辑异或

bic        位清除指令,把某些特定的位清楚,变为0

bic r0,r1,#0x1f        将r1中的数bit0到bit4清零后赋值给r0(特定位就是0x1f里为1的位)

bic r0,r0,#0x1f        将r0中的数bit0到bit4清零后赋值给r0(特定位就是0x1f里为1的位),所以要给r0某些位清零,需要先将r0的数读出来,清零后再存回去。

        1.4比较指令

cmp        比较是不是相等

cmn        比较是不是互补

tst           测试某些位是否为1

teq          比较相等不相等

比较指令用来比较两个寄存器中的数

注意:比较指令不用后加s后缀可以影响cpsr中的标志位。

         1.5乘法指令

写的时候分析

        1.6前导零计数

 写的时候分析 

      2. cpsr访问指令

        cpsr和spsr的区别和联系:cpsr是程序状态寄存器,整个Soc中只有一个;而spsr有5个,分别在5种异常模式下,作用是当从普通模式进入异常模式时,用来保存之前普通模式下的cpsr,以后返回普通模式时恢复原来的cpsr。

  • mrs & msr
  • mrs用来读psr,msr用来写psr。
  • CPSR寄存器比较特殊,需要专门的指令访问,这就是mrs和msr。
  • msr cpsr_c #0xd3,可以直接处理cpsr的模式位。

         3.跳转指令

  • b & bl & bx
  • b 直接跳转(就没打开算返回)
  • bl (branch and link),跳转前把返回地址放入lr中,以便返回,以便用于函数调用
  • bx跳转同时切换到ARM模式,一般用于异常处理的跳转。(使用很少)

        4.访问指令

ldr/str &    ldm/stm & swp

  • 单个字/半字/字节访问 ldr/str        (单字一次4个字节/h后缀两个字节/b后缀一个字节)
  • 多字批量访问  ldm/stm              
  • swp r1, r2, [r0]                             把[r0]内存的数据读到r1,再把r2写入[r0]。
  • swp r1, r1, [r0]

        5.立即数(#前缀)

  • 合法立即数与非法立即数
  • ARM指令都是32位,除了指令标记和操作标记外,本身只能附带很少位数的立即数。因此立即数有合法和非法之分。
  • 合法立即数:经过任意位数的移位后非零部分可以用8位表示的即为合法立即数

         6.软中断指令

  • swi(software interrupt)
  • 软中断指令用来实现操作系统中系统调用

十五、ARM汇编指令集(四)

     协处理器

  • SoC内部另一处理核心,协助主CPU实现某些功能,被主CPU调用执行一定任务。
  • ARM设计上支持多达16个协处理器,但是一般SoC只实现其中的CP15。(cp:coprocessor)
  • 协处理器和MMU、cache、TLB等处理有关,功能上和操作系统的虚拟地址映射、cache管理等有关。

         1. 协处理器cp15操作指令

  • mcr & mrc
  • mrc用于读取CP15中的寄存器
  • mcr用于写入CP15中的寄存器

        例如:

                mrc  p15, 0, r0,c1,c0,0(读协处理器,r0时cpu的寄存器,c1是协处理器的寄存器)

                mcr  p15, 0 ,r 0,c1, c0,0(写协处理器)

《ARM裸机》2--ARM体系结构和汇编指令_第14张图片


十六、ARM汇编指令集(五)

        1.为什么需要多寄存器访问指令

  • ldr/str每周期只能访问4字节内存,如果需要批量读取、写入内存时太慢,解决方案是stm/ldm
  • ldm(load register mutiple)
  • stm(store register mutiple)

         2.八种后缀

  • ia(increase after)先传输,再地址+4
  • ib(increase before)先地址+4,再传输
  • da(decrease after)先传输,再地址-4
  • db(decrease before)先地址-4,再传输
  • fd(full decrease)满递减堆栈
  • ed(empty decrease)空递减堆栈
  • fa(·······) 满递增堆栈
  • ea(·······)空递增堆栈

        3.四种栈

  • 空栈:栈指针指向空位,每次存入时可以直接存入然后栈指针移动一格;而取出时需要先移动一格才能取出
  • 满栈:栈指针指向栈中最后一格数据,每次存入时需要先移动栈指针一格再存入;取出时可以直接取出,然后再移动栈指针
  • 增栈:栈指针移动时向地址增加的方向移动的栈
  • 减栈:栈指针移动时向地址减小的方向移动的栈

        4.!和^的作用 

!:

  • ldmia    r0, {r2 - r3}
  • ldmia    r0!, {r2 - r3}
  • 感叹号的作用就是r0的值在ldm过程中发生的增加或者减少最后写回到r0去,也就是说ldm时会改变r0的值。

^:

  • ldmfd    sp!, {r0 - r6, pc}
  • ldmfd    sp!, {r0 - r6, pc}^
  • ^的作用:在目标寄存器中有pc时,会同时将spsr写入到cpsr,一般用于从异常模式返回。(pc寄存器是放指令的)

十七、ARM汇编指令集——伪指令

        1.伪指令的意义

  • 伪指令不是指令,伪指令和指令的根本区别是经过编译后会不会生成机器码。
  • 伪指令的意义在于指导编译过程。
  • 伪指令是和具体的编译器相关的,我们使用gnu工具链,因此学习gnu环境下的汇编伪指令。

         2.gnu汇编中的一些符号

  • @ 用来做注释。可以在行首也可以在代码后面同一行直接跟,和C语言中//类似
  • # 做注释,一般放在行首,表示这一行都是注释而不是代码。
  • :以冒号结尾的是标号
  • .  点号在gnu汇编中表示当前指令的地址
  • # 立即数前面要加#或$,表示这是个立即数

        3.常用的伪指令

.global _start                                                           @ 给_start外部链接属性 在别的文件访问 

.section .text                                                           @ 指定当前段为代码段

.ascii .byte .short .long .word .quad .float .string    @ 定义数据

.align 4                                                                    @ 以16(2^4)字节对齐

.balignl 16 0xabcdefgh                                            @ 16字节对齐填充

b表示位填充;align表示对齐;l表示long,以4个字节填充;16表示16字节对齐;0xabcdefgh表示填充的原料

.equ                                                                         @ 类似于C中宏定义

        4.偶尔用的伪指令

.end                       @标识文件结束

.include                  @ 头文件包含

.arm / .code32        @声明以下为arm指令

.thumb / .code16    @声明以下为thubm指令

        5.最重要的伪指令

  • ldr        大范围的地址加载指令
  • adr       小范围的地址加载指令
  • adrl      中等范围的地址加载指令
  • nop      空操作
  • ARM中有一个ldr指令,还有一个ldr伪指令
  • 一般都使用ldr伪指令而不用ldr指令(因为ldr指令要考虑立即数的合法性,ldr伪指令不用考虑)
  • ldr指令  ldr r0, #0xff ; ldr伪指令  ldr  r0,=0xff

        6.adr和ldr

  • adr编译时会被1条sub或add指令替代,而ldr编译时会被一条mov指令替代或者文字池方式处理;
  • adr总是以PC为基准来表示地址,因此指令本身和运行地址有关,可以用来检测程序当前的运行地址在哪里;
  • ldr加载的地址和链接时给定的地址有关,由链接脚本决定。

你可能感兴趣的:(arm开发,汇编)