数据处理指令1.数据传送(MOV MVN)2.算术运算(ADD ADC SUB SBC RSB RSC)3.位运算(AND ORR EOR BIC)4.比较测试(CMP CMN TST TEQ)操作码{条件码}S 目标寄存器,第一源操作数,第二源操作数1.数据传送指令无第一源操作数2.比较测试指令无目标寄存器3.比较测试指令不加S,结果影响NZCV4.第一源操作数是寄存器5.第二源操作数有:8位图立即数,寄存器,寄存器移位(LSL,LSR,ASR,ROR,RRX)6.S:1.目标寄存器为PC,CPSR=SPSR2.目标寄存器不为PC,结果影响NZCV7.加法,C进位,有进位,C=1,无进位,C=08.减法,C借位,有借位,C=0,无借位,C=11-10累加和arm-linux-as -g -o sum.o sum.s arm-linux-ld -e _start -o sum sum.oqemu-arm -g 1234 sumarm-linux-gdb sum最大公约数的求解20=5X412=3X4= 2X4R0=20R1=12R0==R1?20!=12R0=R0-R1=20-12=8R1=R1-R0=12-8=4R0=R0-R1=8-4=4while(R0 != R1){if(R0 >= R1){R0 = R0 – R1;}else{R1 = R1 – R0;}}跳转指令数据处理指令(传送,加法,减法,位运算,比较测试)mov r1, #0x56从存储器中获得,怎么办?加载指令:将数据从存储器中读到寄存器存储指令:将处理完毕的数据(寄存器)存储回存储器实现了寄存器与存储器之间的数据交互单寄存器多寄存器单寄存器字和无符号字节的加载,存储指令单寄存器的字加载指令LDR{cond} Rd, <地址模式> 功能:将指定地址单元<地址模式>的字数据读入Rd中。
单寄存器的无符号字节加载指令LDR{cond}B Rd, <地址模式> 功能:将指定<地址模式>地址单元中的字节数据读入Rd中,字节数据放在Rd的低8位,高24bit用0填充<地址模式>:数据来源Rd:目标寄存器示例LDR R1, [R2]R2=0x20008000R1是0x20008000地址中的数据LDR PC, [R0, #8]LDRB R1, [R2], #1R2=0x20008000 0x56R1=0x56R2=R2+1=0x20008001LDR R1, [PC, R3]LDR R1,[R2, R3, LSL #2]LDREQB R1,[R2, R3]LDR R0, [R0, #8]! @×基址与目标寄存器不一样单寄存器字和无符号字节存储指令语法格式STR{cond} Rd, <地址模式>功能:将Rd寄存器的字数据存储到由<地址模式>指定的地址中STR{<cond>}B Rd, <地址模式>功能:将寄存器中一个字节数据保存到<地址模式>指定的地址中Rd:源寄存器<地址模式>:数据需要存储到的目标地址示例STR R1, [R2]STR R1, [R2], #1STR R1, [R2, R3]STRB R0, [R1, R2, ASR #2]STREQB R0, [R1, R2, LSL #2]STR PC, [R0, #8] [PC, #8] 单元内容STR R0, [R0, #8]! @×1 .零偏移LDR R0, [R1] //将R1指定的地址中的数据加载到R0R0=0xe92d48002. [<Rn>, #+/-<offset_12>] 偏移量为立即数(12bit)LDR R0, [R1,#0x8] ;R0<-[R1+0 x8]LDR R0, [R1, #-0x20] ; R0<- [R1 –0x20]R0=0xe59f30603. [<Rn>, +/-<Rm>] 偏移量为寄存器LDR R0,[R1, R2] ;R0<-[R1+R 2]LDRR0,[R1,-R2] ;R0 <-[R1-R2]4. [<Rn>, +/-<Rm>, <shift> #<shift_imm>] 偏移量为寄存器移位LDR R0,[R1 ,R2,LSL#2] ;R0<-[R1+R2*4]5. [<Rn>, #+/-<offset_12>]!LDR R0,[R1, #0x8]! ;R0<-[R1+0x8] R1=R1+81.先加载数据2.改变基址6. [<Rn>, +/-<Rm>]!LDRR0,[R1,R2] ! ;R0<-[R1+R2] R1=R1+R27. [<Rn>, +/-<Rm>, <shift> #<shift_imm>]!LDR R0,[R1,R2,LSL #2] !;R0<-[R 1+R2*4] R1=R1+R2*48. [<Rn>], #+/-<offset_12>LDR R0, [R1], #0x20 ;R0=<-[R1] R1=R1+0x201.现将基址指定的数据加载到R02.改变基址9. [<Rn>], +/-<Rm>LDR R0, [R1], R2 ;R0=<-[R1] R1=R1+R210. [<Rn>], +/-<Rm>, <shift> #<shift_imm>LDR R0, [R1], R2, LSL #2;R0=<-[R1] R1=R1+R2*4地址模式:10:1.无偏移量,将指定基址的数据加载到寄存器,基址不变2.将基址+偏移量指定地址的数据加载到寄存器,基址不变1.立即数2.寄存器3.寄存器移位3.将基址+偏移量指定地址的数据加载到寄存器,基址=基址+偏移量1.立即数2.寄存器3.寄存器移位4.将基址表示的加载到寄存器,基址=基址+偏移量1.立即数2.寄存器3.寄存器移位单寄存器字和无符号字节的加载,存储指令单寄存器半字和有符号字节的加载,存储指令加载指令语法格式LDR{cond}H Rd, <地址模式> 功能:Rd<- <地址模式>,高16bit 用0填充LDR{cond}SH Rd, <地址模式> 功能:Rd<- <地址模式>,高16bit 用符号位填充LDR{cond}SB Rd, <地址模式> 功能:Rd<- <地址模式>,高24bit 用符号位填充使用示例LDRH R1, [R0]R0=0x20008000R1=0x4800LDRSH R8, [R3, #2] LDREQH R12, [R13, #-6] LDRSB R7, [R6, #-1]!LDRH R3, [R9], #2LDRSB R1, [R2], R3LDRH PC, [R0] @×LDRH R0, [R0], #4 @×LDRSB PC, [R0]@×LDRSB R0, [R0], #4 @×不要以PC作为目标寄存器用在加载半字和字节的加载指令中在基址要发生变化的指令中,基址寄存器和目标寄存器不要相同的语法格式STR{cond}H Rd,<地址模式>使用示例STRH R1, [R0]STRH R8, [R3, #2] STREQH R12, [R13, #-6] STRH R7, [R6, #-2]!STRH R3, [R9], #2STRH R1, [R2], R3STRH PC, [R0] @×STRH R0, [R0], #4 @×STRH R7, [R6, #-1] @ ?半字读写时,指定的地址必须半字对齐,地址整除2基址+偏移量偏移量:立即数(由8bit来表示),寄存器1 .零偏移LDRSH R0, [R1]R0<-[R1]的低16bit R0的高16bit用符号位填充2. [<Rn>, #+/-<offset_8>] LDRH R0, [R1, #0x04]3. [<Rn>, +/-<Rm>]LDRSB R0, [R1, R2]4. [<Rn>, #+/-<offset_8>]! LDRH R0, [R1, #0x08]!5. [<Rn>, +/-<Rm>]!LDRSB R0, [R1, R2]!6. [<Rn>], #+/-<offset_8> LDRSH R0, [R1], #0x47. [<Rn>], +/-<Rm> LDRSH R0, [R1], R2单寄存器字和无符号字节存储加载指令地址模式:基址+偏移量立即数(12bit)寄存器寄存器移位单寄存器半字和有符号字节存储加载指令地址模式:基址+偏移量立即数(8bit)寄存器多寄存器存储加载指令多寄存器加载指令LDMLDM{cond}{addressing_mode} Rb{!}, < Reglist >{^}功能:将Rb基址中数据加载到Reglist表示的寄存器列表中LDMIA / STMIA 后增加LDMIB / STMIB 先增加LDMDA / STMDA 后减小LDMDB / STMDB 先减小多寄存器存储指令STMSTM{cond} {addressing_mode} Rb{!}, < Reglist >{^}cond : 条件域addressing_modeLDMIA / STMIA Increment After(先操作,后增加)LDMIB / STMIB Increment Before(先增加,后操作)LDMDA / STMDA Decrement After (先操作,后递减)LDMDB / STMDB Decrement Before (先递减,后操作)Rb : 基址寄存器! : 更新基址寄存器Reglist: 源/目标寄存器列表(可以是16个寄存器的任何子集)^ : 1.寄存器列表中没有PC寄存器:特权模式下使用用户模式下的寄存器2.寄存器列表中有PC寄存器,CPSR=SPSR,异常返回R10:基址寄存器{R0,R1,R4}:源操作的寄存器STMDA R10!,{R0,R1,R4}LDMIA R10,{R0,R1,R4}R0=0x20008000 IB地址先增加,然后再加载数据[0x20008000]=1[0x20008004]=2[0x20008008]=3[0x2000800C]=4[0x20008010]=5LDMIB R0! , {R1,R2,R3,R4}R1=2R2=3R3=4R4=5R0=0x20008010R0=0x20008000 IA地址后增加,先加载数据[0x20008000]=1[0x20008004]=2[0x20008008]=3[0x2000800C]=4[0x20008010]=5LDMIA R0!, {R1, R2, R3,R4}R1=1R2=2R3=3R4=4R0=0x20008010LDMIA R0!, {R1-R3} LDMIB R0, {R1-R3, R7}^ @ x usr/sysLDMDB SP!, {R1-R3, PC}^ @ x usr/sysLDMDB R0, {R0-R2} LDMDA R15, {R1} @xLDMDB R0!, {R0-R2} @x Rn值LDM{cond}{addressing_mode} Rb{!}, < Reglist >{^}功能:将Rb基址中数据加载到Reglist表示的寄存器列表中多寄存器存储指令STMSTM{cond} {addressing_mode}Rb{!}, < Reglist >{^}IA 先存储或加载数据,地址后增加IB 地址先增加,后存储或加载数据DA 先存储或加载数据,地址后减小DB 地址先减小,后存储或加载数据多寄存器存储加载,只操作字数据大编号寄存器存放在高地址,小编号寄存器存放在低地址!:基址要更新^:1.寄存器列表中包括PC,CPSR=SPSR(异常模式下使用)2.寄存器列表中不包括PC,特权模式下使用用户模式寄存器PC不做为基址寄存器若要更新基址,基址和目标寄存器不使用相同的寄存器STMIA R0!, {R1-R3} STMIA SP!, {R1-R3, LR} STMIB R0, {R1-R3, R9}^ @x usr/sys STMDB R0, {R0-R2} STMDB R0!, {R0-R2}STMDA R15, {R1} @ x栈的种类:Descending stacks (减栈)栈向内存地址减小的方向变化Ascending stacks (加栈)栈向内存地址增加的方向变化Full stacks (满栈)栈指针指向的栈顶保存有效元素Empty stacks (空栈)栈指针指向的栈顶未保存有效元素综合以上两种特点,有以下4种栈FD(Full Descending)满减栈ED(Empty Descending)空间栈FA(Full Ascending)满加栈EA(Empty Ascending)空加栈STMFD (Push) [多寄存器存储- STMDB]LDMFD (Pop) [多寄存器加载- LDMIA]STMDB 入栈LDMIA 出栈…….MOV R0, #0MOV R1,#1BL loop CPU自动将ADD指令地址存放LRADD R3,R4loop:STMFD sp!, {r4-r7, lr}SUB R4, #1…..LDMFD sp!, {r4-r7, pc}STMFD(STMDB\Push):入栈根据满减栈原则,先减地址,后入栈,高地址存大编号寄存器的原则,依次入栈,栈顶指针永远指向有效元素。