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指令集及汇编ARM7TDMI(-S)指令集及汇编ARM 处理器是基于精简指令集计算机(RISC)原理设计的,指令集和相关译码机制较为简单,ARM7TDMI(-S)具有 32 位 ARM 指令集和16 位 Thumb 指令集,ARM 指令集效率⾼,但是代码密度低,⽽ Thumb 指令集具有更好的代码密度,却仍然保持 ARM 的⼤多数性能上的优势,它是 ARM 指令集的⼦集。

所有 ARM 指令都是可以有条件执⾏的,⽽ Thumb 指令仅有⼀条指令具备条件执⾏功能。

ARM 程序和Thumb 程序可相互调⽤,相互之间的状态切换开销⼏乎为零。

ARM 处理器寻址⽅式寻址⽅式是根据指令中给出的地址码字段来实现寻找真实操作数地址的⽅式,ARM 处理器有 9 种基本寻址⽅式。

寄存器寻址操作数的值在寄存器中,指令中的地址码字段指出的是寄存器编号,指令执⾏时直接取出寄存器值操作。

寄存器寻址指令举例如下:MOV R1,R2;R2 -> R1SUB R0,R1,R2;R1 - R2 -> R0⽴即寻址⽴即寻址指令中的操作码字段后⾯的地址码部分就是操作数本⾝,也就是说,数据就包含在指令当中,取出指令也就取出了可以⽴即使⽤的操作数(⽴即数)。

⽴即寻址指令举例如下:SUBS R0,R0,#1 ;R0 – 1 -> R0MOV R0,#0xff00 ;0xff00 -> R0 ⽴即数要以“#”为前缀,表⽰ 16 进制数值时以“0x”表⽰。

寄存器偏移寻址寄存器偏移寻址是ARM指令集特有的寻址⽅式,当第2操作数是寄存器偏移⽅式时,第 2 个寄存器操作数在与第 1 个操作数结合之前,选择进⾏移位操作。

寄存器偏移寻址⽅式指令举例如下:MOV R0,R2,LSL #3 ;R2 的值左移 3 位,结果放⼊ R0,即 R0 = R2 * 8ANDS R1,R1,R2,LSL R3 ;R2 的值左移 R3 位,然后和 R1 相与操作,结果放⼊ R1 可采⽤的移位操作如下:LSL:逻辑左移(Logical Shift Left),寄存器中字的低端空出的位补 0LSR:逻辑右移(Logical Shift Right),寄存器中字的⾼端空出的位补 0ASR:算术右移(Arithmetic Shift Right),移位过程中保持符号位不变,即如果源操作数为正数,则字的⾼端空出的位补 0,否则补 1 ROR:循环右移(Rotate Right),由字的低端移出的位填⼊字的⾼端空出的位 RRX:带扩展的循环右移(Rotate Right eXtended by1place),操作数右移⼀位,⾼端空出的位⽤原 C 标志值填充。

ARM笔记

ARM笔记

ARM处理器结构ARM处理器模式处理器模式用户user FIQ fiq IRQ irq 管理svc 终止abt 未定义und 系统sys寄存器组织ARM处理器共有37个寄存器31个通用寄存器,包括程序计数6个状态寄存器,都是32位,但寄存器R13通常用作指针堆栈,寄存器R14用作子程序链接寄存CPSR在所有处理器模式下都可以访问当前程序状态寄存器CPSR。

CPSR包含条件码标志、中断禁止位31302928765NZ C VDNM(RAZ)I F T条件码标志N 本位设置成当前指令运算结果的bit[31]的值。

当两个表示的有符号整数运算时,n=1表示运算Z z=1表示运算的结果为零;z=0表示运算的结果不为零。

对于CMP 指令,Z=1表示进行比较的两C在加法指令中(包括比较指令CMN ),当结果产生了进位,则C=1,表示无符号运算发生溢出(ov 在减法指令中(包括比较指令CMP ),当运算中发生借位,则C=0,表示无符号运算数发生进对于包含移位操作的非加减运算指令,C中包含最后一次溢出的位的数值对于其他非加减运算指令,C 位的值通常不受影响V 对于加减运算指令,当操作数和运算结果为二进制的补码表示的带符号数时,V=1表示符号位溢控制位I置1则禁止IRQ中断F 置1则禁止FIQ中断模式位CPSR(当前程序状态寄存器)在任何处理器模式下被访问。

它包含了条件标志位、中断禁止位、当前处理器一个专用的物理状态寄存器,称为SPSR (备份程序状态寄存器)。

当特定的异常中断发生时,这个寄存器SPSR 来恢复CPSR 。

由于用户模式和系统模式不是异常中断模式,所以他没有SPSR 。

当用户在用户模式T T=0表示执行ARM 指令T=1表示执行Thumb 指令R10 ------ R10 ------ R10 R10_fiq sl R11 ------ R11 ------ R11 R11_fiq fp R12 ------ R12 ------ R12 R12_fiq ip R13 R13_svc R13_irq R13_fiq sp R14 R14_svc R14_irq R14_fiq lr .-------------R15/PC-------------PC R4 ------- R4 ------- R4 ------- R4 v1R5 ------- R5 ------- R5 ------- R5 v2R6 ------- R6 ------- R6 ------- R6 v3R7 ------- R7 ------- R7 ------- R7 v4R8 ------- R8 ------- R8 R8_fiq v5R9 ------- R9 ------- R9 R9_fiq v6User 模式 SVC 模式 IRQ 模式 FIQ 模式 APCS R0 ------- R0 ------- R0 ------- R0 a1R1 ------- R1 ------- R1 ------- R1 a2R2 ------- R2 ------- R2 ------- R2 a3R3 ------- R3 ------- R3 ------- R3 a432位ALU(是算术逻辑单元,是能实现多组算术运算和逻辑运算的组合逻辑电路)31个32位通用寄存器6位状态寄存器32*8位乘法器32*32位桶形移位寄存器指令译码及控制逻辑,指令流水线和数据/地址寄存器组成M[4:0]模式可访问的寄存器ob10000 user 0b10001 FIQ 0b10010 IRQ 0B10011 管理0b10111中止0b11011未定义0b11111系统Thumb状态的寄存器集Thumb状态寄存器与A系统和用户FIQ 管理中止IRQ 未定义R0R0R0R0R0R0R0R1R1R1R1R1R1R1R2R2R2R2R2R2R2R3R3R3R3R3R3R3R4R4R4R4R4R4R4R5R5R5R5R5R5R5R6R6R6R6R6R6R6R7R7R7R7R7R7R7SP SP_fiq*SP_svc*SP_abt*SP_irq*SP_und*LR LR_fiq*LR_svc*LR_abt*LR_irq*LR_und*PCPC PC PC PC PCSP LR PC CPSR SPSRARM异常异常向量表异常类型模式复位管理0x0000 00000xFFFF 0000未定义指令未定义0x0000 00040xFFFF 0004软件中断(SWI)管理0x0000 00080xFFFF 0008预取中止(取指令存储器中止)中止0x0000 000C 0xFFFF 000C 数据中止(数据访问存储器中止)中止0x0000 00100xFFFF 0010IRQ(中断)IRQ 0x0000 00180xFFFF 0018FIQ(快速中断)FIQ 0x0000 001C 0xFFFF 001C 当异常出现时,异常模式分组的R14和SPSR用于保存状态。

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指令是一样的符号在汇编程序中代表一个地址,可以用在指令中,汇编程序经过汇编器的处理之后,所有的符号都被替换成它所代表的地址值。

3.ARM汇编指令集

3.ARM汇编指令集
3--寄存器移位
(2)算术指令: ADD ADC SUB SBC RSB RSC
逻辑指令: AND ORR EOR BIC
比较指令: CMP CMN TST TEQ
数据搬移: MOV MVN
(3)加法指令 ADD R1,R2,R3 @ R1=R2+R3
64位乘法: MULL R0, R1, R2, R3 @{R1:R0}=R2*R3
【6】分支指令(偏移,跳转)
(1)指令格式
B{<cond>} label
BL{<cond>} subroutine_label
(2) b -- 无返回的跳转 -- c语言的goto
【1】测试一:
(1)mov r0,#16
mov r0,r1,ASR #4
MUL r1,r2,#3
mvn r0,r0 @r0=~r0
add r0,r0,#1
RSB R0,R0,#0 @R0 = 0-R0
比如:(1)0x1122
(2)0x8000007F
01 0001 0010 0010
0000 0000 0000 0000 0000 | 0111 1111 10| 00
用伪指令:
ldr r1,#0x1122
数据传输指令 MOV R1,R2 @ R1=R2
取反传送指令 MVN R1,R2 @ R1= ~R2
【2】乘法指令
32位乘法: MUL R1,R2,R3 @R1=R2*R3
mov r3,r1,LSL #2 @r3=r1*4=4
【8】立即数
(1)立即数:就是满足一定规则的数。
这个数可以用一个8位的数循环右移0--30之间的偶数位形成。

ARM指令集学习总结(转载)

ARM指令集学习总结(转载)

ARM指令集学习总结(转载)2008-11-24 01:12:37ARM指令集比较简单,本文介绍ARM指令集中需要注意和不易理解的地方。

一、ARM指令集是32位的,程序的启动都是从ARM指令集开始,包括所有异常中断都是自动转化为ARM状态,并且所有的指令都可以是有条件执行的。

二、ARM指令集是Load/Store型的,只能通过Load/Store指令实现对系统存储器的访问,而其他的指令都是基于处理器内部的寄存器操作完成的,这和INTEL汇编是不同的,初学者很不易理解。

三、指令的后缀:"S" 可选后缀,若指定S,则根据指令执行的结果更新CPSR中的条件码。

很多初学着不知道怎么更新,若这条指令执行完以后,对AR M程序状态寄存器的条件码标志(N,Z,C,V)的影响。

"! " 表示在完成数据操作以后,将更新基址寄存器,并且不消耗额外的时间。

如:LDR R0, [R1, #4] 他相当于R0 <- mem32[R1+4]R1 = R1+4;"^" LDMFD R13!, (R0-R3, PC)^ //"^"表示一条特殊形式的指令。

(在从存储器中装入PC的同时,CPSR也得到恢复)。

四、#号后面加0x或&表示十六进制:#0xFF, #&FF#号后面加0b表示二进制。

#号后面加0d表示十进制。

*******************************************************************************五、立即数寻址每个立即数都是采用一个8位的常数循环右移偶数位间接得到。

初学者不易理解:一个32位的指令不可能全部用来保存32位的立即数,所以从指令的编码格式上分析,在指令编码中只分配了12位来存储立即数,其中4位用来保存右循环值,8位用来保存一个常数,所以并不是每一个32位的立即数都是合法的。

ARM汇编学习笔记

ARM汇编学习笔记

这两天参加了一个编写操作系统的项目,因为要做很多底层的东西,而且这个操作系统是嵌入式的,所以开始学习ARM汇编,发现ARM汇编和一般PC平台上的汇编有很多不同,但主要还是关键字和伪码上的,其编程思想还是相同的。

现将一些学习感悟部分列出来,希望能给有问题的人一点帮助。

1、ARM汇编的格式:在ARM汇编里,有些字符是用来标记行号的,这些字符要求顶格写;有些伪码是需要成对出现的,例如ENTRY和END,就需要对齐出现,也就是说他们要么都顶格,要么都空相等的空,否则编译器将报错。

常量定义需要顶格书写,不然,编译器同样会报错。

2、字符串变量的值是一系列的字符,并且使用双引号作为分界符,如果要在字符串中使用双引号,则必须连续使用两个双引号。

3、在使用LDR时,当格式是LDR r0,=0x022248,则第二个参数表示地址,即0x022248,同样的,当src变量代表一个数组时,需要将r0寄存器指向src 则需要这样赋值:LDR r0,=src 当格式是LDR r0,[r2],则第二个参数表示寄存器,我的理解是[]符号表示取内容,r2本身表示一个寄存器地址,取内容候将其存取r0这个寄存器中。

4、在语句:CMP r0,#numBHS stop书上意思是:如果r0寄存器中的值比num大的话,程序就跳转到stop标记的行。

但是,实际测试的时候,我发现如果r0和num相等也能跳转到stop 标记的行,也就是说只要r0小于num才不会跳转。

下面就两个具体的例子谈谈ARM汇编(这是我昨天好不容易看懂的,呵呵)。

第一个是使用跳转表解决分支转移问题的例程,源代码如下(保存的时候请将文件后缀名改为s):AREA JumpTest,CODE,READONLYCODE32num EQU 4ENTRYstartMOV r0, #4MOV r1, #3MOV r2, #2MOV r3, #0CMP r0, #numBHS stopADR r4, JumpTableCMP r0, #2MOVEQ r3, #0LDREQ pc, [r4,r3,LSL #2]CMP r0, #3MOVEQ r3, #1LDREQ pc, [r4,r3,LSL #2]CMP r0, #4MOVEQ r3, #2LDREQ pc, [r4,r3,LSL #2]CMP r0, #1MOVEQ r3, #3LDREQ pc, [r4,r3,LSL #2]DEFAULTMOVEQ r0, #0SWITCHENDstopMOV r0, #0x18LDR r1, =0x20026SWI 0x123456JumpTableDCD CASE1DCD CASE2DCD CASE3DCD CASE4DCD DEFAULTCASE1ADD r0, r1, r2B SWITCHENDCASE2SUB r0, r1, r2B SWITCHENDCASE3ORR r0, r1, r2B SWITCHENDCASE4AND r0, r1, r2B SWITCHENDEND程序其实很简单,可见我有多愚笨!还是简要介绍一下这段代码吧。

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

ARM汇编指令集:
指令:汇编指令是CPU机器指令的助记符,经过编译后会得到一串1、0组成的机器码,可以由CPU读取执行
伪指令:在编译过程中间起作用,用来指导编译过程,经过编译后不会生成机器码
***ARM汇编特点1:LDR/STR架构:在RISC架构中,cpu读写内存需要通过CPU内部的寄存器(CISC的CPU可以直接和内存通信)
***ARM汇编特点2:8中寻址方式
#寄存器寻址mov r1,r2 把r2里面的内容送到r1里面去(寄存器靠名字找的)
#立即寻址(立即数)mov r0,#0xFF00 加#表示数字
#寄存器移位寻址mov r0, r1, lsl #3 lsl左移指令,把r1的值左移三位,然后把左移后生成的那个数赋值给r0
#寄存器间接寻址ldr r1, [r2] [r2]表明内存地址存在r2中,然后把内存地址里面存储的那个值赋给r1
基址变址寻址ldr r1, [r2, #4]
[r2,#4]中存储的地址为r2中的地址+4构成的地址,r2里面存储的地址称为基地址,后面的数字就是需要的变址数这条指令的意思:把r2存储的内存地址加4的地址的值赋值给r1 #多寄存器寻址ldmia r1!, {r2-r7, r12}
一次访问多个寄存器//////r1放的内存地址,把r1理解为数组,r2-r7,r12表示7个寄存器,这句指令的意思就是:r1当中存储的内存地址为基地址,然后把从这个地址开始的连续七个地址当中存储的值,依次放在后面对应的寄存器中
#堆栈寻址stmfd sp!, {r2-r7, lr}
#相对寻址beq flag
flag:标号
***ARM汇编特点3:指令后缀
同一指令经常附带不同后缀,变成不同的指令。

经常使用的后缀有:
B(byte)功能不变,操作长度变为8位
H(half word)功能不变,长度变为16位
S(signed)功能不变,操作数变为有符号
如ldr ldrb ldrh ldrsb ldrsh
S(S标志)功能不变,影响CPSR标志位一般用在数据传输指令
如mov和movs movs r0, #0
***ARM汇编特点4:条件执行后缀
mov r0,r1 @相当于C语言的r0 = r1
moveq r0,r1 @如果eq后缀成立,则执行本句指令,反之,则不执行
条件后缀执行注意两点:
1.条件后缀是否成立,不是取决于本句代码,而是取决于这句代码之前的代码运行后的结果
2.条件后缀决定了本句代码是否会执行,而不会影响上一句或下一句代码是否会执行
***ARM汇编特点5:多级指令流水线
pc指向正在被取指的指令,而非正在执行的指令
******数据传输指令
mov r1,r0 @两个寄存器之间传递数据
mov r1,#12fff @把立即数赋值给目标寄存器
mvn 和mov 用法一样区别是mov原封不动传递,mvn是按位取反传递
******逻辑指令
and 逻辑与
orr 逻辑或
eor 逻辑异或
bic 位清除指令bic r0,r1,#0x1f 将r1中的数的bit0到bit4 (#0x1f为1的位清零)清零后赋值给r0
******比较指令
cmp
cmn 看两个值是否互补
tst test r0,#0xf @测试r0的0~3位是不是为0
teq 测试等价
比较指令用来比较两个寄存器中的数
比较指令不用后加S后缀就可以影响cpsr中的标志位
******常用ARM指令
cpsr访问指令:mrs & msr
mrs用来读psr ,msr 用来写psr
cpsr寄存器比较特殊,需要专门的指令访问,这就是mrs和msr
******跳转指令
b & bl & bx
b: 直接跳转
bl(branch and link):跳转前把返回地址放入lr中,以便返回,用于函数调用
*******访存指令
ldr /str / ldm / stm / swp
单个字/半字/字节访问:ldr/str
多字批量访问:ldm/stm
swp:内存和寄存器互换指令
swp r1,r2,[r0] 把r0存的地址的内容放到r1里面去,然后把r2的内容放到r0存的地址的内存中去
swp r1,r1,[r0]
******************************
合法立即数与非法立即数
ARM指令都是32位,除了指令标记和操作标记外,本身只能附带很少位数的立即数。

因此立即数有合法和非法之分。

合法立即数:经过任意位数的移位后非零部分可以用8位表示的即为合法立即数
**************
协处理器cp15的操作指令
mcr& mrc
mrc用于读取cp15中的寄存器
mcr用于写入cp15中的寄存器
*******************
由于ldr/str每周期只能访问4字节内存,如果需要批量读取,写入内存时太慢,解决的方案就是ldm/stm
ldm/stm与栈的处理
ldm (load register mutiple)
stm (store register mutiple)
****************************************************************
!的作用:r0值在ldm过程中发生的增加或减少写回到r0去,也就是ldm在运算过程中会改变r0中的地址值,如果没有!,则r0中的地址值不发生变化,如果有!,则r0中的值,会发生相应的改变
ldmia r0,{r2,r3}
ldmia r0!,{r2,r3}
^的作用:在目标寄存器中有PC时,会同时将spsr写入到cpsr(异常返回的时候)
ldmfd sp!,{r0-r6,pc}
ldmfd sp!,{r0-r6,pc}^
四种栈
空栈:空栈就是当需要往栈中加入内容的时候,直接将内容存入栈指针所指向的地址空间,然后在将栈指针指向下一个空的地址空间,而要取出内容时则需要先移动指针才能去除
满栈:满栈就是栈指针始终指向栈的最后一格,每次需要存储内容时,都需要先移动栈指针,然后把你内容存入栈指针所指向的地址空间,当要取出内容的时候不用移动指针直接可以取出
增栈栈指针移动的时候,往地址值增加的方向移动
减栈栈指针移动的时候,往地址值减小的方向移动
**********************************************************
伪指令
@用来做注释
#做注释一般用来放做行首,表示这一行都是注释而不是代码
:以冒号结尾的是标号
.点号在gnu汇编中表示当前指令的地址
立即数前面要加#或者$,表示这个数是立即数。

相关文档
最新文档