ARM--汇编指令

ARM--汇编指令
ARM汇编学习arm汇编的主要目的是为了编写arm启动代码引导程序到c语言环境下运行。启动代码的目的是为了在处理器复位以后搭建c语言最基本的需求。启动代码的主要任务初始化异常向量表初始化各工作模式的栈指针寄存器开启arm内核中断允许将工作模式设置为user模式引导程序进入c语言主函数执行格式伪操作不是 ARM 处理器实际的指令如 MOV, ADD 等而是汇编器的命令用于指导汇编器如何工作area reset, code, readonly code32 entry endarea:用于定义一个段。程序、数据、堆栈等都需要被组织在不同的段中。reset: 段的名字。名字 reset 具有很强的暗示性通常用于表示复位向量段即CPU上电或复位后首先执行的第一段代码所在的位置。code: 指定该段的属性为代码意味着这个段包含可执行的指令。readonly: 指定该段的属性为只读。对于代码段来说通常是默认且必须的。code32: 表示后续指令使用 32位的 ARM 指令集。标志位CPSR寄存器中条件判断标志位N: 符号标志位上条指令执行结果最高位bit31为1,则 N 1, 当结果作为有符号解释时为负值Z: 零值标志位上条指令执行结果为0即bit0 - bit31 均为0)则 Z 1C: 进位标志位进行无符号解读如果在加法过程中进位或者减法时没有借位则为 C 1,否则 C 0V: 溢出标志位进行有符号解读是否发生溢出 -2^31 - 2^31-1(两个正数加得负数两个负数加得正数)条件码eq相等 ne不相等ge大于等于 gt大于 le小于等于 lt小于al(无条件执行)指令手册目录指令目的操作数第一操作数第二操作数immediate立即数register寄存器SP plus栈指针立即数12位立即数imm12的条件是把某个数展开成2进制该数必须存在一种循环右移偶数位使得移位后高24位全0低8位即为有效imm8eg0xA000 000A 是立即数0xFFFF FFFF 不是立即数mov指令基本格式MOV{S}c Rd, #constMOV{S}c Rd, RmMOV与位移指令的结合注意(1)与C语言中的赋值运算对比左值/右值利于加深理解(2)#n/Rs 取值范围 0 - 31(3)RRX{S}:扩展右移 不需要移位量(4)在计算机中只识别二进制数据计算机没有有无符号浮动点等概念add指令立即数作为第二操作数 ADD{S}c Rd, Rn, #const寄存器作为第二操作数寄存器 ADD{S}c Rd, Rn, Rm{, shift}寄存器作为第二操作数移位量 ADD{S}c Rd, Rn, Rm, type Rs注意(1){, shift} 其中{}代表可选择“,”表示在使用时需要在Rm后添加“,” shift 移位量立即数(2) add r0, #3, #2 :没有这种形式C语言int a 1 2; 编译阶段计算 不需要在机器指令中体现sub指令立即数作为第二操作数 SUB{S}c Rd, Rn, #const寄存器作为第二操作数寄存器 SUB{S}c Rd, Rn, Rm{, shift}寄存器作为第二操作数移位量 SUB{S}c Rd, Rn, Rm, type Rsldr指令向寄存器中加载一个非立即数将RAM中的数据加载到通用寄存器str指令将通用寄存器中值写入到RAM空间mvn指令MVN{S}c Rd, #constMVN{S}c Rd, Rm{, shift}MVN{S}c Rd, Rm, type Rsbic指令BIC{S}c Rd, Rn, #constBIC{S}c Rd, Rn, Rm{, shift}BIC{S}c Rd, Rn, Rm, type Rsorr指令ORR{S}c Rd, Rn, #constORR{S}c Rd, Rn, Rm{, shift}ORR{S}c Rd, Rn, Rm, type Rscmp指令CMPc Rn, #constCMPc Rn, Rm{, shift}CMPc Rn, Rm, type Rs比较并获取三个数中的最大值b bl bx指令Bc labelb fun ldr pc, fun直接跳转到目标地址不保存返回地址BLc labelbl fun跳转前将返回地址存入LR寄存器BXc Rmbx lr mov pc, lr跳转到寄存器指定的地址并可切换指令集不保存返回地址stmfd将寄存器的值保存到栈区入栈ldmfd将寄存器的值从栈区取出出栈while/dowhile循环三要素循环结束条件推动循环趋向终结的语句循环的循环体dowhile实现0-100求和while实现0-100求和ARM栈FD (满减栈)​栈指针SP指向最后压入的元素即栈顶元素操作方式PUSHSP先减少再存数据POP先取数据再增加SPFA满增栈栈指针SP指向最后压入的元素即栈顶元素操作方式PUSHSP先增加再存数据POP先取数据再减少SPEA (空增栈)​栈指针SP指向下一个空闲位置操作方式PUSH现存数据再增加SPPOPSP先减少再取数据ED (空减栈)​栈指针SP指向下一个空闲位置操作方式PUSH现存数据再减少SPPOPSP先增加再取数据汇编与C语言函数的相互调用汇编调用C函数汇编-C函数传参通过通用寄存器传参将C语言函数返回值保存到R0寄存器如果参数个数小于等于4个时可以通过通用寄存器R0 - R3传参当参数个数超过4个时必须通过栈进行传参入栈出栈C语言调用汇编C - 汇编传参将C语言传递的参数保存到通用寄存器中汇编程序结果通过R0寄存器返回初始化supervisor模式栈ldr sp, 0x40001000 // 初始化栈指针,复位后默认为supervisor模式在进入主函数操作前需要对当前默认的supervisor模式设置一个有效的栈空间确保能够进行函数调用和临时数据存储通过ldr命令将预先分配的地址0x40001000存入到栈指针声明主函数import main // 声明主函数告知汇编器符号main是在C语言文件中定义的定义后可以调用示例在汇编中调用C语言函数main.c示例在C语言函数中调用汇编函数main.cextern int _asm_min(int a,int b);修改处理器工作模式为USER模式步骤将cpsr寄存器中的值读到通用寄存器中将通用寄存器中的低5位修改为10000USER将通用寄存器中的值写回到CPSR寄存器mrs指令读取某个特殊寄存器(cpsr)值到通用寄存器msr指令将通用寄存器的值写入到特殊寄存器(cpsr)