前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >linux内核学习(四)之回顾简单的汇编知识(一))

linux内核学习(四)之回顾简单的汇编知识(一))

作者头像
用户6280468
发布2022-03-21 14:09:58
5090
发布2022-03-21 14:09:58
举报
文章被收录于专栏:txp玩Linux

大家周末晚上好,今天给大家分享一些简单的汇编知识;说起汇编,不管是学习或者说工作中,都会或多或少的接触到,比如说学习中,在进入c语言编程世界之前,都会有一段汇编作为引导来进入c的;当然在实际开发当中,现在用汇编来开发的比较少,不是没有;做一为嵌入式软件工程师,我觉得还是非常有必要要掌握一些基本的汇编指令知识的,不要你会写汇编代码,要求自身会分析以.s结尾的文件里面的汇编代码就差不多了,看的懂常规汇编指令就行(这里顺便插一句题外话,我们知道一般ARM都是采用risc架构的,如果有网友对risc-v架构感兴趣的,可以来交流学习),好了,废话就不多说了,开始进入主题啦!

一、ARM体系之寄存器介绍:

在写这个寄存器介绍之前,给大家看一下linux内核代码文件head.S里面的汇编代码,感受一下,暂时看不懂没关系:

代码语言:javascript
复制
					@ and irqs disabled
	mrc	p15, 0, r9, c0, c0		@ get processor id
	bl	__lookup_processor_type		@ r5=procinfo r9=cpuid
	movs	r10, r5				@ invalid processor (r5=0)?
	beq	__error_p			@ yes, error 'p'
	bl	__lookup_machine_type		@ r5=machinfo
	movs	r8, r5				@ invalid machine (r5=0)?
	beq	__error_a			@ yes, error 'a'

这里讲的汇编代码书写风格是基于arm处理器,如果是Intel(AMD)的汇编风格是这样的:

代码语言:javascript
复制
	subq	$16, %rsp
	movl	$9, -4(%rbp)
	movl	-4(%rbp), %eax
	movl	%eax, %esi
	movl	$.LC0, %edi
	movl	$0, %eax
	call	printf
	movl	$0, %eax

好了,这里也只是感受一下,具体Intel(X86-64)的汇编风格,我后面会在c语言专辑里面详细写到(结合我们平时的c语言程序类具体分析!),这里我就不偏离主题了。那么为什么CPU在运行的时候要有寄存器这么东西呢,我之前看过一段话,解释的比较到位:

想象CPU是一个圈一直在运转,然后寄存器里面有大量的指令,这些指令不知道从哪里来的,但是一般情况下我们的CPU在计算我们的程序,我们的程序一般是放在内存里面的,它从内存里面把这些程序读进来之后,再运行,但是如果现在这个程序在运行时异常,那么就要进行CPU状态的切换,除了状态切换之外,当前的一些数据结果需要进行一个保存,但是如果要把这个结果存到内存去,内存并不稳定并且很慢,所以就要想办法能不能找到一个临时空间保存一下,这就是为什么会诞生寄存器。

接下来我们先来看一下ARM里面的寄存器分类:

image

ARM 处理器一般共有 37 个寄存器,其中包括:

1、 31 个通用寄存器,包括 PC(程序计数器)在内,都是 32 位的寄存器。

2、 6 个状态寄存器,也都是 32 位的寄存器。

同时ARM处理器有7种处理模式:

代码语言:javascript
复制
1、用户模式(User)
2、快速中断模式(FIQ)
3、普通中断模式(IRQ)
4、管理模式(Svc)
5、数据访问中止模式(Abort)
6、未定义指令中止模式(Und)
7、系统模式(Sys)

在任意一种处理器模式下,可见的寄存器包括 15 个通用寄存器(R0~R14)、一个或者二个状态寄存器以及程序计数器(PC)。在所有的寄存器中,有些是各模式共用同一个物理寄存器,有些寄存器是各个模式自己拥有独立的物理寄存器,这里就不具体展开叙述了。

(1)ARM状态下的通用寄存器与程序计数器:

(2)ARM状态下的程序寄存器:

注意上面表格中小影阴直角三角形表示的是分组寄存器,所谓分组寄存器,就是说是当前模式下独有的,不共享。

注解:

--1 其中 r0~r3 主要用于子程序间传递参数, r4~r11 主要用于保存局部变量,但在 Thumb 程序中,通常只能使用 r4~r7 来保存局部变量;r12 用作子程序间scratch 寄存器,即 ip 寄存器;r13 通常用做栈指针,即 sp;r14 寄存器又被称为连接寄存器(lr),用于保存子程序以及中断的返回地址,也就是说它就是去连接某一个地方;r15 用作程序计数器(pc),由于 ARM 采用了流水线机制,当正确读取了 PC 的值后,该值为当前指令地址加 8 个字节,即 PC 指向当前指令的下两条指令地址:

SP:栈指针,存储栈地址,比如有个CPU,然后还有个外部资源也就是内存,我们想象CPU在程序跳转的时候在运行是最核心的ALU单元,然后外部资源存储着程序A和程序B还有程序C,实际上在CPU在读程序A的时候,可能下面的时候会跳到程序B单元,这个时候它可能不知道地址在哪里,那么这个时候就存储在SP这个寄存器里面,SP这个寄存器表示后面将要执行的程序。

LR:链接寄存器,存储于程序返回地址。这个链接寄存器主要用在函数A和函数B,A正在运行时,突然要调用B,那么就引了一个分支了,然后这个函数B去运行,运行完之后还是要返回到最初然后继续往下走,那么这个时候返回值应该要有个记录,这就是链接寄存器。

CPSR和SPSR都是程序状态寄存器,其中SPSR是用来保存中断前的CPSR中的值,以便在中断返回之后恢复处理器程序状态;CPSR是当前程序状态寄存器的意思,SPSR是程序状态保存寄存器,这里我在网上看到一个非常通俗易通的解释这两个寄存器的用法:

已存储程序状态寄存器。想象一个程序正在运行,这个程序当前状态正常,这个状态就先把它保存到CPS里面,这个时候突然发生异常,那么当前状态就应该变成异常,就把这个状态存到CPSR上面,但是异常处理完了之后,我们希望还是能够回到之前那个状态,但是这个时候当时的状态已经被清理掉了,这个时候我们就可以用SPSR把原来那个状态保存,这样当状态在发生改变的时候,要还原就可以去SPSR里面读取之前那个状态,这就是它们之间的关系,就类似有一个A的变量,给A这个变量赋了一个值,然后还赋了一个新值,但是又希望原来那个值要保存,所以有个变量B,然后把变量A赋给变量B。

--2 通过上面的图片,我们仔细观察到:

各个模式的R0到R12与USR模式是共享的(除了FIQ,R8-R12),PC,CPSR是共享的。而且要注意到USR模式没有SPSR的。

二、汇编指令和伪指令:

本来上次的文章中有介绍这个,当时可能没有系统给大家分享完,所以我这里再稍微提一下,这次专题,把完整分享完。

1、(汇编)指令:

它是CPU机器指令的助记符, 经过编译后会得到一串10组成的机器码, 可以由CPU读取执行。

2、(汇编)伪指令:

它本质上不是指令(只是和 指令一起写在代码中),它是编译器环境 提供的,目的是用来指导编译过程,经过 编译后伪指令最终不会生成机器码。

3、两个寄存器:

代码语言:javascript
复制
ldr(load register)指令将内存内容加载入 通用寄存器。

str(store register)指令将寄存器内容存入 内存空间中。

4、ARM的8种寻址方式(同样这里先理性了解一下):

代码语言:javascript
复制
• 寄存器寻址 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

6、指令后缀:

同一指令经常附带不同后缀,变成不同的 指令。经常使用的后缀有:

• B(byte)功能不变,操作长度变为8位

• H(half word)功能不变,长度变为16位

• S(signed)功能不变,操作数变为有符号  如 ldr ldrb ldrh ldrsb ldrsh

• S(S标志)功能不变,影响CPSR标志位  如 mov和movs movs r0, #0

7、条件执行后缀:

三、总结:

今天的简单分享了一些ARM汇编概念,下期我们就开始具体学习汇编常用的汇编指令了,也就是我们在实际分析汇编代码中会遇到有用的汇编指令了。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-05-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 txp玩Linux 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档