##ARM 汇编基础-- 【GNU 汇编语法】--【Cortex-A7 常用汇编指令】

  • ARM 汇编基础

出栈入栈就要对堆栈进行操作,所谓的堆栈其实就是一段内存,这段内存比较特殊,由 SP 指针访问, SP 指针指向栈顶。芯片一上电 SP 指针还没有初始化,所以 C 语言没法运行,对于有些芯片还需要初始化 DDR负责内存与CPU之间数据交换的重要组成部分。,因为芯片本身没有 RAM,或者内部 RAM 不开放给用户使用,用户代码需要在DDR 中运行,因此一开始要用汇编来初始化 DDR 控制器。

  • GNU 汇编语法

GNU 汇编语法适用于所有的架构,并不是 ARM 独享的, GNU 汇编由一系列的语句组成,每行一条语句,每条语句有三个可选部分

labelinstruction @ comment

注意! ARM 中的指令、伪指令、伪操作、寄存器名等可以全部使用大写,也可以全部使用小写,但是不能大小写混用

常见伪操作

.byte 定义单字节数据,比如.byte 0x12

.short 定义双字节数据,比如.short 0x1234

.long 定义一个 4 字节数据,比如.long 0x12345678

.equ 赋值语句,格式为: .equ 变量名,表达式,比如.equ num, 0x12,表示 num=0x12

.align 数据字节对齐,比如: .align 4 表示 4 字节对齐。

.end 表示源文件结束。

.global 定义一个全局符号,格式为: .global symbol,比如: .global _start

  1. GNU 汇编--函数

函数格式如下:

函数名:

     函数体

     返回语句【不是必须滴】

/* 未定义中断 */

Undefined_Handler:

     ldr r0, =Undefined_Handler

     bx r0 @bx r0”是函数返回语句,

  1. “bx”指令是返回指令,函数返回语句不是必须的
  • Cortex-A7 常用汇编指令

 处理器内部数据传输指令

数据传输常用的指令有三个: MOV、 MRS 和 MSR

  1. 存储器访问指令

常用的存储器访问指令有两种:

LDR:LDR 主要用于从存储加载数据到寄存器 Rx 中

STR:LDR 是从存储器读取数据, STR 就是将数据写入到存储器中

  1. LDR 和 STR 都是按照字进行读取和写入的,也就是操作的 32 位数据
  1. 压栈和出栈指令

在 A 函数中调用 B 函数,当 B 函数执行完以后再回到 A 函数继续执行。要想在跳回 A 函数以后代码能够接着正常运行,那就必须在跳到 B 函数之前将当前处理器状态保存起来(就是保存 R0~R15 这些寄存器值),当 B 函数执行完成以后再用前面保存的寄存器值恢复R0~R15 即可。保存 R0~R15 寄存器的操作就叫做现场保护【压栈】,恢复 R0~R15 寄存器的操作就叫做恢复现场。【出栈】

压栈的指令为 PUSH,出栈的指令为 POP

PUSH 和 POP 是一种多存储和多加载指令,即可以一次操作多个寄存器数据.

PUSH 和 POP 的另外一种写法是STMFD SP“LDMFD SP!” STMFD 可以分为两部分: STM 和 FD,

示例代码    STMFD 和 LDMFD 指令

1 STMFD SP!,{R0~R3, R12} @R0~R3,R12 入栈

2 STMFD SP!,{LR} @LR 入栈

 

4LDMFD SP!, {LR} @先恢复 LR

5 LDMFD SP!, {R0~R3, R12} @再恢复 R0~R3, R12

  1. 跳转指令

有多种跳转操作,比如:

①、直接使用跳转指令 B、 BL、 BX 等。

②、直接向 PC 寄存器里面写入数据。

上述两种方法都可以完成跳转操作,但是一般常用的还是 B、 BL 或 BX

  1. 算术运算指令

ADD Rd, Rn, Rm

Rd = Rn + Rm

加法运算,指令为 ADD

ADD Rd, Rn, #immed

Rd = Rn + #immed

 

SUB Rd, Rn, Rm

Rd = Rn – Rm

减法

SUB Rd, #immed

Rd = Rd - #immed

 

SUB Rd, Rn, #immed

Rd = Rn - #immed

 
         
  1. 逻辑运算指令

基本很好理解,和c一样

 

 

 

 

 

 

你可能感兴趣的:(linux)