历史上的今天
返回首页

历史上的今天

今天是:2024年12月03日(星期二)

正在发生

2019年12月03日 | ARM-汇编指令集(总结)

2019-12-03 来源:eefocus

ARM汇编指令集

指令、伪指令

(汇编)指令:   是机器码的助记符,经过汇编器编译后,由CPU执行。 

(汇编)伪指令:用来指导指令执行,是汇编器的产物,最终不会生成机器码。


有两种不同风格的ARM指令

1).ARM官方的ARM汇编风格:指令一般用大写,Windows中的IDE开发环境。

2).GNU风格的ARM汇编:指令一般用小写。


ARM汇编的特点

1. LDR/STR架构

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

2. 至此8种寻址方式

1).寄存器寻址mov r1, r2。
2).立即(立即数)寻址 mov r0, #0xFF00。
3).寄存器移位寻址 mov r0, r1, lsl #3。
4).寄存器间接寻址 ldr r1, [r2] 表示内存,内存地址存在r2这个寄存器中,把内存地址里的值给r1。

5).基址变址寻址ldr r1, [r2, #4]内存地址在r2+4里面。

6).多寄存器寻址 ldmia r1!, {r2-r7, r12}一次访问多个寄存器。
7).堆栈寻址 stmfd sp!, {r2-r7, lr}。
8).相对寻址      beq flag。

3. 指令后缀

同一指令经常附带不同后缀,变成不同的指令。经常使用的后缀有:
B(byte)功能不变,操作长度变为8位
H(half word)功能不变,长度变为16位
S(signed)功能不变,操作数变为有符号
如 ldr ldrb ldrh ldrsb ldrsh
S(S标志)功能不变,影响CPSR标志位
如 mov和movs movs r0, #0

4. 条件执行后缀

条件后缀是否成立取决于当前代码的前面的代码。

条件后缀只影响当前代码的执行。

5. 多级指令流水线

为增加处理器指令流的速度,ARM使用多级流水线.,下图为3级流水线工作原理示意图。(S5PV210使用13级流水线,ARM11为8级)
允许多个操作同时处理,而非顺序执行。

1).PC指向正被取指的指令,而非正在执行的指令


数据传输与跳转指令详解

1. 数据处理指令

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


2. cpsr访问指令

mrs & msr
mrs用来读psr,msr用来写psr
CPSR寄存器比较特殊,需要专门的指令访问,这就是mrs和msr。

3. 跳转(分支)指令

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

4. 访存指令

ldr/str & ldm/stm & swp
单个字/半字/字节访问 ldr/str
多字批量访问  ldm/stm
swp r1, r2, [r0]
swp r1, r1, [r0]

5. 软中断指令

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

ARM汇编中的立即数

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


协处理器与协处理器指令集

6.协处理器cp15操作指令

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

7.arm寻址方式

1). 寄存器:    MOV R1,R2 ; R2->R1

2). 立即数:    SUBS R0,R1,#1; R0=R1-1

3). 寄存器移位:MOV R0,R2,LSL #3 ;R2左移三位->R0 

4). 间接寻址:  LDR R1,[R2] ; 装载R2指向的内存数值至R1

5). 基址寻址:  LDR R2,[R3,#0x0F] ;R3+0x0F作为地址,将所

 

指向的置装入R2.R3的值不改变

6). 多寄存器寻址: LDMIA R1!,{R2-R7,R12} ; 将R1所指向的内

 

存块依次装入{}中的寄存器。

STMIA R0!,{R3-R6,R10} ;将{}列出的寄存器里的值依次填入R0所指向的内存块。

7). 相对寻址: BL XXX ;跳转 

BEQ XXX ;条件跳转

协处理器解析:

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


MRC & MCR的使用方法

mcr{}   p15, , , , , {}
opcode_1:对于cp15永远为0
Rd:ARM的普通寄存器
Crn:cp15的寄存器,合法值是c0~c15
Crm:cp15的寄存器,一般均设为c0
opcode_2:一般省略或为。

 

ldm/stm与栈的处理

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

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

举例(uboot start.S 537行)

stmia sp, {r0 - r12}
将r0存入sp指向的内存处(假设为0x30001000);然后地址+4(即指向0x30001004),将r1存入该地址;然后地址再+4(指向0x30001008),将r2存入该地址······直到r12内容放入(0x3001030),指令完成。
一个访存周期同时完成13个寄存器的读写


后缀的种类:

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


四种栈解析:

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


!的作用:

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,一般用于从异常模式返回。


总结:批量读取或写入内存时要用ldm/stm指令。
各种后缀以理解为主,不需记忆,最常见的是stmia和stmfd。
谨记:操作栈时使用相同的后缀就不会出错,不管是满栈还是空栈、增栈还是减栈。

 

常用gun伪指令:

global _start @ 给_start外部链接属性
.section .text @ 指定当前段为代码段
.ascii .byte .short .long .word 
.quad .float .string @ 定义数据
.align 4 @ 以4字节对齐
.balignl 16 0xabcdefgh @ 16字节对齐填充
.equ @ 类似于C中宏定义


偶尔会用到的gun伪指令

.end @标识文件结束
.include @ 头文件包含
.arm / .code32 @声明以下为arm指令
.thumb / .code16 @声明以下为thubm指令

重要的几个伪指令

ldr 大范围的地址加载指令
adr 小范围的地址加载指令
adrl 中等范围的地址加载指令
nop 空操作
ARM中有一个ldr指令,还有一个ldr伪指令
一般都使用ldr伪指令而不用ldr指令

adr与ldr

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

推荐阅读

史海拾趣

Herth+Buss Fahrzeugteile GmbH & Co KG公司的发展小趣事
电路结构简单,易于安装和维护。
GaN Systems公司的发展小趣事

多年来,GAIA盖亚电源凭借其卓越的产品性能和专业的技术支持,赢得了众多知名客户的信赖和合作。这些客户涵盖了航空航天、军事、交通运输、工业自动化等多个领域。在与客户的合作过程中,GAIA盖亚电源不仅提供了高质量的产品和服务,还与客户共同研发了多项创新解决方案,帮助客户解决了许多技术难题。这些成功案例不仅彰显了GAIA盖亚电源的技术实力和市场竞争力,也为其在电子行业的发展奠定了坚实的基础。

Clulite公司的发展小趣事
  1. 创业初期
    • 描述Clulite公司的创始人或核心团队如何识别电子行业中的某个市场机遇。
    • 讲述他们是如何筹集初始资金,设立公司,并开发出第一款产品或解决方案的。
    • 可以提及公司在初创阶段面临的挑战,如技术难题、市场竞争等。
  2. 技术创新
    • 讲述Clulite如何通过研发创新,推出了一款颠覆性的产品或技术,从而获得了市场认可。
    • 详细描述这一创新过程,包括研发团队的努力、关键技术的突破等。
    • 提及这一创新如何帮助公司在市场上取得了竞争优势。
  3. 市场拓展
    • 描述Clulite如何逐步扩大市场份额,从地区市场走向全国乃至国际市场。
    • 可以讲述公司如何建立销售网络、与合作伙伴建立合作关系,以及参与行业展会等活动来推广品牌和产品。
    • 提及公司在市场拓展过程中遇到的挑战和应对策略。
  4. 品质管理
    • 讲述Clulite如何注重产品质量和客户体验,通过严格的质量控制流程来提升产品可靠性。
    • 描述公司如何建立完善的售后服务体系,为客户提供及时、专业的支持。
    • 提及这些举措如何帮助公司赢得了客户的信任和口碑。
  5. 可持续发展
    • 讲述Clulite如何关注环境保护和社会责任,推动公司的可持续发展。
    • 描述公司如何采取环保措施,减少生产过程中的污染排放。
    • 提及公司如何参与社会公益事业,回馈社会。

请注意,这些故事需要根据Clulite公司的实际情况进行调整和补充。如果你需要更具体的内容,建议查阅Clulite公司的官方网站、新闻报道或行业分析报告,以获取更详细的信息和数据。

Anvo-Systems公司的发展小趣事

Anvo-Systems公司自成立以来,一直致力于电子技术的研发与创新。某年,公司成功研发出一款具有高效能源利用率的智能家居控制系统,该产品迅速在市场上获得了广泛关注。通过不断优化产品性能和用户体验,Anvo-Systems逐步扩大了市场份额,并与多家知名家电品牌建立了合作关系。这一技术突破不仅提升了公司的知名度,也为公司的持续发展奠定了坚实基础。

Acculin Inc公司的发展小趣事

为了进一步提升技术水平,Acculin Inc积极寻求与国际知名企业的合作。通过与欧洲一家半导体制造商的技术交流,公司引进了一条先进的生产线,并成功将其应用于新型芯片的制造中。这一合作不仅提升了Acculin的生产效率,也使其在芯片制造领域达到了国际先进水平。

Astro Tool Corp公司的发展小趣事

在市场竞争日益激烈的背景下,Astro Tool Corp公司始终坚持以创新驱动发展。公司不断投入研发资金,引进先进技术和设备,推出了一系列具有创新性和竞争力的新产品。这些产品不仅满足了客户日益多样化的需求,也为公司带来了可观的利润。同时,公司还注重人才培养和团队建设,打造了一支高效、专业的研发团队,为公司的持续发展提供了有力保障。

问答坊 | AI 解惑

开关电源中几种过流保护方式的比较

                                   开关电源中几种过流保护方 ...…

查看全部问答>

供应麦肯MDT单片机,PIC单片机,Freescale传感器,单片机,单片机开发

广州远景微电子有限公司从1999年至今专业从事麦肯MDT单片机,十速TENX单片机,美国MEAS传感器,Freescale单片机、传感器,自产IC的销售及产品方案单片机开发设计。公司技术力量雄厚,拥有专业的工程师队伍,专业承接各类单片机的开发与设计,坚持以 ...…

查看全部问答>

高手帮我找个编译错误吧.

我用的是CE6.0 。 系统定制时编译出现一个错误,只能找到最后说 ; Build for Windows CE (Release 601) (Built on Aug 17 2006 15:18:52) File names: Build.log Build.wrn Build.err Build.dat CEBUILD: Running sysgen -p script preproc St ...…

查看全部问答>

三星6410/Wince6.0 环境下,Directshow显示

三星6410/Wince6.0 环境下,Directshow 的范例一般在什么目录下? 我想用Directshow 显示 Byte *pBuf(pBuf 是一个指向RGB数据 的指针) 中的数据应可以吧?…

查看全部问答>

请教流接口驱动的问题

在wince5中,流接口驱动中,几个接口函数的参数如何确定? 我看过几个流接口驱动代码,同功能接口函数参数并不一定一样, 那这些接口函数的参数该如何确定? …

查看全部问答>

Modesim错误

编译完,启动仿真后就出现这种错误。# Reading C:/altera/10.0/modelsim_ase/tcl/vsim/pref.tcl # do vga_nios_run_msim_rtl_vhdl.do # if {[file exists rtl_work]} {#         vdel -lib rtl_work -all# }# vlib r ...…

查看全部问答>

【原创】请教各位,F149有时候不能下载,有时可以,是什么原因?

能下和找不到没有任何规律。我看斑竹只顶的帖子说有可能是内、外部  电源冲突,不知道具体是什么意思?…

查看全部问答>

PSPICE仿真一个RC震荡电路的问题请教。

各位老大好,今天用PSPICE仿真一个RC震荡电路。有个问题没有想明白,请教各位高手,有劳指点一下。电路很简单,就是一个RC振荡电路。输入是一个1V的正弦波,输入是下面图中最右边的电容。见下。我首先是进行AC扫描,频率从80k到150k,得到的输出如 ...…

查看全部问答>

急救!!!!哪位大大帮看看我的HS9148红外解码程序哪儿除了问题?

这是源代码。//使用12M晶振 适用于HS9148芯片#include<reg52.h>#include<stdio.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intsbit led=P1^1;sbit in=P3^2;//红外接口标志uchar const tab[]={0x3f,0x06,0 ...…

查看全部问答>

【M4开发板Hanker试用狂-Shower.Xu】4、借花献佛-触摸屏驱动的实现

这两天抽空拜读了触摸屏的例程,学习了它的工作原理和驱动方法,和大家分享一下。触摸屏和鼠标这类相对坐标系统不一样,属于绝对坐标系统输入设备,所以它要求一个相对固定的数据作为位置的定位,常用的有电阻和电容屏,这里我们只介绍电阻屏。电阻 ...…

查看全部问答>