怎样优化排名自己网站,在线培训系统软件,深圳创业补贴申请,app开发公司未按照合同开发目录
写在前面
1、Cortex-A7 处理器有 9 种处理模式
2、Cortex-A 寄存器组
通用寄存器
1、汇编语法
2、Cortex-A7 常用汇编指令
2.1 处理器内部数据传输指令
2.1.1 传输数据操作类型
1、MOV指令
2、MRS指令
3、MSR指令
2.2、存储器访问指令
2.2.1 LDR指令
2.2.2 …目录
写在前面
1、Cortex-A7 处理器有 9 种处理模式
2、Cortex-A 寄存器组
通用寄存器
1、汇编语法
2、Cortex-A7 常用汇编指令
2.1 处理器内部数据传输指令
2.1.1 传输数据操作类型
1、MOV指令
2、MRS指令
3、MSR指令
2.2、存储器访问指令
2.2.1 LDR指令
2.2.2 STR指令
2.3 压栈和出栈指令
2.4 跳转指令
2.4.1 B指令
2.4.2 BL指令
2.5算术运算指令
2.6 逻辑运算指令
相关好的博文 写在前面
记录下学习arm汇编的一些知识点
1、Cortex-A7 处理器有 9 种处理模式 2、Cortex-A 寄存器组
ARM 架构提供了 16 个 32 位的通用寄存器(R0~R15)供软件使用前 15 个(R0~R14)可以用作通用的数据存储 R15 是程序计数器 PC用来保存将要执行的指令。 ARM 还提供了一个当前程序状态寄存器 CPSR 和一个备份程序状态寄存器 SPSR SPSR 寄存器就是 CPSR 寄存器的备份。 通用寄存器
R0~R15 就是通用寄存器通用寄存器可以分为以下三类 ①、 未备份寄存器即 R0~R7。 ②、 备份寄存器即 R8~R14。 ③、程序计数器 PC即 R15。
1、未备份寄存器 未备份寄存器指的是 R0~R7 这 8 个寄存器因为在所有的处理器模式下这 8 个寄存器都是同一个物理寄存器在不同的模式下这 8 个寄存器中的数据就会被破坏。所以这 8 个寄存器并没有被用作特殊用途。
2、备份寄存器 备份寄存器中的 R8~R12 这 5 个寄存器有两种物理寄存器在快速中断模式下(FIQ)它们对应着 Rx_irq(x8~12)物理寄存器其他模式下对应着 Rx(8~12)物理寄存器。 FIQ 是快速中断模式看名字就是知道这个中断模式要求快速执行 FIQ 模式下中断处理程序可以使用 R8~R12寄存器因为 FIQ 模式下的 R8~R12 是独立的因此中断处理程序可以不用执行保存和恢复中断现场的指令从而加速中断的执行过程。备份寄存器 R13 一共有 8 个物理寄存器其中一个是用户模式(User)和系统模式(Sys)共用的剩下的 7 个分别对应 7 种不同的模式。 R13 也叫做 SP用来做为栈指针。基本上每种模式都有一个自己的 R13 物理寄存器应用程序会初始化 R13使其指向该模式专用的栈地址这就是常说的初始化 SP 指针。备份寄存器 R14 一共有 7 个物理寄存器其中一个是用户模式(User)、系统模式(Sys)和超级监视模式(Hyp)所共有的剩下的 6 个分别对应 6 种不同的模式。R14 也称为连接寄存器(LR)LR 寄存器在 ARM 中主要用作如下两种用途
①、每种处理器模式使用 R14(LR)来存放当前子程序的返回地址如果使用 BL 或者 BLX来调用子函数的话 R14(LR)被设置成该子函数的返回地址在子函数中将 R14(LR)中的值赋给R15(PC)即可完成子函数返回。
②、当异常发生以后该异常模式对应的 R14寄存器被设置成该异常模式将要返回的地址R14 也可以当作普通寄存器使用。
3、程序计数器 R15
程序计数器 R15 也叫做 PC R15 保存着当前执行的指令地址值加 8 个字节这是因为 ARM的流水线机制导致的。 ARM 处理器 3 级流水线取指-译码-执行这三级流水线循环执行比如当前正在执行第一条指令的同时也对第二条指令进行译码第三条指令也同时被取出存放在R15(PC)中。我们喜欢以当前正在执行的指令作为参考点也就是以第一条指令为参考点那么 R15(PC)中存放的就是第三条指令换句话说就是 R15(PC)总是指向当前正在执行的指令地址再加上 2 条指令的地址。对于 32 位的 ARM 处理器每条指令是 4 个字节
R15 (PC)值 当前执行的程序位置 8 个字节。
4、程序状态寄存器
所有的处理器模式都共用一个 CPSR 物理寄存器因此 CPSR 可以在任何模式下被访问。CPSR 是当前程序状态寄存器该寄存器包含了条件标志位、中断禁止位、当前处理器模式标志等一些状态位以及一些控制位。所有的处理器模式都共用一个 CPSR 必然会导致冲突为此除了 User 和 Sys 这两个模式以外其他 7 个模式每个都配备了一个专用的物理状态寄存器叫做 SPSR(备份程序状态寄存器)当特定的异常中断发生时 SPSR 寄存器用来保存当前程序状态寄存器(CPSR)的值当异常退出以后可以用 SPSR 中保存的值来恢复 CPSR。
1、汇编语法
label: instruction comment label 即标号表示地址位置有些指令前面可能会有标号这样就可以通过标号得到这个指令的地址标号也可以用来表示数据地址。 注意 label 后面的 “ ” ,任何以“ ”结尾的标识符都会被识别为一个标号。 instruction 即指令 即汇编指令或者伪指令 符号 表示后面的是注释 comment 就是注释内容 注意arm中的指令伪指令伪操作寄存器名都可以全部使用大写也可以全部使用小写但是不能大小写混用。
开发者可以使用 .section 伪操作来定义一个段汇编系统预定义了一些段名 .text 表示代码段 .data 表示初始化的数据段 .bss 表示未初始化的数据段 .rodata 表示只读数据段 用 .section 来定义一个段每个段以段名开始以下一个段名或者文件结尾结束· .section .testsection 定义一个 testsection 汇编程序的默认入口标号是 _start ,通常在链接脚本中使用 ENTRY 来指明其他入口 .global_start _start: ldr r0,0x12 r00x12 上面代码中 .global 是伪操作表示 _start 是一个全局标号常见伪操作包括 .byte 定义单字节数据 比如 .byte 0x12 .short 定义双字节数据比如 .short 0x1234 .long 定义一个4字节数据 比如.long 0x12345678 .equ 赋值语句格式是 .equ 变量名表达式比如 .equ num 0x12表示 num0x12 .align 数据字节对齐 比如.align 4 表示4 字节对齐 .end 表示源文件结束 .global 定义一个全局符号格式为 .global symbol ,比如 .global_start GNU 汇编同时支持函数 函数名 函数体 返回语句 GNU 汇编函数返回语句不是必须的 /* 未定义中断 */ Undefined_Handler: ldr r0, Undefined_Handler bx r0 其中 Undefined_Handler 是函数名“ldr r0Undefined_Handler”是函数体“bx r0”是函数返回语句“bx”指令是返回指令函数返回语句不是必须的。
2、Cortex-A7 常用汇编指令
2.1 处理器内部数据传输指令
2.1.1 传输数据操作类型 1、寄存器到寄存器 2、寄存器到特殊寄存器 3、立即数到寄存器 常用的数据传输指令 MOV MRS MSR
指令目的源描述MOVR0 R1将R1中数据传输到R0中MRSR0CPSR将特殊寄存器CPSR中的数据复制到R0中MSRCPSRR1将R1里面的数据复制到特殊寄存器CPSR中
1、MOV指令
MOV指令通常是将数据从一个寄存器拷贝到另一个寄存器中或者将一个立即数传递到寄存器里面 MOV R0R1 寄存器R1中的数据传递给R0 MOV R0 #0x12 将立即数0x12传递给R0寄存器 2、MRS指令
MRS指令用于将特殊寄存器的值复制给普通寄存器 MSR R0CPSR 将CPSR中的数据复制到R0中 3、MSR指令
MSR指令和MRS指令相反MSR 指令用来将普通寄存器的数据传递给特殊寄存器也就是写特殊寄存器只能使用 MSR指令 MSR CPSRR0 将R0中的数据复制到CPSR中 2.2、存储器访问指令
arm 不能直接访问存储器也就是需要将存储器中的数据读到寄存器中常用的存储器访问指令主要有 LDR 和 STR
指令 描述LDR Rd, [Rn , #offset]从存储器Rnosset的位置读取数据存放到Rd中STR Rd, [Rn,#offset]将 Rd 中的数据写入到存储器中的 Rnoffset 位置
2.2.1 LDR指令
LDR是将数据从存储器加载到寄存器 Rx中LDR 也可以将立即数加载到寄存器 Rx中LDR 加载立即数的时候要用 ,不能使用 # 来描述立即数 。嵌入式开发中LDR 最常用的就是读取 CPU 的寄存器值加入有个寄存器 REG0 其地址为 0x81000000 ,我们要读取这个寄存器中数据示例代码如下
LDR R0 0x81000000 将寄存器地址加载到 R0 中
LDR R1[R0] 读取地址0x81000000 中的数据到 R1 寄存器中
没有用到 offset 则代表 offset 值为0
2.2.2 STR指令
LDR指令是从存储器读取数据STR 指令是将数据写入到存储器中
LDR R0 0x81000000
LDR R1, 0x81000008
STR R1, [R0] 将R1中的值写入到 R0 中保存的地址中 LDR 和 STR 都是按照字进行读取和写入的也就是操作的是 32位的数据如果要按照字节、半字操作的话可以在 LDR 指令后加上 B或者 H 字节操作的指令就是 LDRB 和 STRB按半字进行操作的指令就是 LDRH 和 STRH 2.3 压栈和出栈指令 会在 A 函数中调用 B 函数当 B 函数执行完以后再回到 A 函数继续执行。要想再跳回 A 函数以后代码能够接着正常运行那就必须在跳到 B 函数之前将当前处理器状态保存起来(就是保存 R0~R15 这些寄存器值)当 B 函数执行完成以后再用前面保存的寄存器值恢复R0~R15 即可。保存 R0~R15 寄存器的操作就叫做现场保护恢复 R0~R15 寄存器的操作就叫做恢复现场。在进行现场保护的时候需要进行压栈(入栈)操作恢复现场就要进行出栈操作。压栈的指令为 PUSH出栈的指令为 POP PUSH 和 POP 是一种多存储和多加载指令即可以一次操作多个寄存器数据他们利用当前的栈指针 SP 来生成地址。
指令描述PUSH reg list将寄存器列表存入栈中POP reg list从栈中恢复寄存器列表
假如我们现在要将 R0~R3 和 R12 这 5 个寄存器压栈当前的 SP 指针指向 0X80000000处理器的堆栈是向下增长的使用的汇编代码如下 PUSH {R0~R3R12} 将R0~R3和R12 压栈 PUSH {LR} 将 LR 进行压栈 POP {LR} 先恢复 LR POP {R0~R3,R12} 在恢复 R0~R3,R12 2.4 跳转指令
跳转操作通常可以使用 跳转指令 B、BL、BX也可以直接往 PC 寄存器中写值下面详细介绍一下汇编指令
指令 描述B label 跳转到label 如果跳转了超过 、- 2KB 可以指定 B.W label指令使用32位版本的跳转指令BX Rm间接跳转跳转到存放在 Rm 中的地址处并切换指令集BL label 跳转到标号位置并将返回地址保存在 LR 中BLX Rm结合 BX 和 BL的特点跳转到 Rm 指定的地址并将返回地址保存到 LR 中切换指令集
2.4.1 B指令
B指令会将 PC 寄存器的值设置为跳转目标地址但是不会再返回原来的执行处 _start: dr sp,0X80200000 设置栈指针 b main 跳转到 main 函数 在汇编中初始化C运行环境然后跳转到C语言的main函数处
2.4.2 BL指令
BL指令相较于 B指令在跳转之前会在寄存器 LRR14中保存当前PC寄存器的值所以可以通过 LR 寄存器恢复现场 push {r0, r1} 保存 r0,r1 cps #0x13 进入 SVC 模式允许其他中断再次进去 bl system_irqhandler 加载 C 语言中断处理函数到 r2 寄存器中 cps #0x12 进入 IRQ 模式 pop {r0, r1} str r0, [r1, #0X10] 中断执行完成写 EOIR 2.5算术运算指令 2.6 逻辑运算指令 相关好的博文
GNU风格 汇编语法总结_gnu汇编语法-CSDN博客
https://www.cnblogs.com/zhumengke/articles/10643032.html