ARM汇编指令 对比记忆 (整理)

合集下载

arm汇编指令积累

arm汇编指令积累

arm汇编指令积累arm 汇编指令积累2011-03-26 14:40 1115人阅读评论(0) 收藏举报一、ldr的确是个复杂的指令,现总结一下:首先要判断我们用的是ldr arm指令还是伪指令。

当我们用的是arm指令时,它的作用不是向寄存器里加载立即数,而是将某个地址里的内容加载到寄存器。

而伪指令ldr的作用就是向寄存器里加载立即数。

(1) ldr伪指令ldr伪指令的格式是 ldr Rn, =expr其中,expr是要加载到Rn中的内容,一般可以是立即数或者label。

如果expr可以用8bit数据向右移偶数位得到,那么这条伪指令就被编译器翻译成mov指令。

具体的移位情况可以去查阅资料。

反之如果立即数很大,超过了12bit的表示范畴,那么就不能用一条mov指令了,毕竟arm指令最大只有32bit的空间可用(RISC的arm所有的指令长度是一致的,效率较高,当然我们并不关心16bit的thumb 指令)。

如果不能用一条32bit的指令乘下来,那么就只能另辟蹊径了,新开一段缓冲,将立即数expr放到里面,然后将其地址(暂时标记为addr)拿来使用:ldr Rn, addrxxx (xxx就是expr)xxx由于编译器一般来说新安排的存储这个立即数expr的缓冲的位置是在相应代码的附近(这个应该可以控制,好像是使用.ltorg伪指令)。

我们从addr地址加载数据到Rn不就可以了。

(2)ldr arm 指令就是将一个地址的内容加载到寄存器。

不能用mov,因为arm里的mov只是在寄存器之间传输数据,不支持在寄出器和memory之间传递数据。

因此就出现了ldr/str指令。

如ldr Rn, addr,注意这里的addr的值也是有限制的。

这个label应该距离当前指令的距离不超过4k。

因为我们知道label在具体使用的时候应该是被翻译成了相对偏移,如果这个label长度不超过12bit,那么就不应超过4k,我们可以这样做:ldr pc, _start_armboot_start_armboot: .word arm_startboot这样label _start_armboot就在指令下方,因此肯定是合法的。

ARM汇编语言指令总结

ARM汇编语言指令总结

ARM汇编语⾔指令总结ARM处理器有9种寻址⽅式:1、寄存器寻址,2、⽴即寻址,3、寄存器器移位寻址,4、寄存器间接寻址,5、基址寻址,6、多寄存器寻址,7、堆栈寻址,8、块拷贝寻址,9、相对寻址。

ARM指令集:ARM指令基本格式如下:{}{S} ,{,}其中<>的内容是必须的,{}的内容是可选的。

OPCODE指令助记符,COND执⾏条件,S是否影响CPSR中的值,Rd⽬标寄存器,Rn 第⼀个操作数的寄存器,OPERAND2第⼆个操作数。

灵活的使⽤第2个操作数“operand2”能够提⾼代码效率。

它有如下的形式:1)#immed_8r ——常数表达式;2)Rm——寄存器⽅式;3)Rm,shift——寄存器移位⽅式(ASR算术右移,LSL逻辑左移,LSR 逻辑右移,ROR循环右移,RRX带扩展的右移1位)。

COND执⾏条件:下⾯介绍ARM指令:1、存储器访问指令。

存储器访问指令分为单寄存器操作指令和多寄存器操作指令。

单寄存器操作指令LDR/STR指令⽤于对内存变量的访问、内存缓冲区数据的访问、查表、外围部件的控制操作等。

LDR:从内存到寄存器,加载数据。

STR:将寄存器的数据存储到内存。

LDRB操作字节,LDRH操作半字,LDRSH操作有符号半字。

多寄存器操作指令LDM为加载多个寄存器;STM为存储多个寄存器。

允许⼀条指令传送16个寄存器的任何⼦集或所有寄存器。

它们主要⽤于现场保护、数据复制、常数传递等。

进⾏数据复制时,先设置好源数据指针和⽬标指针,然后使⽤块拷贝寻址指令LDMIA/STMIA(传送后地址加4)、LDMIB/STMIB(传送前地址加4)、LDMDA/STMDA(传送后地址减4)、LDMDB/STMDB(传送前地址减4)进⾏读取和存储。

进⾏堆栈操作操作时,要先设置堆栈指针(SP),然后使⽤堆栈寻址指令STMFD/LDMFD(满递减堆栈)、STMED/LDMED(空递减堆栈)、STMFA/LDMFA(满递增堆栈)和STMEA/LDMEA(空递增堆栈)实现堆栈操作。

ARM常用汇编指令

ARM常用汇编指令

ARM常用汇编指令arm 2009-12-19 15:51:59 阅读113 评论0 字号:大中小LDR 和STR——用于字和无符号字节指令格式:LDR/STR{cond}{T} Rd,<地址>LDR/STR{cond}B{T} Rd,<地址>LDR{cond}{T} Rd,<地址> 加载指定地址的字数据到Rd中;STR{cond}{T} Rd,<地址> 存储Rd中的字数据到指定的地址单元中;LDR{cond}B{T} Rd,<地址> 指令加载指定地址的字节数据到Rd的的最低字节中(Rd的高24位清零);STR{cond}B{T} Rd,<地址> 指令存储Rd中的最低字节数据到指定的地址单元中。

T为可选后缀,若有T,那么即使处理器是在特权模式下,存储系统也将访问看成处理器是在用户模式下,T 在用户模式下无效,不能与前索引偏移一起使用T。

地址部分可用的形式有4种:∙零偏移(zero offset) [Rn],Rn的值作为传送数据的地址。

如:LDR R0,[R1];∙前索引偏移(pre-indexed offset) [Rn,Flexoffset]{!}在数据传送之前,将偏移量Flexoffse t加到Rn 中。

其结果作为传送数据的存储器地址。

若使用后缀“!”,则结果写回到Rn 中,且Rn 不允许是R15,如:LDRB R0,[R1,#8]LDR R0,[R1,#8]!∙程序相对偏移(program relative) label(label 必须是在当前指令的土4KB范围内) 。

程序相对偏移是前索引形式的另一种版本。

从PC 计算偏移量,并将PC 作为Rn 生成前索引指令,不能使用后缀“!”,如:LDR R0,place ;place地址装入R0∙后索引偏移(post-indexed offset) [Rn],Flexoffset。

ARM中的汇编指令

ARM中的汇编指令

ARM中的汇编指令Arm指令,32位的指令集,⼀共有16条的基本指令,每条指令都可以按条件执⾏, 指令都是32bit的,⾼四位是条件码[31:28],Thumb指令,16位的指令集,执⾏效率⽐arm指令集要低,但是节省了系统的存储空间,兼容了16位的数据总线宽度的应⽤体系。

thumb指令,相⽐较与arm代码,储存器的功耗也较低。

thumb指令,基本都是⽆条件的,⼀共有18条基本指令,全部指令都是16bit。

Thumb-2指令,由16bit、32bit的指令混合组成,⼀共有16条基本指令,BIC:ARM指令,对某些位,清零。

先取反再相与。

asm("BIC r2, r2, #0x1f"); ##对R2的低5位清零。

ORR:ARM指令,逻辑或asm("ORR r2, r2, #0x10"); ##R2逻辑与0x10。

MRS:asm("MRS r2, CPSR"); ##将CPSR的值加载到R2中。

MSR:asm("MSR CPSR, r2"); ##将R2的值加载到CPSR中。

asm(" SWI 0x0"); ##跳转到软件中断函数,并转换为SVC模式。

LDR:{条件}⽬的寄存器存储器寄存器。

将存储地址所指的4个字节数据传送到寄存器,其中寻址⽅式会有很多种。

asm("ldr r0,=0xddeeaabb"); ##在这⾥ldr是⼀个伪指令,相当于move指令。

asm("ldr r0, [r1]"); ##将存储器地址为r1的⼀个字的数据加载到r0中。

MRC与MCR:在处理器寄存器与协处理器寄存器之间交换数据。

MRC {cond} coproc, opcode1, Rd, CRn, CRm {,opcode2}asm("mrc p15,0,r0,c1,c1,0"); ##在CRn, CRm均为c1, opcode均为0时,表⽰SCR(Secure Configuration Register),表⽰将c1的值赋值给r0.asm("mcr p15,0,r0,c1,c1,0"); ##将r0的值赋值给c1.asm("mcr p15,0,r0,c12,c0,0"); ##将r0的值赋值给c12,此时c12表⽰VBAR,Vector Base Address Register,存放异常时的⼊⼝地址。

ARM的汇编指令讲解

ARM的汇编指令讲解

汇编知识点的要求:1、能看的懂2、可以做修改3、不需要用汇编直接编写程序汇编代码的应用场合:1、ARM的启动代码必须要汇编,如:uboot最开始初始化硬件的代码2、内核在最开始初始化的位置。

一、ARM汇编指令的编码格式1、编码格式ARM汇编指令编译成机器码以后,机器码的长度是32bits,这32bits的编码有一个固定的格式。

不同ARM 汇编指令,编码格式不同。

2、举例C:if(a==10)a++;elsea--;汇编1:CMP R0, #10;ADDEQ R0,R0,#1SUBNE R0,R0,#1汇编2SUBS R1, R0, #10; //S ---运算的结果会影响条件码标志位:CPSR:NZCVADDEQ R0,R0,#1SUBNE R0,R0,#1提示:空指令NOP,实际上是占用CPU的时间,但是执行后,没有什么意义。

NOP ---- MOV R0,R03、条件码标识10 -10Z = 1C = 0N = 0V = 0=================================================================================二、ARM的寻址方式1、立即数寻址操作数,有立即数。

ADD R0,R0,#1MOV R1,#10ORR R1,R1,#0xf @ R1=R1 | 0xfBIC R1,R1,#0xf @R1 = R1&(~(0xf))错误:ADD R1,#1,#2注意:立即数合法的条件在ARM汇编指令中,并不是所有的立即数,立即数是有一定的限制的。

什么样的立即数是合法的???1、如果一个立即数是小于256的(即该立即数是8bits以内的,0~255),该立即数是合法的。

2、如果一个立即数是大于等于256,该立即数经过循环左移偶数位,可以得到一个小于256的数,则该立即数合法。

256 = 0x100 ------→左移20位0x10000000----→左移4 0x1 合法0x111 非法0x102 非法0x104 合法0xfff0xff000x120000x4500000xab原因:在数据处理指令编码的时候,立即数用12bits来表示:高4bits:循环左移左移偶数位除以2低8bits:循环左移后的结果。

常用ARM指令汇总

常用ARM指令汇总

常用ARM指令集及汇编一、ARM处理器的寻址方式二、指令集学习(一)ARM指令集1.指令格式2.条件码3.ARM存储器访问指令1)LDR/ STR-加载/ 存储指令2)LDM/ STM-多寄存器加载/ 存储指令3)SWP-寄存器和存储器交换指令4.ARM数据处理指令1)数据传送指令a)MOV-数据传送指令b)MVN-数据非传送指令2)算术逻辑运算指令a)ADD-加法运算指令b)SUB-减法运算指令c)RSB-逆向减法指令d)ADC-带进位加法指令e)SBC-带进位减法指令f)RSC-带进位逆向减法指令g)AND-逻辑“与”h)ORR-逻辑“或”i)EOR-逻辑“异或”j)BIC-位清除指令3)比较指令a)CMP-比较指令b)CMN-负数比较指令c)TST-位测试指令d)TEQ-相等测试指令4)乘法指令a)MUL-32位乘法指令b)MLA-32位乘加指令c)UMULL-64位无符号乘法指令d)UMLAL-64位无符号乘加指令e)SMULL-64位有符号乘法指令f)SMLAL-64位有符号乘加指令5.ARM分支指令1)B-分支指令2)BL-带连接的分支指令3)BX-带状态切换的分支指令6.ARM协处理器指令1)CDP-协处理器数据操作指令2)LDC-协处理器数据读取指令3)STC-协处理器数据写入指令4)MCR-ARM处理器到协处理器的数据传送指令5)MRC-协处理器到ARM处理器的数据传送指令7.ARM杂项指令1)SWI-软中断指令2)MRS-读状态寄存器指令3)MSR-写状态寄存器指令8.ARM伪指令1)ADR-小范围的地址读取伪指令2)ADRL-中等范围的地址读取伪指令3)LDR-大范围的地址读取伪指令4)NOP-空操作伪指令(二)Thumb指令集1.Thumb指令集和ARM指令集的区别2.Thumb存储器访问指令1)LDR/ STR-加载/ 存储指令2)PUSH/ POP-寄存器入栈 / 出栈指令3)LDMIA/ STMIA-多寄存器加载/ 存储指令3.Thumb数据处理指令1)数据传送指令a)MOV-数据传送指令b)MVN-数据非传送指令c)NEG-数据取负指令2)算术逻辑运算指令a)ADD-加法运算指令b)SUB-减法运算指令c)ADC-带进位加法指令d)SBC-带进位减法指令e)MUL-乘法运算指令f)AND-逻辑“与”g)ORR-逻辑“或”h)EOR-逻辑“异或”i)BIC-位清除指令j)ASR-算术右移指令k)LSL-逻辑左移指令l)LSR-逻辑右移指令m)ROR-循环右移指令3)比较指令a)CMP-比较指令b)CMN-负数比较指令c)TST-位测试指令4.Thumb分支指令1)B-分支指令2)BL-带连接的分支指令3)BX-带状态切换的分支指令5.Thumb杂项指令1)SWI-软中断指令6.Thumb伪指令1)ADR-小范围的地址读取伪指令2)LDR-大范围的地址读取伪指令3)NOP-空操作伪指令。

arm汇编指令笔记.

arm汇编指令笔记.

ARM assembler guide DUI0068是一个RISC指令结构,因为有一个加载存储结构。

只有load和store可以读取内存。

ARM的处理器模式可以全部大写或小写,不能混标志符表示一个地址常量的定义格式:1230x1C2_1001ARM编译、链接后最终生成一个ELF格式(Executable and Linking Format)的可执行文件(后缀.axf)ELF中是分section部分的,一个ELF section在汇编中定义一个section使用AREA指令。

ENTRY指令指示汇编代码第一条要执行的指令。

start是一个标识符,代表一个地址。

结束的方式是产生一个软件中断,把控制权交给调试器。

END指令指示汇编的结束使用cmd进行调试:Microsoft Windows XP [版本5.1.2600](C) 版权所有1985-2001 Microsoft Corp.C:\Documents and Settings\Administrator>cd D:\Program Files\ARM\ADSv1_2\BinC:\Documents and Settings\Administrator>D;'D' 不是内部或外部命令,也不是可运行的程序或批处理文件。

C:\Documents and Settings\Administrator>D:D:\Program Files\ARM\ADSv1_2\Bin>armsd E:\dsparm\pxa270\project\armex\__image.ax fARM Source-level Debugger, ADS1.2 [Build 805]Software supplied by: Team-EFASoftware supplied by: Team-EFAARM7TDMI, BIU, Little endian, Semihosting, Debug Comms Channel, 4GB, Mapfile, Timer, Profiler, Tube, Millisecond [20000 cycles_per_millisecond], Pagetables,IntCtrl, Tracer, RDI CodesequencesObject program file E:\dsparm\pxa270\project\armex\__image.axfarmsd: helphelp [<keyword>]Display help information on one of the following commands:Registers Fpregisters Coproc CRegisters CREGDefCWrite Step Istep Examine ListQuit Obey Go Break Unbreak Watch UNWatch Print CONtext OUtIN WHere BAcktrace Variable SYmbols LSym LEt Arguments LAnguage HelpType CAll WHIle ALias LOadLOG RELoad REAdsyms FInd PUtfile GEtfile LOCalvar COMment PAuse LOADConfig SElectconfig LISTConfig LOADAgent PROfon PROFOFf PROFClear PROFWrite CCin CCOut PROCessor SYS SETregister TRacetrigger TRACEExtent TRACEWrite TRACEStart TRACESTOp TRACEFlushHELP * gives helps on all available commands. To print the help use the LOGcommand to record the help output into a file & print the file.If the first character of a line is the '!' character the rest of the commandline is executed by a call to system(). If the first character of a line isthe '|' character the rest of the line is a treated as a comment.Note that this help is not intended to replace the printed manual whichexplains ARMSD in much greater detail.armsd: LOG** Error: No log filearmsd: stepStep completed at PC = 0x000080040x00008004: 0xe3a01003 .... : mov r1,#3armsd: Registerr0 = 0x0000000a r1 = 0x00000000 r2 = 0x00000000 r3 = 0x00000000r4 = 0x00000000 r5 = 0x00000000 r6 = 0x00000000 r7 = 0x00000000r8 = 0x00000000 r9 = 0x00000000 r10 = 0x00000000 r11 = 0x00000000r12 = 0x00000000 r13 = 0x00000000 r14 = 0x00000000pc = 0x00008004 cpsr = %nzcvqIFt_SVC spsr = %nzcvqift_Reserved_00armsd: stepStep completed at PC = 0x000080080x00008008: 0xe0800001 .... : add r0,r0,r1armsd: Registerr0 = 0x0000000a r1 = 0x00000003r2 = 0x00000000 r3 = 0x00000000r8 = 0x00000000 r9 = 0x00000000 r10 = 0x00000000 r11 = 0x00000000 r12 = 0x00000000 r13 = 0x00000000 r14 = 0x00000000pc = 0x00008008 cpsr = %nzcvqIFt_SVC spsr = %nzcvqift_Reserved_00 armsd: stepStep completed at PC = 0x0000800c0x0000800c: 0xe3a00018 .... : mov r0,#0x18armsd: LOG** Error: No log filearmsd: Registerr0 = 0x0000000d r1 = 0x00000003 r2 = 0x00000000 r3 = 0x00000000 r4 = 0x00000000 r5 = 0x00000000 r6 = 0x00000000 r7 = 0x00000000 r8 = 0x00000000 r9 = 0x00000000 r10 = 0x00000000 r11 = 0x00000000 r12 = 0x00000000 r13 = 0x00000000 r14 = 0x00000000pc = 0x0000800c cpsr = %nzcvqIFt_SVC spsr = %nzcvqift_Reserved_00 armsd: stepStep completed at PC = 0x000080100x00008010: 0xe59f1000 .... : ldr r1,0x00008018 ; = #0x00020026 armsd: Registerr0 = 0x00000018 r1 = 0x00000003 r2 = 0x00000000 r3 = 0x00000000 r4 = 0x00000000 r5 = 0x00000000 r6 = 0x00000000 r7 = 0x00000000 r8 = 0x00000000 r9 = 0x00000000 r10 = 0x00000000 r11 = 0x00000000 r12 = 0x00000000 r13 = 0x00000000 r14 = 0x00000000pc = 0x00008010 cpsr = %nzcvqIFt_SVC spsr = %nzcvqift_Reserved_00 armsd: stepStep completed at PC = 0x000080140x00008014: 0xef123456 V4.. : swi 0x123456armsd: Registerr0 = 0x00000018 r1 = 0x00020026 r2 = 0x00000000 r3 = 0x00000000 r4 = 0x00000000 r5 = 0x00000000 r6 = 0x00000000 r7 = 0x00000000 r8 = 0x00000000 r9 = 0x00000000 r10 = 0x00000000 r11 = 0x00000000 r12 = 0x00000000 r13 = 0x00000000 r14 = 0x00000000pc = 0x00008014 cpsr = %nzcvqIFt_SVC spsr = %nzcvqift_Reserved_00 armsd: stepProgram terminated normally at PC = 0x000080140x00008014: 0xef123456 V4.. : swi 0x123456armsd: Registerr0 = 0x00000018 r1 = 0x00020026 r2 = 0x00000000 r3 = 0x00000000 r4 = 0x00000000 r5 = 0x00000000 r6 = 0x00000000 r7 = 0x00000000 r8 = 0x00000000 r9 = 0x00000000 r10 = 0x00000000 r11 = 0x00000000 r12 = 0x00000000 r13 = 0x00000000 r14 = 0x00000000pc = 0x00008014 cpsr = %nzcvqIFt_SVC spsr = %nzcvqift_Reserved_00 armsd: quitQuittingD:\Program Files\ARM\ADSv1_2\Bin>使用armsd调试有点像微机原理上调试汇编,爽!MOV叫指令,常数范围是0-255LDR叫伪指令都是将常数放到Reg中#和FIELD指令是一样的符号在汇编程序中代表一个地址,可以用在指令中,汇编程序经过汇编器的处理之后,所有的符号都被替换成它所代表的地址值。

arm 汇编 指令

arm 汇编 指令

arm 汇编指令ARM汇编指令是一种用于编写ARM处理器程序的语言。

ARM处理器广泛应用于嵌入式系统和移动设备等领域。

ARM汇编指令与x86汇编指令有所不同,它基于RISC(精简指令集计算机)架构。

下面是一些基本的ARM汇编指令:1. 数据传输指令:用于在寄存器之间传输数据。

例如:- mov:将数据从一个寄存器传输到另一个寄存器。

- ldr:将数据从内存传输到寄存器。

2. 算术指令:用于执行加法、减法、乘法和除法等操作。

例如:- add:加法操作。

- sub:减法操作。

- mull:乘法操作。

- div:除法操作。

3. 逻辑指令:用于执行逻辑操作,如与、或、非等。

例如:- and:与操作。

- or:或操作。

- xor:异或操作。

4. 移位指令:用于对数据进行左移、右移或无符号右移。

例如:- lsr:无符号右移。

- asr:带符号右移。

- ror:循环右移。

5. 比较指令:用于比较两个寄存器的值。

例如:- cmp:比较两个寄存器的值,若相等则返回0,否则返回1。

6. 跳转指令:用于改变程序的执行流程。

例如:- b:条件跳转。

- bl:无条件跳转。

- bx:带状态跳转。

7. 循环指令:用于实现循环操作。

例如:- loop:内部循环。

- ldp:外部循环。

8. 调用指令:用于实现函数调用。

例如:- blx:带状态调用。

- bx:不带状态调用。

9. 系统调用指令:用于实现与操作系统交互的功能。

例如:- swi:执行系统调用。

10. 存储器访问指令:用于访问内存数据。

例如:- str:将数据存储到内存。

- ldr:从内存中加载数据。

以上仅为ARM汇编指令的一部分,实际上,ARM汇编指令还有很多其他功能。

为了更好地理解和使用ARM汇编指令,可以参考相关的教程和手册,并进行实际操作。

arm 浮点数的比较汇编指令

arm 浮点数的比较汇编指令

arm 浮点数的比较汇编指令ARM浮点数比较汇编指令,在ARM体系结构中,主要有三种浮点数比较指令:FCCMPE(float compare compare NaN and set EFLAGS)、FCMPE(float compare setting EFLAGS)和FCMP(float compare 比较两个单精度的浮点数,并设置条件标志位)。

下面我们一步步来了解这三种浮点数比较指令:1. FCCMPE指令FCCMPE指令进行的是浮点数比较操作,并且会比较NaN(非数字),最后会将标志位设置为0或1。

使用FCCMPE指令的语法如下:FCCMPE Dn, Dm其中,Dn和Dm是两个浮点寄存器,用于比较操作。

指令执行后,标志位将被设置为0或1。

如果Dn和Dm中的一个是NaN,那么标志位将被设置为1,否则为0。

2. FCMPE指令FCMPE指令执行浮点数比较操作,并将比较结果存储在条件码寄存器中。

使用FCMPE指令的语法如下:FCMPE Dn, Dm其中,Dn和Dm是两个浮点寄存器,用于比较操作。

指令执行后,条件码寄存器中的标志位将被设置为:* Z(位0):结果为零时设置为1。

* N(位1):结果为负数时设置为1。

* C(位2):无符号数操作中,表示结果比较时进位或借位。

在有符号数操作中,表示结果的最高位(符号位)。

3. FCMP指令FCMP指令比较两个单精度的浮点数,并设置条件标志位。

使用FCMP指令的语法如下:FCMP Dn, Dm其中,Dn和Dm是两个浮点寄存器,用于比较操作。

指令执行后,条件码寄存器中的标志位将被设置为:* Z(位0):结果为零时设置为1。

* N(位1):结果为负数时设置为1。

* C(位2):无符号数操作中,表示结果比较时进位或借位。

在有符号数操作中,表示结果的最高位(符号位)。

综上所述,ARM浮点数比较汇编指令主要有三种:FCCMPE、FCMPE 和FCMP。

它们在比较操作时的表现略有不同,但最终都会将比较结果存储在标志位或条件码寄存器中,方便程序对比较结果进行判断和处理。

ARM指令集详解--汇编

ARM指令集详解--汇编

ARM指令集详解--汇编1. 汇编1.1. 通⽤通⽤寄存器37个寄存器,31个通⽤寄存器,6个状态寄存器,R13指针sp,R14返回指针,R15为PC指针, cpsr_c代表的是这32位中的低8位,也就是控制位CPSR有4个8位区域:标志域(F)、状态域(S)、扩展域(X)、控制域(C)MSR - Load specified fields of the CPSR or SPSR with an immediate constant, orfrom the contents of a general-purpose register. Syntax: MSR{cond} _, #immed_8rMSR{cond} _, Rm where: cond is an optional condition code. is either CPSR orSPSR. specifies the field or fields to be moved. can be one or more of: ccontrol field mask byte (PSR[7:0]) x extension field mask byte (PSR[15:8]) sstatus field mask byte (PSR[23:16) f flags field mask byte (PSR[31:24]).immed_8r is an expression evaluating to a numeric constant. The constant mustcorrespond to an 8-bit pattern rotated by an even number of bits within a32-bit word. Rm is the source register.C 控制域屏蔽字节(psr[7:0])X 扩展域屏蔽字节(psr[15:8])S 状态域屏蔽字节(psr[23:16])F 标志域屏蔽字节(psr[31:24])CPSR寄存器FIQ和IRQ的区别?MODE(以下为⼆进制)10000⽤户模式PC,CPSR,R0~R1410001FIQ PC,CPSR,SPSR_fiq,R14_fiq~R8_fiq,R7~R010010IRQ PC,CPSR,SPSR_irq,R14_irq~R13_irq,R12~R010011管理模式(svc)PC,CPSR,SPSR_svc,R14_svc~R13_svc,R12~R010111终⽌模式PC,CPSR,SPSR_abt,R14_abt~R13_abt,R12~R011011未定义PC,CPSR,SPSR_und,R14_und~R13_und,R2~R011111系统模式(sys)PC,CPSR,R14 ~R01.2. 指令格式1) 基本格式<opcode>{<cond>}{S} <Rd>,<Rn>{,<opcode2>}其中,<>内的项是必须的,{}内的项是可选的,如<opcode>是指令助记符,是必须的,⽽{<cond>}为指令执⾏条件,是可选的,如果不写则使⽤默认条件AL(⽆条件执⾏)。

ARM3_汇编指令

ARM3_汇编指令

ARM3_汇编指令16位数据操作指令名字功能ADC 带进位加法(ADD with Carry)ADD 加法AND 按位与。

这里的按位与和C的”&”功能相同ASR 算术右移(Arithmetic Shift Right)BIC 按位清零(把一个数跟另一个无符号数的反码按位与)CMN 负向比较(把一个数跟另一个数据的二进制补码相比较)CMP 比较(Compare,比较两个数并且更新标志)CPY 把一个寄存器的值拷贝(COPY)到另一个寄存器中EOR 近位异或LSL 逻辑左移(Logic Shift Left)LSR 逻辑右移(Logic Shift Right)MOV 寄存器加载数据,既能用于寄存器间的传输,也能用于加载立即数MUL 乘法(Multiplication)MVN 加载一个数的NOT值(取到逻辑反的值)NEG 取二进制补码ORR 按位或ROR 循环右移SBC 带借位的减法SUB 减法(Subtraction)TST 测试(Test,执行按位与操作,并且根据结果更新Z)REV 在一个32位寄存器中反转(Reverse)字节序REVH 把一个32位寄存器分成两个(Half)16位数,在每个16位数中反转字节序REVSH 把一个32位寄存器的低16位半字进行字节反转,然后带符号扩展到32位SXTB 带符号(Signed)扩展一个字节(Byte)到32位SXTH 带符号(Signed)扩展一个半字(Half)到32位UXTB 无符号(Unsigned)扩展一个字节(Byte)到32位UXTH 无符号(Unsigned)扩展一个半字(Half)到32位16位转移指令名字功能B 无条件转移(Branch)B 有条件(Condition)转移BL 转移并连接(Link)。

用于呼叫一个子程序,返回地址被存储在LR中CBZ 比较(Compare),如果结果为零(Zero)就转移(只能跳到后面的指令)CBNZ 比较,如果结果非零(Non Zero)就转移(只能跳到后面的指令)IT If-Then16位存储器数据传送指令名字功能LDR 从存储器中加载(Load)字到一个寄存器(Register)中LDRH 从存储器中加载半(Half)字到一个寄存器中LDRB 从存储器中加载字节(Byte)到一个寄存器中LDRSH 从存储器中加载半字,再经过带符号扩展后存储一个寄存器中LDRSB 从存储器中加载字节,再经过带符号扩展后存储一个寄存器中STR 把一个寄存器按字存储(Store)到存储器中STRH 把一个寄存器存器的低半字存储到存储器中STRB 把一个寄存器的低字节存储到存储器中LDMIA 加载多个字,并且在加载后自增基址寄存器STMIA 存储多个字,并且在存储后自增基址寄存器PUSH 压入多个寄存器到栈中POP 从栈中弹出多个值到寄存器中其它16位指令名字功能SVC 系统服务调用(Service Call)BKPT 断点(Break Point)指令。

ARM汇编指令集详解大汇总

ARM汇编指令集详解大汇总

ARM汇编指令集详解大汇总——《常用ARMv4指令集及汇编》和《ARM汇编指令集》前言零零散散用了大概一周的时间,在《常用ARM指令集及汇编》(2003年12月1日)的基础上,大致学习了一遍ARM指令集和汇编,看的过程当中更正了一些错误的地方,并结合其它资料适当添加了一些内容,也做了一些删减,现分享出来,希望能帮助到需要的人。

文中必然还有一些错误还有待改进,有些地方还需要解释的更加详细,本人精力有限,希望有心的读者,订正并增加注释,最好也分享出来,以方便大家对ARM指令的深入理解。

作为刚入行的新手,不谦虚的推荐几本书:《ARM体系结构与编程-杜春雷》,《嵌入式系统体系结构、编程与设计-Raj Kamal著,贾建斌译》,《嵌入式系统:采用公开源代码和StrongARM_XScale处理器-毛德操》。

这几本书到底好不好,看个人需求和喜好吧,仁者见仁智者见智。

最后,感谢《常用ARM指令集及汇编》的原作者和其它资料的作者让我有机会学习我不熟悉的东西,谢谢。

learllp2015-11-09目录常用ARM v4指令集及汇编........................................................................ 错误!未定义书签。

前言................................................................................................................................................ I I 目录. (IV)ARM v4指令集及汇编 (1)一、ARM处理器寻址方式 (1)寄存器寻址 (1)立即寻址 (1)寄存器偏移寻址 (1)寄存器间接寻址 (2)基址寻址 (2)多寄存器寻址 (3)堆栈寻址 (3)块拷贝寻址 (3)相对寻址 (3)二、指令集介绍 (4)ARM指令集 (4)指令格式 (4)基本格式 (4)第2个操作数 (4)1.#immed_8r常数表达式 (5)2.Rm 寄存器方式 (5)3.Rm,shift寄存器移位方式 (5)条件码 (6)ARM 存储器访问指令 (6)◆LDR和STR (7)◆LDM和STM (9)◆SWP (12)ARM 数据处理指令 (12)数据传送指令 (13)算术逻辑运算指令 (13)比较指令 (15)乘法指令 (16)ARM 跳转指令 (17)ARM 协处理器指令 (18)ARM 杂项指令 (19)ARM 伪指令 (21)Thumb 指令集 (23)Thumb 指令集与ARM 指令集的区别 (23)跳转指令 (24)数据处理指令 (24)单寄存器加载和存储指令 (24)批量寄存器加载和存储指令 (24)Thumb 存储器访问指令 (24)伪指令 (26)符号定义伪指令 (26)数据定义伪指令 (28)报告伪指令 (32)汇编控制伪指令 (33)杂项伪指令 (35)◆AREA (36)◆CODE16 和CODE32 (37)◆END (37)◆ENTRY (37)◆EQU (37)◆EXPORT 和GLOBAL (38)◆IMPORT 和EXTERN (38)◆GET 和INCLUDE (38)◆INCBIN (39)◆KEEP (39)◆NOFP (39)◆REQUIRE (39)◆PEQUIRE8 和PRESERVE8 (39)◆RN (39)◆ROUT (40)ARM 伪指令 (40)◆ADR (40)◆ADRL (40)◆LDR (40)◆NOP (41)◆LDFD (41)◆LDFS (41)三、ARM汇编程序设计 (41)文件格式 (41)ARM 汇编的一些规范 (41)汇编语句格式 (41)标号 (42)基于PC 的标号 (42)基于寄存器的标号 (42)绝对地址 (42)局部标号 (43)符号 (43)常量 (43)数字常数 (43)字符常量 (44)布尔常量 (44)段定义 (44)宏定义及其作用 (44)子程序的调用 (45)数据比较跳转 (45)循环 (46)数据块复制 (46)栈操作 (46)特殊寄存器定义及应用 (47)散转功能 (47)查表操作 (47)长跳转 (47)对信号量的支持 (48)伪指令使用 (48)一个完整的例子 (48)外围部件控制 (48)四、C与汇编混合编程 (49)内嵌汇编 (49)内嵌汇编的指令用法 (50)内嵌汇编器与armasm 汇编器的差异 (51)内嵌汇编注意事项 (51)访问全局变量 (52)C与汇编相互调用 (53)寄存器的使用规则 (53)堆栈使用规则 (53)参数传递规则 (54)C程序调用汇编程序 (54)调用汇编的C函数: (54)汇编程序调用C程序 (55)五、ARM 指令集列表 (55)ARM 存储器访问指令表列表 (55)ARM 数据处理指令列表 (57)ARM 乘法指令列表 (58)ARM 跳转指令列表 (59)ARM 协处理器指令列表 (60)ARM 杂项指令列表 (61)ARM 伪指令列表 (62)六、Thumb 指令集列表 (120)Thumb 存储器访问指令列表 (120)Thumb 数据处理指令列表 (121)Thumb 跳转指令及软中断指令列表 (122)Thumb 伪指令列表 (123)七、汇编预定义变量及伪指令 (124)预定义的寄存器和协处理器名 (124)通用寄存器 (124)程序状态寄存器 (124)浮点数寄存器 (124)协处理器及协处理器寄存器 (125)八、内置变量列表 (125)九、伪指令列表 (126)十、指令条件码列表 (128)十一、CPSR 和S PSR 分配图 (129)ARM v4指令集及汇编ARM 处理器是基于精简指令集计算机(RISC)原理设计的,指令集和相关译码机制较为简单,具有32 位ARM 指令集和16 位Thumb 指令集。

ARM汇编指令

ARM汇编指令
准确称取氧化锌0.25-0.28g,再加入6mol•L-1HCl溶解氧化锌,用少量蒸馏水冲洗烧 杯内壁,定量转移至250mL容量瓶中,用水稀释至刻度,摇匀。计算锌离子的准确浓 度,贴上标签备用。用移液管移取25.00mL锌离子标准溶液于250mL锥形瓶中,加5mL 缓冲溶液及少量铬黑T指示剂,摇匀,然后用EDTA滴定至溶液由酒红色变为纯蓝色, 即为终点。平行做3次,按下式计算EDTA溶液的物质的量浓度。
2021-8-17
1/57
ARM处理器寻址方式
寻址方式是根据指令中给出的地址码 字段来实现寻找真实操作数地址的方式。
ARM处理器具有几种基本寻址方式:
1. 立即寻址
2. 寄存器直接寻址、寄存器移位寻址
3. 寄存器间接寻址、基址变址寻址
4. 多寄存器直接寻址
5. 相对寻址
6. 堆栈寻址
2/57
立即寻址
9/57
寄存器移位寻址
1. 操作数存放在寄存器中;
2.指令地址码字段给出寄存器编号(名)及移
位表达式;
3.指令执行时取出寄存器值并移位,再将结果
作为源操作数;
寄存器寻址
MOV R0, R2, LSL #3
; R0<=R2×8
逻辑左移3位
R2 0x01
0x08
R0 0x5058
LSL、LSR ASR
前;R索1引=>[R0-4], R0<=R0-4 后;R索0引<=[R1],R1<=R1+4
;R0<=[R1+R2]
12/57
多寄存器直接寻址
内存单元 0x40000000
0xAA
R2 0x40000000 R0 00xxA55A

ARM汇编指令集详解

ARM汇编指令集详解

ARM汇编指令集一、跳转指令跳转指令用于实现程序流程的跳转,在ARM程序中有两种方法可以实现程序流程的跳转:Ⅰ.使用专门的跳转指令。

Ⅱ.直接向程序计数器PC写入跳转地址值。

通过向程序计数器PC写入跳转地址值,可以实现在4GB的地址空间中的任意跳转,在跳转之前结合使用MOV LR,PC等类似指令,可以保存将来的返回地址值,从而实现在4GB连续的线性地址空间的子程序调用。

ARM指令集中的跳转指令可以完成从当前指令向前或向后的32MB的地址空间的跳转,包括以下4条指令:1、B指令B指令的格式为:B{条件} 目标地址B指令是最简单的跳转指令。

一旦遇到一个B 指令,ARM 处理器将立即跳转到给定的目标地址,从那里继续执行。

注意存储在跳转指令中的实际值是相对当前PC值的一个偏移量,而不是一个绝对地址,它的值由汇编器来计算(参考寻址方式中的相对寻址)。

它是24 位有符号数,左移两位后有符号扩展为32 位,表示的有效偏移为26 位(前后32MB的地址空间)。

以下指令:B Label ;程序无条件跳转到标号Label处执行CMP R1,#0 ;当CPSR寄存器中的Z条件码置位时,程序跳转到标号Label 处执行BEQ Label2、BL指令BL指令的格式为:BL{条件} 目标地址BL 是另一个跳转指令,但跳转之前,会在寄存器R14中保存PC的当前内容,因此,可以通过将R14 的内容重新加载到PC中,来返回到跳转指令之后的那个指令处执行。

该指令是实现子程序调用的一个基本但常用的手段。

以下指令:BL Label ;当程序无条件跳转到标号Label处执行时,同时将当前的PC值保存到R14中3、BLX指令BLX指令的格式为:BLX 目标地址BLX指令从ARM指令集跳转到指令中所指定的目标地址,并将处理器的工作状态有ARM 状态切换到Thumb状态,该指令同时将PC的当前内容保存到寄存器R14中。

因此,当子程序使用Thumb指令集,而调用者使用ARM指令集时,可以通过BLX指令实现子程序的调用和处理器工作状态的切换。

arm趣味记忆方法

arm趣味记忆方法

arm趣味记忆方法ARM趣味记忆方法ARM是一种广泛应用于嵌入式系统和移动设备的处理器架构。

在学习和掌握ARM架构时,我们可以采用一些趣味的记忆方法,帮助我们更好地理解和记忆相关的知识点。

一、ARM架构简介ARM架构是一种精简指令集计算机(RISC)架构。

它具有高效的能耗和出色的性能,在移动设备、嵌入式系统和其他各种应用中得到广泛应用。

ARM处理器有多种型号和系列,如ARM Cortex-A、Cortex-M和Cortex-R系列等。

每个系列都有不同的特点和应用领域。

二、ARM寄存器ARM架构中有一组寄存器,用于存储和处理数据。

这些寄存器分为通用寄存器、程序状态寄存器和特殊寄存器等。

其中,通用寄存器用来存储临时数据,程序状态寄存器用来存储程序的状态信息,特殊寄存器用来控制处理器的运行。

三、ARM指令集ARM指令集是一组用于控制和操作处理器的指令。

ARM指令集包括数据处理指令、分支指令、访存指令和特权指令等。

这些指令可以完成各种数据处理、跳转、访存和特权操作,实现复杂的计算和控制功能。

四、ARM编程模型ARM编程模型是一种用于编程的抽象模型,它描述了ARM处理器的寄存器和内存的布局。

ARM编程模型包括用户模式和特权模式,用户模式用于用户程序的执行,特权模式用于操作系统的执行。

在编程模型中,寄存器和内存分别有不同的用途和访问权限。

五、ARM汇编语言ARM汇编语言是一种低级语言,用于编写直接运行在ARM处理器上的程序。

ARM汇编语言使用助记符来表示指令和操作数,具有直观和紧凑的特点。

通过学习ARM汇编语言,我们可以更深入地了解ARM架构和指令集。

六、ARM调试和仿真工具在开发和调试ARM程序时,我们可以使用一些专门的工具来辅助我们的工作。

例如,ARM调试器可以用来监控程序的执行和寄存器的状态,ARM仿真器可以用来模拟ARM处理器的运行。

这些工具可以帮助我们定位和解决程序中的问题。

七、ARM应用实例ARM架构广泛应用于各种设备和系统中。

ARM汇编指令对比记忆(整理)

ARM汇编指令对比记忆(整理)

ARM汇编指令对比记忆(整理)1.RichardBlum,ProfeionalAemblyLanguage一.Linu某汇编行结构Linu某ARM汇编中,任何以冒号结尾的标识符都被认为是一个标号,而不一定非要在一行的开始。

【例1】定义一个\的函数,返回两个参数的和。

.ection.te某t,“某”1.LDRLDRR0,=0某3FF5000;伪指令,把0某3FF5000这个地址送给R0LDRR0,0某FF;把立即数0某ff送给R0LDRR0,=&FF;&相当于0某BICR0,R0,#11;.#表示立即数,%表示二进制LDRR1,=0某3ff5000;伪指令R1=0某3FF5000LDRR1,0某3ff5000;存储器访问指令R1=[0某3ff5000]2.adr与ldr比较adrr0,InitSytem;ldrr1,=InitSytem;伪指令adrr0,InitSytem编译时汇编成:ubr0,PC,#offettoInitSytemLDRr1,=InitSytem,这种方式读取的地址值在连接时已经被固定了,这种代码不是位置无关的。

遇到LDR伪指令时,汇编编译器将该地址值保存到一个缓冲区(literalpool)中,然后将该LDR伪指令处理成一条基于PC到该数据缓冲区单元的LDR指令,从而将该地址值读取到寄存器总,这时,要求该数据缓冲区到PC的距离小于4KB。

如果该目标地址值为一个外部地址值或者不在本数据段内,则汇编译器在目标文件中插入一个地址重定位伪操作,当连接器进行连接时生成该地址值。

LDRr1,=InitSytem汇编成:LDRR1,[PC,#offettoLitpool1]------------------------------------------------------adr用来加载地址,例如adrr0,var1ldr用来加载地址处的内容,例如ldrr0,var1上面的这种语法只能从.te某t段中加载但ldrr0,=var1可从任意段中加载地址ldr有伪指令和非伪指令,伪指令后面的立即数前加=ADR在编译时会被替换成一条add或者ub指令,如果替换不了则报错。

ARM-汇编指令集(总结)

ARM-汇编指令集(总结)

ARM-汇编指令集(总结)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 ldrshS(S标志)功能不变,影响CPSR标志位如 mov和movs movs r0, #04. 条件执⾏后缀条件后缀是否成⽴取决于当前代码的前⾯的代码。

ARM比较指令

ARM比较指令

status = op_1 - (- op_2)
CMN 同于 CMP,但它允许你与小负值(操作数 2 的取负的值)进行比较,比如难于用其他方法实现的用于结束列表的 -1。这样与 -1 比较将使用:
CMN R0, #1 ; 把 R0 与 -1 进行比较
明显的,你不需要显式的指定 S 后缀来更改状态标志... 如果你指定了它则被忽略。
Байду номын сангаас
TEQ : 测试等价
(Test Equivalence)
TEQ{条件}{P} <op 1>, <op 2>
Status = op_1 EOR op_2
TEQ 类似于 TST。区别是这里的概念上的计算是 EOR 而不是 AND。这提供了一种查看两个操作数是否相同而又不影响进位标志(不象 CMP 那样)的方法。加上 P 后缀的 TEQ 还可用于改变 R15 中的标志(在 26-bit 模式中)。详情请参照 psr.html,在 32-bit 模式下如何做请参见这里。
TST R0, #%1 ; 测试在 R0 中是否设置了位 0。
详情参照 CMP 指令。
CMP : 比较
(Compare)
CMP{条件}{P} <op 1>, <op 2>
status = op_1 - op_2
CMP 允许把一个寄存器的内容如另一个寄存器的内容或立即值进行比较,更改状态标志来允许进行条件执行。它进行一次减法,但不存储结果,而是正确的更改标志。标志表示的是操作数 1 比操作数 2 如何(大小等)。如果操作数 1 大于操作操作数 2,则此后的有 GT 后缀的指令将可以执行。
比较指令

arm汇编指令总结(不断更新)

arm汇编指令总结(不断更新)

arm汇编指令总结(不断更新)/********************************************************************************* @author Maoxiao Hu* @version V1.0.1* @date Jan-2015******************************************************************************* < COPYRIGHT 2015 ISE of SHANDONG UNIVERSITY >********************************************************************************/本⽂会不时完善和纠正⼀些⼩错误,还请到参考最新版本。

ARM的指令集去哪⾥查才最权威最详细呢?⼀般ARM官⽅⽹站上会有针对你⼿上芯⽚对应指令集的《架构参考⼿册》,可以免费下载。

例如我⼿上的exynos4412是ARM v7-A指令集,那么对应的⼿册就是《arm_architecture_reference_manual ARMv7-A and ARMv7-R edition.pdf》。

在这个⼿册的第A8节:Instruction Details 按照字母顺序详细介绍了ARMv7-A的各种指令语法,700页之多,⽤到时详查即可。

下⾯说⼀下查阅⽂档需要注意的⼏个地⽅。

⼀、指令格式当我们查找⼀些指令⽐如ldrle movne,发现⽆法在⼿册中搜索到,其实并不是没有这些指令,⽽是这些指令是在原始指令ldr mov后⾯加上了条件码(Condition Code)le ne,然后被写到了⼀起。

举个例⼦:LDR的第⼀种指令格式如下,LDR后⾯的<c>就表⽰可以选择后接条件码,当然也可以不接。

arm汇编学习笔记

arm汇编学习笔记

arm汇编学习笔记
1.LDR和MOV的不同
ARM是RISC结构,数据从内存到CPU之间的移动只能通过L/S 指令来完成,也就是ldr/str指令。

比如想把数据从内存中某处读取到寄存器中,只能使用ldr
比如: ldr r0, 0x12345678
就是把0x12345678这个地址中的值存放到r0中。

而mov不能干这个活,mov只能在寄存器之间移动数据,或者把立即数移动到寄存器中,这个和x86这种CISC架构的芯片区别最大的地方。

x86中没有ldr这种指令,因为x86的mov指令可以将数据从内存中移动到寄存器中。

2.汇编的位操作技巧
ldr r0,=rGPBCON;//设置GPB5~GPB8输出端口
ldr r1,=0x55<<10;
3.B与BL的不同
B或BL指令引起处理器转移到“子程序名”处开始执行。

两者的不同之处在于BL指令在转移到子
程序执行之前,将其下一条指令的地址拷贝到R14(LR,链接寄存器)。

由于BL指令保存了下条指令的地
址,因此使用指令“MOV PC ,LR”即可实现子程序的返回。

而B 指令则无法实现子程序的返回,只能实
现单纯的跳转。

4.IMPORT
伪操作告诉编译器当前的符号不是在本源文件中定义的,而是在其他源文件中定义的,在本源文件中可能引用该符号,而且不论本源
文件是否实际引用该符号,该符号都将被加入到本源文件的符号表中。

即后面的标号来自外部文件。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

参考资料:1. Richard Blum,Professional Assembly Language2. GNU ARM 汇编快速入门,/u/31996/showart.php?id=3261463. ARM GNU 汇编伪指令简介,/jb8164/archive/2008/01/22/41661.aspx4. GNU汇编使用经验,/u1/37614/showart_390095.html5. GNU的编译器和开发工具,/blog-htm-do-showone-uid-34335-itemid-81387-type-blog.html6. 用GNU工具开发基于ARM的嵌入式系统,/liren0@126/blog/static/32897598200821211144696/7. objcopy命令介绍,/junhua198310/archive/2007/06/27/1669545.aspx从网上找到一些关于ARM伪指令的资料,现整理如下:一. Linux汇编行结构任何汇编行都是如下结构:[:] [} @ comment[:] [} @ 注释Linux ARM 汇编中,任何以冒号结尾的标识符都被认为是一个标号,而不一定非要在一行的开始。

【例1】定义一个"add"的函数,返回两个参数的和。

.section .text, “x”.global add @ give the symbol add external linkageadd:ADD r0, r0, r1 @ add input argumentsMOV pc, lr @ return from subroutine@ end of program1. LDRLDR R0, =0X3FF5000 ;伪指令,把0X3FF5000这个地址送给R0LDR R0, 0XFF ; 把立即数0xff送给R0LDR R0, =&FF ; &相当于0XBIC R0, R0, #%1011 ;.#表示立即数,%表示二进制LDR R1, =0x3ff5000 ;伪指令 R1=0X3FF5000LDR R1, 0x3ff5000 ;存储器访问指令 R1= [0x3ff5000]2. adr与ldr比较adr r0, InitSystem ;ldr r1, =InitSystem ;伪指令adr r0,InitSystem 编译时汇编成:sub r0,PC,#offset to InitSystemLDR r1,=InitSystem ,这种方式读取的地址值在连接时已经被固定了,这种代码不是位置无关的。

遇到LDR伪指令时,汇编编译器将该地址值保存到一个缓冲区(l iteral pool)中,然后将该LDR 伪指令处理成一条基于PC到该数据缓冲区单元的LD R 指令,从而将该地址值读取到寄存器总,这时,要求该数据缓冲区到PC的距离小于4KB。

如果该目标地址值为一个外部地址值或者不在本数据段内,则汇编译器在目标文件中插入一个地址重定位伪操作,当连接器进行连接时生成该地址值。

LDR r1,=InitSystem 汇编成:LDR R1,[PC,#offset to Litpool1]------------------------------------------------------adr用来加载地址,例如adr r0,var1ldr用来加载地址处的内容,例如ldr r0,var1上面的这种语法只能从.text段中加载但ldr r0,=var1可从任意段中加载地址ldr有伪指令和非伪指令,伪指令后面的立即数前加=ADR在编译时会被替换成一条add或者sub指令,如果替换不了则报错。

相对PC寻址ADRL会被替换成两条指令,替换不了报错误。

相对PC或者积存器寻址这两条指令依据立即数的对齐方式不同,允许的立即数范围也不同。

LDR则是产生文字池的方式加载常量,基于PC的相对寻址,专用加载32bit立即数.通过反汇编可以很容易看出LDR和ADR区别:假设入口点地址为0x8000AREA LDRlabel, CODE, READONLYENTRY ; Mark first instruction to executestartBL func1 ; Branch to first subroutinestopMOV r0, #0x18 ; angel_SWIreason_ReportExceptionLDR r1, =0x20026 ; ADP_Stopped_ApplicationExitLDR r1,=0xffSWI 0x123456 ; ARM semihosting SWIfunc1LDR r0, =start ; => LDR R0,[PC, #offset to Litpool 1]ADR r2,startLDR r1, =Darea +12 ; => LDR R1,[PC, #offset to Litpool 1]ADR r3,Darea+12MOV pc,lr ; ReturnLTORG ; Literal Pool 1Darea SPACE 8000 ; Clears a 8000 byte area of memory,; starting at the current location,; to zero.END反汇编后:start [0xeb000003] bl func1stop [0xe3a00018] mov r0,#0x1800008008 [0xe59f1018] ldr r1,0x00008028 ; = #0x00020026 0000800c [0xe3a010ff] mov r1,#0xff00008010 [0xef123456] swi 0x123456func1 [0xe59f0010] ldr r0,0x0000802c ; = #0x0000800000008018 [0xe24f2020] sub r2,pc,#0x20 ; #0x80000000801c [0xe59f100c] ldr r1,0x00008030 ; = #0x00008040 00008020 [0xe28f3018] add r3,pc,#0x18 ; #0x804000008024 [0xe1a0f00e] mov pc,r1400008028 [0x00020026] dcd 0x00020026&...0000802c [0x00008000] dcd 0x00008000....00008030 [0x00008040] dcd 0x00008040@...Darea [0x00000000] dcd 0x00000000....00008038 [0x00000000] dcd 0x00000000....0000803c [0x00000000] dcd 0x00000000....00008040 [0x00000000] dcd 0x00000000....00008044 [0x00000000] dcd 0x00000000....……….3. MOVMOV加载8位立即数8位立即数即第2操作数,必须可由一个8位常数循环移位偶数位得到,如0xf0000000,0xf00000001都是合法的4. 数据回写例如:ldr r0,[r1]!stmdb sp!,{r0,r4}!用于前索引方式中表示数据回写,例如:ldr r0,[r1,#4]!后索引方式不用!, 数据始终回写,例如:ldr r0,[r1],#4对堆栈方式中用!, 表示堆栈自动增加或者减少访问内存的LDR/STR指令索引方式ldr r0,[r1,#4]前索引, 先加ldr r0,[r1],#4后索引, 后加5. DCD和SPACEDCD分配一个地址并初始化为指定的表达式如 DCD 0x8000就是分配一个32位的地址,其内容是0x8000如果用上标号label,那么这个label相当于一个变量,如label DCD 0X8000这样引用label就是使用了0x8000这个数值。

SPACE分配一段指定长度的内存空间并初始化为0如label SPACE 0x8000就是分配一段长度为0x8000的空间,并初始化为0Data1 DCD 1,2,3Data2 SPACE 12反汇编后的结果:Data1 [0x00000001] dcd 0x00000001 ....00008040 [0x00000002] dcd 0x00000002 ....00008044 [0x00000003] dcd 0x00000003 ....Data2 [0x00000000] dcd 0x00000000 ....0000804c [0x00000000] dcd 0x00000000 ....00008050 [0x00000000] dcd 0x00000000 ....6. LTORG与LDRLTORG是与LDR联合使用的literal pool,可以在函数尾部声明, 这样相对PC偏移最少, 如果不用LTORG, 则编译器自动在(整个)程序末尾声名,但这样偏移有可能太大而编译不通过.ARM立即数,LDR和MOV的区别Mov 是把立即数赋给一个寄存器,但对立即数的范围有要求。

只能是由8bit 连续有效位通过偶数次移位能得到的数。

如果立即数超出这个范围,就没办法用一条MOV指令给寄存器赋值。

LDR除了普通的读数之外,也有给寄存器赋立即数的功能。

你只要写LDR R0,=0xabcdef它没有立即数范围的限制。

因为这是一条伪指令。

如果立即数在MOV的要求内,那就用一条汇编来实现。

如果不在Mov的范围内,就用其它方式实现,如变成两条指令,或从PC偏移地址读一个32位数给寄存器。

MOV是从一个寄存器或者移位的寄存器或者立即数的值传递到另外一个寄存器从本质上是寄存器到寄存器的传递,为什么会有立即数,其实也是有限制的立即数,不是所有立即数都可以传递的这个立即数要符合一个8位数循环右移偶数位的取值原因是,MOV本身就是一条32bit指令,除了指令码本身,它不可能再带一个可以表示32bit的数字,所以用了其中的12bit来表示立即数,其中4bit表示移位的位数(循环右移,且数值x2),8bit用来表示要移位的一个基数。

还有一点是关于ldr的,其实ldr可以装载一个32bit立即数的说法并不确切,因为实际上并不是这一条语句装载了一个32bit立即数,比如ldr r1,=0x12345678其实真正的汇编代码是将某个地址的值传递给r1,就是说需要一个地址存放0x12345678这个立即数,实际上可以看作是一条伪指令而且如果这个立即数可以用mov指令的形式来表达,会被编译器实际用mov 来代替比如:ldr r1,=0x10会变成mov r1,#0x10ARM是RISC结构,数据从内存到CPU之间的移动只能通过L/S指令来完成,也就是ldr/str指令。

相关文档
最新文档