凡客诚品官方网站查询,做印尼购物网站如何发货,h网站模板,网站建设费用如何做账一、数据处理指令1#xff09;数学运算数据运算指令的格式数据搬移指令立即数伪指令加法指令带进位的加法指令减法指令带借位的减法指令逆向减法指令乘法指令数据运算指令的扩展 2#xff09;逻辑运算按位与指令按位或指令按位异或指令左移指令右移指令位清零指令 3#xff… 一、数据处理指令1数学运算数据运算指令的格式数据搬移指令立即数伪指令加法指令带进位的加法指令减法指令带借位的减法指令逆向减法指令乘法指令数据运算指令的扩展 2逻辑运算按位与指令按位或指令按位异或指令左移指令右移指令位清零指令 3比较指令怎么影响到CPSR寄存器中的状N, Z, C, V比较指令ARM指令的条件码 二、跳转指令1跳转指令跳转指令 三、Load / Srore指令1内存访问指令写内存读内存 2ARM指令的寻址方式立即寻址寄存器寻址寄存器移位寻址寄存器间接寻址基址加变址寻址基址加变址寻址的索引方式多寄存器内存访问指令的寻址方式 3栈的种类与使用 一、数据处理指令
数据处理指令数学运算、逻辑运算
1数学运算
32位处理器什么意思单次运算数据的能力单次最大可处理32位的数据 数据运算指令的格式 《操作码》《目标寄存器》《第一操作寄存器》《第二操作数》 操作码 表示执行哪种操作 目标寄存器 表示存储运算的结果 第一操作寄存器 存储第一个参与运算的寄存器只能是寄存器 第二操作数 存储第二个参与运算的数据寄存器、立即数都可以 数据搬移指令 MOV R1, #1 MOV R2, R1 // R2 R1 MOV PC, #7 // 可以更改PC的值但是系统会默认把后两位改成07八进制111系统会自动改成4100 MVN R0, #0xFF // R0 ~0xFF R0的内容就是0xFFFFFF00 立即数 立即数的本质是包含在指令当中的数属于指令的一部分这条执行是一起编译成机器码的 优点 取值的时候就可以直接读取到CPU不用单独去内存读取速度快 缺点 不能是任意的32位的数字有局限性 MOV R1, #0x12345678 //不可以执行因为数字太大 MOV R1, #0x12 //可以执行 伪指令 MOV R1, #0xFFFFFFFF //当执行这条指令的时候显然这个数字太大但是可以编译成功是系统自动会将这条指令替换成 MVN R1, #0x00000000 这样就和MOV R1, #0xFFFFFFFF 指令执行的效果一样这样的行为前提是两条指令要达到的效果相同 加法指令 ADD R1, R2, R3 //R1 R2R3 带进位的加法指令 ADC R5, R2, R4 // R5 R2 R4 ‘CPSR-C’ 1.编程实现使用32bit的ARM处理器实现两个128位的数据的加法运算。 注 第一个数的bit[31:0]、bit[63:32]、bit[95:64]、bit[127:96]分别存储在R1、R2、R3、R4寄存器 第二个数的bit[31:0]、bit[63:32]、bit[95:64]、bit[127:96]分别存储在R5、R6、R7、R8寄存器 运算结果的bit[31:0]、bit[63:32]、bit[95:64]、bit[127:96]分别存储在R9、R10、R11、R12寄存器 第一个数 0x00000004 00000002 FFFFFFFF 00000004MOV R1, #0xFFFFFFFFMOV R2, #0x00000002MOV R3, #0xFFFFFFFFMOV R4, #0x00000004 第二个数 0x00000005 00000004 00000003 00000002MOV R5, #0x00000002 MOV R6, #0x00000003MOV R7, #0x00000004MOV R8, #0x00000005 运算结果ADDS R9 , R1, R5 //加 S 可以影响到CPSR寄存器高位运算时可以看出低位有没有进位ADCS R10, R2, R6ADCS R11, R3, R7ADC R12, R4, R8减法指令 SUB R1, R2, R3 //R1 R2-R3 带借位的减法指令 SBC R5, R2, R4 // R5 R2 - R4 - ‘~CPSR-C’ 取反 逆向减法指令 RSB R1, R2, #3 //R1 3-R2 乘法指令 MUL R1, R2, R3 //R1 R2*R3 乘法指令只能是两个寄存器执行 数据运算指令的扩展 MOV R1, R2, LSL #1 //R1 (R21)
2逻辑运算 按位与指令 AND R1, R2, R3 //R1 R2R3 按位或指令 ORR R1, R2, R3 //R1 R2 | R3 按位异或指令 EOR R1, R2, R3 //R1 R2 ^ R3 左移指令 LSL R1, R2, R3 //R1 R2 R3 右移指令 LSR R1, R2, R3 //R1 R2 R3 位清零指令 MOV R2, #0xFF BIC R1, R2, #0x0F //第二操作数的哪一位为1就把第一寄存器中的哪一位清零然后将结果放入目标寄存器中
3比较指令 怎么影响到CPSR寄存器中的状N, Z, C, V 数据运算指令对条件位CPSR寄存器中的状N, Z, C, V的影响 默认情况下数据运算不会对条件位产生影响当在指令后加后缀‘S’后可以影响 MOV R2, #3 SUBS R1, R2, #5 //将会对 N 状态位产生影响 比较指令 CMP R1, R2 本质是一条SUBS只是没有将运算结果放入寄存器当中是看CSPR寄存器状态位N, Z, C, V Z1
! Z0C0C0 或 Z1C1 且 Z0 C1MOV R1, #1MOV R2, #2CMP R1, R2BEQ FUNC 执行逻辑if(EQ){B FUNC} 本质if(Z1){B FUNC}BNE FUNC 执行逻辑if(NE){B FUNC} 本质if(Z0){B FUNC}MOV R3, #3MOV R4, #4MOV R5, #5FUNC:MOV R6, #6MOV R7, #7 ARM指令集中大多数指令都可以带条件码后缀MOV R1, #1MOV R2, #2CMP R1, R2MOVGT R3, #3 练习用汇编语言实现以下逻辑int R1 9;int R2 15;START:if(R1 R2){STOP();}else if(R1 R2){ R1 R1 - R2;goto START;}else{R2 R2 - R1;goto START;} 练习答案:MOV R1, #9MOV R2, #15START:CMP R1,R2BEQ STOPSUBGT R1, R1, R2SUBLT R2, R2, R1B STARTSTOP: B STOPARM指令的条件码 ARM指令集中大多数指令都可以带条件码后缀如SUBEQ 二、跳转指令
1跳转指令 跳转指令 有三种方式 第一种方法直接去修改PC的值不建议使用因为需要自己计算绝对地址 MAIN:MOV R1, #1MOV R2, #2MOV PC, #0x16MOV R3, #3FUNC:MOV R4, #4MOV R5, #5MOV R6, #6第二种方法不带返回的跳转指令本质就是将PC寄存器的值修改成跳转标号下第一条指令的地址 MAIN:MOV R1, #1MOV R2, #2B FUNCMOV R3, #3FUNC:MOV R4, #4MOV R5, #5MOV R6, #6第三种方法带返回的跳转指令本质就是将PC寄存器的值修改成跳转标号下第一条指令的地址同时将跳转指令的下一条指令的地址存储到LR MAIN:MOV R1, #1MOV R2, #2BL FUNCMOV R3, #3FUNC:MOV R4, #4MOV R5, #5MOV R6, #6MOV PC, LR三、Load / Srore指令
Load / Srore指令访问读写内存
1内存访问指令
Load/Srore指令访问读写内存 当LD开头的指令 内存读数据到CPU 当ST开头的指令 把CPU中的数据存到内存当中 写内存 MOV R1, #0xFFFFFFF1 MOV R2, #0x40000000 STR R1, [R2] 默认是写入一个字四个字节的数据 STRB R1, [R2] 内存中写入B一个字节的数据F1 STRH R1, [R2] 内存中写入H两个字节的数据FFF1 R2-0x40000000内存空间 R1的数据读内存 MOV R1, #0xFFFFFFF1 MOV R2, #0x40000000 LDR R3, [R2] R3 默认内存读出一个字四个字节的数据 LDRB R3, [R2] R3 内存读出一个字节的数据 LDRH R3, [R2] R3 内存读出两个字节的数据 R3 R2-0x40000000内存空间的数据2ARM指令的寻址方式
寻址方式就是CPU去寻找操作数的方式 立即寻址 MOV R1, #1 ADD R1, R2, #1 寄存器寻址 ADD R1, R2, R3 寄存器移位寻址 MOV R1, R2, LSL #1 寄存器间接寻址 STR R1, [R2] 基址加变址寻址 MOV R1, #0xFFFFFFFF MOV R2, #0x40000000 MOV R3, #4 STR R1, [R2,R3] 将R1寄存器中的数据写入到R2R3指向的内存空间 STR R1, [R2,R3,LSL #1] 将R1寄存器中的数据写入到R2(R31)指向的内存空间基址加变址寻址的索引方式 前索引 MOV R1, #0xFFFFFFFF MOV R2, #0x40000000 STR R1, [R2,#8] 将R1寄存器中的数据写入到R28指向的内存空间 LDR R2, [R2,#8] 将R28指向的内存空间的数据写入到R2寄存器中后索引 MOV R1, #0xFFFFFFFF MOV R2, #0x40000000 STR R1, [R2],#8 将R1寄存器中的数据写入到R2指向的内存空间然后R2自增8 LDR R1, [R2],#8 将R28指向的内存空间的数据写入到R2寄存器中然后R1自增8自动索引 MOV R1, #0xFFFFFFFF MOV R2, #0x40000000 STR R1, [R2,#8]! 将R1寄存器中的数据写入到R28指向的内存空间然后R2自增8 LDR R6, [R2,#8]! 将R28指向的内存空间的数据写入到R6寄存器中然后R6自增8多寄存器内存访问指令的寻址方式 MOV R1, #1 MOV R2, #2 MOV R3, #3 MOV R4, #4 MOV R11,#0x40000020 STMIA R11!,{R1-R4} 先存储数据后增长地址 STMIB R11!,{R1-R4} 先增长地址后存储数据 STMDA R11!,{R1-R4} 先存储数据后递减地址 STMDB R11!,{R1-R4} 先递减地址后存储数据3栈的种类与使用 栈的概念 栈的本质就是一段内存程序运行时用于保存一些临时数据如局部变量、函数的参数、返回值、以及程序跳转时需要保护的寄存器等 栈的分类 增栈压栈时栈指针越来越大出栈时栈指针越来越小 减栈压栈时栈指针越来越大出栈时栈指针越来越小 满栈栈指针指向最后一次压入到栈中的数据压栈时需要先移动栈指针到相邻位置然后再压栈 空栈栈指针指向最后一次压入到栈中的数据的相邻位置压栈时可直接压栈之后需要将栈指针移动到相邻位置
栈分为空增EA、空减ED、满增FA、满减FD四种 ARM处理器一般使用满减栈 MOV R1, #1MOV R2, #2MOV R3, #3MOV R4, #4MOV R11,#0x40000020STMFD R11!,{R1-R4}LDMFD R11!,{R6-R9} 结果 R6 1, R7 2, R8 3, R9 4栈的应用举例
1.叶子函数的调用过程举例 初始化栈指针MOV SP, #0x40000020
MIAN:MOV R1, #3MOV R2, #5BL FUNCADD R3, R1, R2B STOPFUNC: 压栈保护现场STMFD SP!, {R1,R2}MOV R1, #10MOV R2, #20SUB R3, R2, R1 出栈恢复现场LDMFD SP!, {R1,R2}MOV PC, LR2.非叶子函数的调用过程举例 MOV SP, #0x40000020
MIAN:MOV R1, #3MOV R2, #5BL FUNC1ADD R3, R1, R2B STOP
FUNC1:STMFD SP!, {R1,R2,LR}MOV R1, #10MOV R2, #20BL FUNC2SUB R3, R2, R1LDMFD SP!, {R1,R2,LR}MOV PC, LR
FUNC2:STMFD SP!, {R1,R2}MOV R1, #7MOV R2, #8MUL R3, R1, R2LDMFD SP!, {R1,R2}MOV PC, LR 执行叶子函数时不需要对LR压栈保护执行非叶子函数时需要对LR压栈保护