2.艰难学习Linux系统之难啃的骨头汇编指令

汇编指令
前言:
在上一篇对一些必须了解的知识进行了学习,虽然还是没怎么记住,但是没事多
看几遍应该是没问题的,反正我就是相信能记下来。。哈哈
现在开始不太愿意学习的一篇,汇编指令,虽然平时用的不多,但是在启动文件和一些
特定的场合还是需要汇编的,早晚都要学的,不如就现在让他来的更猛烈些吧。
学习步骤,对常用的汇编指令回忆一遍,然后在以后用到哪个再详细记一下。我的直觉告诉我,这样做是没有问题的。。。


1.ARM处理器对ROM RAM 和IO地址采用统一编址,除了对RAM的操作外,对外围IO,程序的访问都要通过加载存储指令。
那么就来了。。。。。。。。。。。。
LDR R0 [R1] 表示R1指向的存储单元加载到R0寄存器
STR R0 [R1] 表示R0寄存器的内容存储到R1所指向的存储单元


LDM(IA) R0,{R1-R4} 将R0指向的存储单元加载到R1-R4寄存器。
STM(IA)与上面的相反
其实还是蛮好记的,存储相关的常用的就这三个
2.接下来就是数据处理指令了,有点小混乱但是捋清就好了。。
(1)数据传送指令(MOV)算术逻辑运算指令(ADD SUB BIC ORR)和比
较指令
(CMP TST)
完了,混球球了。。。
Mov指令有点像上面的LDR,但是不同
MOV R0 #8 相当于R0=8
MOV R0,R1 将R1的数传送到R0
MOV R0,R1,LSL #3 将R1的数据左移三位然后传送给R0
MOV PC,LR 将R14的值传送给R15.


(2)下面是逻辑运算指令
ADD R0,R1,#1 将R1的值加1后加载到R0中
ADDS R0,R1,#1 加了s之后表示指令执行后可能会影响当前程序寄存器CPSR中的条件标志位,虽然现在不知道具体啥用,先记着吧
BIC R0, R0,#0xF 将R0后四位清零然后保存到R0
ORR R0, R0,#0xF 将R0后四位置一,重新保存到R0
这俩基友感觉像C中的与和或。


(3)接下来是比较指令,感觉没那么乱了有木有。


不过接下来这俩貌似不好理解但是很重要的。
CMP {cond}Rn, operand2 将寄存器Rn的值减去operand2,根据操作结果更新CPSR中的条件标志,以便后面的指令根据条件标志来判断。麻蛋,运算半天只是为了置标志位,哪条语句用的到标志位还不知道。
TST {cond}Rn, operand2将寄存器Rn的值与operand2按位进行逻辑运算,然后结果和上面那个变态一样只是为了置标志位。


3.跳转指令来了,小心跳蒙圈。
B 跳转到指定地址
BL 带返回地址的跳转。
4.程序状态寄存器访问指令
MRS 读程序状态寄存器指令
MSR 写程序状态寄存器指令
这两个能对程序状态寄存器进行操作,常用来切换工作模式。只有在特权模式下才能操作程序状态寄存器。
例:读->修改->写
MRS R0,CPSR 将CPSR的内容读入R0
  BIC R0,R0, #0x1F 将CPSR中与模式有关的位清零
ORR R0,R0 #0xD3 重新修改模式控制位
MSR CPSR_cxsf,R0 修改后的值写入到CPSR中。
5.协处理器访问指令
开始说了ARM用于存储管理的有MMU和CP15
MRC MCR
mrc p15, 0, r0,c1,c0,0 将协处理器c1中的内容读到R0中
mcr p15, 0, r0,c1,c0,0将R0中的数据写入到C1中。
注:
ASR #n 算术右移n位
LSL #n 逻辑左移n位
LSR#n 逻辑右移n位
新的一天开始新的篇章,哎,昨天的知识忘得差不多了,不管了,接着向下梳理,只能每天再多复习一下旧知识了。
6. ARM寻址方式:
从指令中给出的地址码字段寻找到指令执行所需要的真实操作的方式、
包括以下寻址方式:
立即寻址 ,寄存器寻址 ,寄存器移位寻址 ,寄存器间接寻址, 基址寻址 
多寄存器寻址,堆栈寻址,块拷贝寻址。
(1)MOV R1 #9 将9传送到寄存器R1中(立即寻址)
(2)MOV R2 R1 将寄存器R1中的数据传送到寄存器R2中。(寄存器寻址)
(3)MOV R2,R1,LSL #3 将R1的值逻辑左移三位再将操作后的值传送给R2(移位寻址)
(4)LDR R1,[R0] 将R0所指向的存储单元的内容加载到R1,地址码给的是一个编号。(间
接寻址)
(5)LDR R1,[R0,#4] 将R0中的值加上4形成地址,将此地址的内容加载到R1.(基址寻址)
(6)多寄存器寻址就是可以一次传送几个寄存器的值。
(7)堆栈寻址  堆栈是按照特定顺序进行访问的存储区
STMFD SP!,{R0-R2} 将寄存器R0~R2中的数据压入堆栈中。!说明最后堆栈指
针更新。指针指向最后入栈的数据
LDMFD是出栈。
(8)块拷贝寻址 STMTA  R0!,{R1-R7} 将R1-R7的数据保存,存储指针在保存第一个
值后增加,增加方向向上。
顺了一遍感觉寻址方式很是清晰,也知道了上面汇编指令的应用。
7.伪指令和伪操作
还整个伪,感觉上是假操作???还是为了转晕人的操作??
伪指令是汇编程序对源程序进行汇编器件,将源程序替换为合适的ARM指令或者Thumb指令。作用还挺大。。。。。
(1)GET指令 类似于c中的include,包含文件用的
(2)AREA,用于定义一个段。ENTRY指定程序的入口 END源文件结束
  不要问我什么是段,汇编分段设计,利于实现分散加载机制。反正人家就分段,
你就这么看就得了
(3)EXPOPRT(在本源文件定义)  IMPORT(不在本源文件定义)声明外部标号。
(4)EQU定义常量,定义外设地址。
(5)LTORG定义一个数据缓冲区,这里叫文字池(呕吐!!!!)
(6)ALIGN,调整地址指针使位置对齐。
(7)MACRO MEND用于宏定义,这俩是一对。
(8)MAP (内存表首地址)和FIELD(内存表数据域)组合使用类似于定义一个数组
的操作。
(9)LDR伪指令和正常指令的区别是伪指令地址标号前要有个=号。
(10)adrl  r0 数据表地址 将数据表首地址加载到R0.


伪指令内容很多,但是先掌握上面这一点点应该也够应付一阵子了,不够再学吧。毕竟是个大坑,路还是要向前走的。




启动代码中常用的两个伪操作:
DCD 用于分配一个连续的内存单元,并用expr初始化
SPACE 分配一块内存单元,并初始化为0。


这有一个常用的指令
LDR RC, =0x30000000(开发板的内存地址),当向程序计数器PC直接赋值时可以实现程序的跳转,这句的意思就说程序跳转到内存中执行。


根据实际的情况分析一些汇编代码,基本这部分算是告一段落了。。。。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值