东莞网站开发公司哪家好微营销的常见方法有哪些
一、汇编指令
1.1 指令与伪指令
汇编的指令
指令是CPU机器指令的助记符,编译后会得到一串二进制机器码,由CPU执行
汇编的伪指令
伪指令本质上不是指令,它是编译器环境提供用来指导编译过程,编译后伪指令不会生成机器码
 伪指令的意义在于指导编译过程
区别
经过编译后会不会生成二进制机器码
1.2 gun汇编中的符号
| 符号 | 作用 | 
|---|---|
| @ | 用来做注释,可以在行首也可以在代码后面同一行直接跟,和C语言中 // 类似 | 
| : | 以冒号结尾的是标号 | 
| . | 点号在gnu汇编中表示当前指令的地址 | 
| # | 立即数前面要加#或$,表示这是个立即数 | 
1.3 gun汇编中的伪指令
1、ARM中有一个ldr指令,还有一个ldr伪指令,一般都使用ldr伪指令而不用ldr指令
2、adr与ldr:
 ① adr编译时会被sub或add指令替代,
 ② ldr编译时会被mov指令替代或者文字池方式处理
 ③ adr总是以PC为基准来表示地址,指令本身和运行地址有关,用来检测程序当前的运行地址在哪里
 ④ ldr加载的地址和链接时给定的地址有关,由链接脚本决定
| 符号 | 作用 | 
|---|---|
| ldr | 大范围的地址加载 | 
| adr | 小范围的地址加载 | 
| adrl | 中等范围的地址加载 | 
| nop | 空操作 | 
| .global _start | 给_start外部链接属性 | 
| .section .text | 指定当前段为代码段 | 
| .align 4 | 以16字节对齐 | 
| .balignl 16 | 16字节对齐填充 | 
| .end | 标识文件结束 | 
| .include | 头文件包含 | 
| .arm / .code32 | 声明以下为arm指令 | 
| .thumb / .code16 | 声明以下为thubm指令 | 
| .ascii .byte .short .long | 定义数据 | 
| .word.quad .float .string | 定义数据 | 
二、不同风格的ARM指令
ARM官方的ARM汇编风格
 指令一般用大写、 Windows中IDE开发环境(如ADS、MDK等)常用。
LDR R0, [R1]
 
GNU风格的ARM汇编
 指令一般用小写字母、 linux中常用。
 ldr r0, [r1]
 
三、ARM汇编的特点
3.1 LDR/STR架构
1、 ARM的CPU不能直接读取内存,需要先将内存加载到CPU通用寄存器中才能被CPU处理
 2、 ldr(load register)指令将内存加载到通用寄存器
 3、 str(store register)指令将寄存器内容保存到内存空间
 4、 ldr/str组合用来实现 ARM CPU和内存之间数据的交换
3.2 8种寻址方式
| 寻址方式 | 例子 | 
|---|---|
| 寄存器寻址 | mov r1, r2 | 
| 立即寻址 | mov r0, #0xFF00 | 
| 寄存器移位寻址 | mov r0, r1, lsl #3 | 
| 寄存器间接寻址 | ldr r1, [r2] | 
| 基址变址寻址 | ldr r1, [r2, #4] | 
| 多寄存器寻址 | ldmia r1!, {r2-r7,r12} | 
| 堆栈寻址 | stmfd sp!, {r2-r7, lr} | 
| 相对寻址 | beq flag flag: | 
3.3 指令后缀
汇编指令中,同一指令经常附带不同后缀,变成不同的指令
经常使用的后缀有:
1、B(byte)功能不变,操作长度变为8位
 2、H(half word)功能不变,长度变为16位
 3、S(signed)功能不变,操作数变为有符号
 4、S(S标志)功能不变,影响CPSR标志位
//	B    H    SB    SH
ldr ldrb ldrh ldrsb ldrsh
//mov和movsmovs r0, #0
 
3.4 条件执行后缀
| 操作码 | 条件码助记符 | 标志 | 含义 | 
|---|---|---|---|
| 0000 | EQ | Z=1 | 相等 | 
| 0001 | NE | Z=0 | 不相等 | 
| 0010 | CS/HS | C=1 | 无符号数大于或等于 | 
| 0011 | CC/LO | C=0 | 无符号数小于 | 
| 0100 | MI | N=1 | 负数 | 
| 0101 | PL | N=0 | 正数或零 | 
| 0110 | VS | V=1 | 溢出 | 
| 0111 | VC | V=0 | 没有溢出 | 
| 1000 | HI | C=1、Z=0 | 无符号数大于 | 
| 1001 | LS | C=0、Z=1 | 无符号数小于或等于 | 
| 1010 | GE | N=V | 有符号数大于或等于 | 
| 1011 | LT | N!=V | 有符号数小于 | 
| 1100 | GT | Z=0、Z=V | 有符号数大于 | 
| 1101 | LE | Z=1、Z!=V | 有符号数小于或等于 | 
| 1110 | AL | 任意 | 无条件执行(指令默认条件) | 
| 1111 | NV | 任意 | 从不执行(不要使用) | 
3.5 8种后缀
| 后缀 | 含义 | 
|---|---|
| ia | 先传输,再地址+4 | 
| ib | 先地址+4,再传输 | 
| da | 先传输,再地址-4 | 
| db | 先地址-4,再传输 | 
| fd | 满递减堆栈 | 
| ed | 空递减堆栈 | 
| fa | 满递增堆栈 | 
| ea | 空递增堆栈 | 
3.6 4种栈
空栈:栈指针指向空位,存入时可直接存入然后指针移动一格;取出时需要先移动一格才能取出
满栈:栈指针指向栈中最后一格数据,每次存入时需要先移动栈指针一格再存入;取出时可以直接取出,然后再移动栈指针
增栈:栈指针移动时向地址增加的方向移动的栈
减栈:栈指针移动时向地址减小的方向移动的栈
注意:操作栈时使用相同的后缀就不会出错
四、ARM汇编的常用指令
4.1 数据处理指令
| 指令类型 | 指令 | 
|---|---|
| 数据传输指令 | mov mvn | 
| 算术指令 | add sub rsb adc sbc rsc | 
| 逻辑指令 | and orr eor bic | 
| 比较指令 | cmp cmn tst teq | 
| 乘法指令 | mvl mla umull umlal smull smlal | 
| 前导零计数 | clz | 
4.2 CPSR访问指令
CPSR寄存器比较特殊,需要专门的指令进行访问
| 指令类型 | 指令 | 
|---|---|
| mrs | 读取psr | 
| msr | 写入psr | 
4.3 跳转指令
| 指令 | 作用 | 
|---|---|
| b | 直接跳转(跳转后不返回) | 
| bl | 跳转前把返回地址放入lr中,用于函数调用返回 | 
| bx | 跳转同时切换到ARM模式,用于异常处理的跳转 | 
4.4 访存、软中断指令
ldr/str每周期只能访问4字节内存,如果需要批量读取、写入内存时太慢
stm/ldm每周期可以批量读取、写入内存
| 指令 | 作用 | 
|---|---|
| ldr/str | 单个字/半字/字节访问 | 
| ldm/stm | 多字批量访问 | 
| swi(software interrupt) | 软中断指令,用来实现操作系统中系统调用 | 
4.5 协处理器操作指令
1、SoC内部另一处理核心,协助主CPU实现某些功能,被主CPU调用执行一定任务
 2、ARM设计上支持16个协处理器,一般SoC只实现其中的CP15
 3、协处理器和MMU、 cache、 TLB等处理有关
 4、功能上和操作系统的虚拟地址映射、cache管理等有关
| 指令 | 作用 | 
|---|---|
| mrc | 用于读取CP15中的寄存器 | 
| mcr | 用于写入CP15中的寄存器 | 
五、ARM汇编符号的作用
5.1 ! 的作用
ldmia r0   , {r2 - r3}
ldmia r0! , {r2 - r3}
 
!的作用:
r0的值在ldm过程中发生的增加或者减少最后写回到r0去
也就是说ldm时会改变r0的值。
5.2 ^ 的作用
ldmfd sp!, {r0 - r6, pc}
ldmfd sp!, {r0 - r6, pc}^
 
^ 的作用:在目标寄存器中有pc时,会同时将spsr写入到cpsr,一般用于从异常模式返回
