ARM汇编基础

一、GNU汇编语法#

GNU 汇编语法适用于所有的架构,并不是 ARM 独享的

GNU 汇编由一系列的语句组成,每行一条语句,每条语句有三个可选部分,如下:

label:instruction@comment

label:标号,表示地址位置

instruction:指令,汇编指令或伪指令

@符号:表示后面的是注释

comment:注释内容

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

使用伪操作来定义一个段,

预定义段名

.text 表示代码段。

.data 初始化的数据段。

.bss 未初始化的数据段。

.rodata 只读数据段。

默认入口标号是_start

常见的伪操作:

.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. MOV指令

将数据从一个寄存器拷贝到另一个寄存器,或将一个立即数传递到寄存器里面

MOV R0,R1 @将寄存器 R1 中的数据传递给 R0,即 R0=R1
MOV R0, #0X12 @将立即数 0X12 传递给 R0 寄存器,即 R0=0X12
2. MRS指令

将特殊寄存器(如 CPSR 和 SPSR)中的数据传递给通用寄存器,读取特殊寄存器的数据只能使用 MRS 指令

MRS R0, CPSR @将特殊寄存器 CPSR 里面的数据传递给 R0,即 R0=CPSR
3. MSR指令

与MRS指令相反,将普通寄存器的数据传递给特殊寄存器,写特殊寄存器只能使用MSR

MSR CPSR, R0 @将 R0 中的数据复制到 CPSR 中,即 CPSR=R0
存储器访问指令

ARM 不能直接访问存储器,用汇编配置I.MX6Q寄存器的时候需要借助存储器访问指令,一般要将配置的值写入Rx(X=0~12)寄存器中,然后借助存储器访问指令将寄存器Rx的数据写入I.MX6Q寄存器中。

1. LDR指令

从存储加载数据到寄存器Rx中,或加载一个立即数。LDR加载立即数的时候要用=,而非#。

1 LDR R0, =0X0209C004 @将寄存器地址 0X0209C004 加载到 R0 中,即 R0=0X0209C004
2 LDR R1, [R0] @读取地址 0X0209C004 中的数据到 R1 寄存器中
2. STR指令

将数据写入存储器

1 LDR R0, =0X0209C004 @将寄存器地址 0X0209C004 加载到 R0 中,即 R0=0X0209C004
2 LDR R1, =0X20000002 @R1 保存要写入到寄存器的值,即 R1=0X20000002
3 STR R1, [R0] @将 R1 中的值写入到 R0 中所保存的地址中
压栈和出栈指令

现场保护:函数调用前保存当前处理器状态,需要进行压栈操作,指令为PUSH

恢复现场:在调用完成后恢复,进行出栈操作,指令为POP。

 指令 描述

PUSH 将寄存器列表存入栈中。

POP 从栈中恢复寄存器列表。 

堆栈向上增长:就是地址从低址向高地址增长。下一个存储地址比前一个地址更大。堆栈向下增长:就是地址从高地址项低地址增长。下一个存储地址比前一个地址更小。

处理器的堆栈是向下增长的

PUSH {R0~R3, R12} @将 R0~R3 和 R12 压栈
PUSH {LR} @将 LR 进行压栈
POP {LR} @先恢复 LR
POP {R0~R3,R12} @在恢复 R0~R3,R12

PUSH 和 POP 的另外一种写法是“STMFD SP!”和“LDMFD SP!”

跳转指令
  • 直接使用跳转指令:B、BL、BX等
  • 直接向PC寄存器里面写入数据
1. B指令

将PC寄存器的值设置为跳转目标地址

1 _start:
2
3 ldr sp,=0X80200000 @设置栈指针
4 b main @跳转到 main 函数
1. BL指令

BL指令在跳转之前会在寄存器LR(R14)中保存当前PC寄存器值

1 push {r0, r1} @保存 r0,r1
2 cps #0x13 @进入 SVC 模式,允许其他中断再次进去
3
5 bl system_irqhandler @加载 C 语言中断处理函数到 r2 寄存器中
6
7 cps #0x12 @进入 IRQ 模式
8 pop {r0, r1}
9 str r0, [r1, #0X10] @中断执行完成,写 EOIR
算数运算指令

常用加减指令

逻辑运算指令

 

作者:Hkhkl497

出处:https://www.cnblogs.com/hkhkl497/p/17157206.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   Hkhkl497~  阅读(39)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
  1. 1 你不知道的事 王力宏
  2. 2 星座 王力宏
  3. 3 遗失的心跳 萧亚轩
  4. 4 爱错 王力宏
  5. 5 放开你的心 王力宏
  6. 6 另一个天堂 王力宏,张靓颖
  7. 7 让我取暖 王力宏,彭羚
遗失的心跳 - 萧亚轩
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.

作词 : 萧亚轩

作曲 : Per Eklund/Svante Halldin/Emilh Tigerlantz/Viktoria Sandstrom

编曲 : 陈星翰

回忆上了发条 总准时报到

我让日夜颠倒 因为黑夜太难熬

总以为哭过就好 梦和现实对调

穿越了城市的喧闹 心跳却感应不到

夜太深 心跳呢

夜太深 心跳呢

已经 遗失了 不见了

爱上你 心跳呢

慢慢 停止了 不爱了

你紧紧拥抱我入睡

你紧紧拥抱我入睡

曾经是永恒的画面

心痛着 你的爱 残酷的纪念

散落一地拥抱 像是在宣告

散落一地拥抱 像是在宣告

不等答案揭晓 我选择潇洒走掉

把家重新打扫 用香水味盖掉

但寂寞像是一场海啸 心跳被吞噬掉

夜太深 心跳呢

夜太深 心跳呢

已经 遗失了 不见了

爱上你 心跳呢

慢慢 停止了 不爱了

你紧紧拥抱我入睡

你紧紧拥抱我入睡

曾经是永恒的画面

心痛着 你的爱 残酷的纪念

你的爱已停止心跳

你的爱已停止心跳

急救也无效 越爱越想逃跑

自由是你唯一想要 Say goodbye

夜太深 心跳呢

夜太深 心跳呢

已经 遗失了 不见了

爱上你 心跳呢

慢慢 换谁了 心碎了

就算快乐再也找不到

就算快乐再也找不到

就算永远变成了玩笑

我努力 找到我 遗失的心跳

more_horiz
keyboard_arrow_up light_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示