Linux_kernel汇编指令05

news2024/9/20 8:08:10

一、温故知新

        1、跳转指令

b{cond} <target_label>

                相当于C语言中的goto

                <target_label>是跳转地址,±32M

                {cond}是条件码,先决条件

                根据CPSR寄存器的NZCV位来决定是跳转还是不跳转

bl

                l:带链接状态,将PC寄存器的值保存到LR寄存器中

                BL跳转的范围是±32M

bx

                ARM有两种工作状态,ARM与Thumb

                x可以进行状态的切换

        2、数据传输指令

mov 数据传输指令

                mov{cond}{S} <Rd>, <OP2>

                        {cond}条件码,是先决条件

                        {S}决定是否影响CPSR寄存器的NZCV位

                        <Rd>一定是通用寄存器

                        <OP2>有三种表现形式:立即数\寄存器\寄存器移位之后的值

mvn 数据取反传输指令

                mvn{cond}{S} <Rd>, <OP2>

                        {cond}条件码,是先决条件

                        {S}决定是否影响CPSR寄存器的NZCV位

                        <Rd>一定是通用寄存器

                        <OP2>有三种表现形式:立即数\寄存器\寄存器移位之后的值

        3、数据处理指令

                1)移位操作

        LSL逻辑左移,空位补0

        LSR逻辑右移,空位补0

        ASR算术右移,最高位补符号位

        ROR循环右移,被移出的位位将重新插入最高位

        RRX带扩展的循环右移,新的最高位由CPSR寄存器的C位补充,拿最低位更新C位

                2)算术运算指令

 add加法指令

                add{cond}{S} <Rd>, <Rn>, <OP2>

                        {cond}条件码,是先决条件

                        {S}决定是否影响CPSR寄存器的NZCV位

                        <Rd>目标寄存器

                        <Rn>操作寄存器

                        <OP2>有三种表现形式:立即数\寄存器\寄存器移位之后的值

adc带进位的加法指令

                adc{cond}{S} <Rd>, <Rn>, <OP2>

                        {cond}条件码,是先决条件

                        {S}决定是否影响CPSR寄存器的NZCV位

                        <Rd>目标寄存器

                        <Rn>操作寄存器

                        <OP2>有三种表现形式:立即数\寄存器\寄存器移位之后的值

                        adc r0, r1, r2        @r0 = r1 + r2 + CPSR.C位

sub减法指令

                sub{cond}{S} <Rd>, <Rn>, <OP2>

                        {cond}条件码,是先决条件

                        {S}决定是否影响CPSR寄存器的NZCV位

                        <Rd>目标寄存器

                        <Rn>操作寄存器

                        <OP2>有三种表现形式:立即数\寄存器\寄存器移位之后的值

sbc带借位的减法指令

                sbc{cond}{S} <Rd>, <Rn>, <OP2>

                        {cond}条件码,是先决条件

                        {S}决定是否影响CPSR寄存器的NZCV位

                        <Rd>目标寄存器

                        <Rn>操作寄存器

                        <OP2>有三种表现形式:立即数\寄存器\寄存器移位之后的值

                        sbc r0, r1, r2        @r0 = r1 - r2 - NOT(CPSR.C位)

rsb逆向减法指令

                rsb{cond}{S} <Rd>, <Rn>, <OP2>

                        {cond}条件码,是先决条件

                        {S}决定是否影响CPSR寄存器的NZCV位

                        <Rd>目标寄存器

                        <Rn>操作寄存器

                        <OP2>有三种表现形式:立即数\寄存器\寄存器移位之后的值

                        rsb r0, #0x08, r1        @语法错误

        4、位运算指令

                and        &

                orr          |

                eor         ^

                bic        清除

        5、比较测试指令 

                cmp        比较指令(内部其实做了一个相减的操作)

                tst           位测试指令

                teq          相等测试指令

注意:比较测试指令即使不加S,默认也会影响CPSR寄存器的NZCV位

二、ARM汇编-加载存储指令 

         图示过程

        1、单寄存器加载指令

                ldr指令用于从存储器(内存)中加载数据到寄存器中

                ldr{cond} Rd, addr        @用于将一个字(32bit)从内存中加载到寄存器中

                        {cond}条件码

                        Rd寄存器

                        addr地址

加载多少个字节可以根据ldr后面的符号来指定
ldrb用于将一个无符号单字节(8bit)从内存中加载到寄存器中
ldrh用于将一个无符号半字(16bit)从内存中加载到寄存器中
ldrsb用于将一个有符号单字节(8bit)从内存中加载到寄存器中
ldrsh用于将一个有符号半字(16bit)从内存中加载到寄存器中
ldrt用于将一个字(32bit)从内存中加载到寄存器中,并保证加载过程不中断
ldrbt用于将一个无符号单字节(8bit)从内存中加载到寄存器中,并保证加载过程不中断
ldrd用于将一个双字(64bit)从内存中加载到寄存器中

        2、单寄存器字/无符号字节加载地址模式

                地址模式 = 基地址 + 偏移地址

                        基地址 = 任意的通用寄存器

                        偏移地址 = 立即数\寄存器\寄存器移位 

        3、ldr示例

[ ]是把内容取出来
ldr r0, [r1]将存储器地址为r1的字数据读到寄存器r0
ldr r0, [r1, #0x8]将存储器地址为r1 + 0x8的字数据读到寄存器r0
ldr r0, [r1, #-0x20]将存储器地址为r1 - 0x20的字数据读到寄存器r0
ldr r0, [r1, r2]将存储器地址为r1 + r2的字数据读到寄存器r0
ldr r0, [r1, -r2]将存储器地址为r1 - r2的字数据读到寄存器r0
ldr r0, [r1, r2, lsl #3]将存储器地址为r1 + r2 * 8的字数据读到寄存器r0
ldr r0, [r1, #0x8]!将存储器地址为r1 + 0x8的字数据读取到r0,并且将r1 + 0x8的值存入到r1
ldr r0, [r1, r2]!将存储器地址为r1 + r2的字数据读到寄存器r0,并且将r1 + r2的值存入到r1
ldr r0, [r1, r2, lsl #2]将存储器地址为r1 + r2 * 4的字数据读到寄存器r0,并且将r1 + r2 * 4的值存入到r1
注意:加“!”表示要更新地址
ldr r0, [r1, #2]将存储器地址为r1 + 2的字数据读到寄存器r0
ldr r0, [r1], #2将存储器地址为r1的字数据读到寄存器r0,并将r1 + 2的值存入到r1
ldr r0, [r1], r2将存储器地址为r1的字数据读到寄存器r0,并将r1 + r2的值存入到r1
ldr r0, [r1], r2, lsl #3将存储器地址为r1的字数据读到寄存器r0,并将r1 + r2 * 8的值存入到r1
注意:先索引(前变址),后索引(后变址)

        4、ldr和mov的区别

                ldr指令用于从内存中加载数据到寄存器

                ldr指令的应用场景

                        【1】从内存中加载变量或者常量到寄存器中

                        【2】加载数组元素到寄存器中

                        【3】进行数据的读取和赋值操作

                mov指令用于在寄存器之间传递数据,或将立即数存储到寄存器中

                mov指令的应用场景

                        【1】在寄存器之间传递数据

                        【2】将立即数加载到寄存器中

                        【3】进行数据的赋值操作

        5、单寄存器存储指令

                str指令用于将寄存器中的数据写入到内存中

                str{cond} Rd, addr        @从寄存器中将一个32bit的字数据传送到存储器中

                        {cond}条件码

                        Rd寄存器

                        addr地址            

strb把寄存器中低8bit数据写入到存储器中
strh把寄存器中低16bit数据写入到存储器中
strt把寄存器中低8bit数据写入到存储器中,并且不会被中断打断

        6、单寄存器字/无符号字节存储地址模式 

                地址模式 = 基地址 + 偏移地址

                        基地址 = 任意的通用寄存器

                        偏移地址 = 立即数\寄存器\寄存器移位 

        7、str示例

str r0, [r1]将r0寄存器中的数据写入到地址值为r1的存储器中
str r0, [r1, #0x08]将r0寄存器中的数据写入到地址值为r1 + 0x08的存储器中
str r0, [r1, r2]将r0寄存器中的数据写入到地址值为r1 + r2的存储器中
str r0, [r1, r2, lsl #3]将r0寄存器中的数据写入到地址值为r1 + r2 * 8的存储器中
str r0, [r1, #0x08]!

将r0寄存器中的数据写入到地址值为r1 + 0x08的存储器中,

并将r1 + 0x08的值存入到r1

str r0, [r1, r2]!

将r0寄存器中的数据写入到地址值为r1 + r2的存储器中,

并将r1 + r2的值存入到r1

str r0, [r1, r2, lsl #3]!

将r0寄存器中的数据写入到地址值为r1 + r2 * 8的存储器中,

并将r1 + r2 * 8的值存入到r1

str r0, [r1], #0x08

将r0寄存器中的数据写入到地址值为r1的存储器中,

并将r1 + 0x08的值存入到r1

str r0, [r1], r2

将r0寄存器中的数据写入到地址值为r1的存储器中,

并将r1 + r2的值存入到r1

三、栈操作指令 

        栈是一种数据结构:FILO(first in last out)

        1、ATPCS

                ATPCS(ARM-Thumb Produces Call Standard),是ARM程序和Thumb程序中调用的基本规则,目的是为了使单独编译的C语言程序和汇编程序之间能够相互调用(内嵌汇编)

        2、ATPCS中各寄存器的名称

                【1】R0~R3        可以记作A1~A4,用于函数间传递参数

                【2】R4~R11      可以记作V1~V8,用于存储函数的局部变量

                        【a】R7        在Thumb工作状态下记作wr(work register)

                        【b】R9        可以记作sb(static base)

                                可以在与位置无关的代码中保存内存的静态地址,在Uboot中R9用来保存.global data的起始地址

                        【c】R10        可以记作sl(stack limit[栈限制])

                                用来检测stack是否overflow,可以把stack的最低端写入sl寄存器中,这样处理后,如果sp指向的地址低于sl寄存器里面的值时,就会触发栈溢出的错误。

                        【d】R11        可以记作fp(frame pointer[帧指针])

                                在函数的调用过程中,通常使用栈帧结构,也就是sp指针总是指向程序的顶端,同时设置fp来保存当前函数在栈上的基地址

-------------------------------------------------------------------------

补充:

        在多进程并发程序中,每一个进程都有自己的栈

        在同一进程中调用函数和被调用函数使用的是同一个栈,我们该如何进行区分?

        我们可以使用桟帧(stack frame)来区分,桟帧就是一个函数所使用的stack的一部分,所有函数的桟帧穿起来就是一个完整的栈,桟帧的两个边界分别是由fp和sp来限定

-------------------------------------------------------------------------

                【3】R12        可以记作ip(内部程序调用暂存器)

                                在子程序中R13(sp)不能作其他的用途,寄存器R13在进入子程序和退出子程序时的值必须相等

                【4】R13        可以记作sp(stack pointer[栈指针])

                【5】R14        可以记作lr(link register[链接寄存器])

                                用于保存调用函数的返回地址

                【6】R15        可以记作pc(program counter[程序计数器])

                                不能作为其他的用途来使用

        3、数据栈的使用规则

                对于ARM来说,支持4中栈,分别是:

                【1】FD        满递减栈

                【2】FA         满递增栈

                【3】ED        空递减栈

                【4】EA        空递增栈

---------------------------------------------------------

F:Full                满栈SP指向最后一个数据

E:Empty           空栈SP指向与最后一个数据相邻的下一个可写单元

D:Descend       递减,代表栈的增长方向

A:Ascend          递增,代表栈的增长方向 

满栈:栈顶本身有数据(SP寄存器指向位置本来有数据)

空栈:栈顶本身没有数据(SP寄存器指向位置本来没有数据)

注意:我们的S5P6818的内核ARM-Cortex-A53的栈所使用的结构就是fd满递增栈

---------------------------------------------------------

        4、指令

                ldr:从存储器加载数据到寄存器

                str:从寄存器存储数据到存储器

                ldm:(load much)多数据加载,将地址上的值加载到寄存器上(相当于出栈) 

                stm:(store much)多数据存储,将寄存器上的值存储到地址上(相当于入栈)

                1)执行格式

                        ldm{cond} mode Rn{!}, register{^}

                        stm{cond} mode Rn{!}, register{^}

                                Rn基址寄存器,存储传送数据的起始地址(Rn不能是R15)

                                !表示最后的地址写回到Rn中

                                register可以包含多个寄存器,用“,”隔开

                                如:{r1, r2, r3, r6-r9}        寄存器由小到大顺序排列

                                ^不允许在用户模式(user)和系统模式(system)下运行

                2)stm示例(入栈操作)

 注意:在ARM的指令系统中,

对于递减的栈,

入栈操作的顺序是从右到左依次入栈

对于递增的栈,

入栈操作的顺序是从左到右依次入栈

                3)ldm示例(出栈操作) 

注意:在ARM的指令系统中,

对于递减的栈,

出栈操作的顺序是从左到右依次出栈

对于递增的栈,

出栈操作的顺序是从右到左依次出栈

                4)反汇编代码

arm-cortex_a9-linux-gnueabi-gcc xxx.c -o xxx

arm-cortex_a9-linux-gnueabi-objdump -S xxx > xxx.s

注意:

xxx:文件名

objdump:反汇编器

         

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2103923.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

浅谈人工智能之VSCode:使用插件与ollama本地大模型交互

浅谈人工智能之VSCode&#xff1a;使用插件与ollama本地大模型交互 我们在之前的文档中已经说明如何使用Ollama部署本地大模型&#xff0c;这里就赘述&#xff0c;具体如何部署可参考文档&#xff1a; 浅谈人工智能之Windows&#xff1a;基于ollama进行本地化大模型部署 准备…

CDKF(中心差分卡尔曼滤波)的MATLAB代码(附下载链接)

文章目录 CDKF介绍运行结果代码下载链接部分代码如下 CDKF介绍 另有关于EKF和CDKF的对比程序&#xff1a;EKFCDKF两个滤波的MATLAB程序&#xff0c;估计三轴位置&#xff0c;带中文注释——https://blog.csdn.net/callmeup/article/details/136610153。此文章所在的专栏还有更…

传统CV算法——基于Opencv的图像绘制

直线绘制 参数解析&#xff1a; &#xff08;图像矩阵&#xff0c;直线起始坐标&#xff0c; 直线终止坐标、颜色、线条厚度&#xff09; cv2.line()是OpenCV中用于绘制直线的函数。 参数说明&#xff1a;img&#xff1a;要绘制直线的图像矩阵。(100,30)&#xff1a;直线的起…

移动端支持风格设计,更个性化的体验

08/28 主要更新模块概览 风格设计 风格配置 列表模式 跳转按钮 01 表单管理 1.1 【表单设计】-新增移动端风格设计 说明&#xff1a; 在此之前&#xff0c;移动端风格一直继承自 PC 端风格&#xff0c;无法进行自定义。…

Ollama拉起本地模型以及rag系统部署。

什么是 Ollama &#xff1f; Ollama 是一个简明易用的本地大模型运行框架。能在本地启动并运行 Llama、qwen、Gemma 及其他大语言模型&#xff0c;没有GPU资源照样可以拉起模型&#xff0c;和LocalAI 比较类似&#xff0c;但是加载模型更容易。 1.安装 安装后运行&#xff0c…

带你0到1之QT编程:四、打地基QHash的高效用法

此为QT编程的第四谈&#xff01;关注我&#xff0c;带你快速学习QT编程的学习路线&#xff01; 每一篇的技术点都是很很重要&#xff01;很重要&#xff01;很重要&#xff01;但不冗余&#xff01; 我们通常采取总-分-总和生活化的讲解方式来阐述一个知识点&#xff01; 码…

安泰功率放大器应用领域:铁电材料极化测试

铁电材料是一种非常重要的电介质材料&#xff0c;不仅具有较高的介电常数&#xff0c;还有显著的热释电效应和压电效应&#xff0c;因此也被广泛应用于从日常生活到高端技术的多个领域。功率放大器作为铁电材料极化测试中常用的测试仪器之一&#xff0c;在该领域也有着良好应用…

【系统方案】网络空间安全态势感知与大数据分析平台建设方案(Doc完整版)

1.1 网络空间态势感知系统系统建设 1.1.1 安全监测子系统 1.1.2 态势感知子系统 1.1.3 通报预警子系统 1.1.4 等保管理子系统 1.1.5 追踪溯源子系统 1.1.6 威胁情报子系统 1.1.7 指挥调度子系统 1.1.8 侦查调查子系统 1.1.9 应急处置子系统 1.1.10 移动APP 1.1.11 运…

html发送邮件的服务器怎么配置?如何设置?

html发送邮件如何保障安全性&#xff1f;HTML发送邮件链接方法&#xff1f; 配置一个能够高效处理html发送邮件的服务器&#xff0c;不仅可以提升邮件的美观性和互动性&#xff0c;还能增强邮件的专业度和吸引力。AokSend将详细介绍如何配置服务器以支持html发送邮件。 html发…

Aigtek功率放大器的基本要求是什么

功率放大器是电子电路中的关键元件&#xff0c;用于增加输入信号的幅度&#xff0c;以便有效地驱动负载。为了确保功率放大器在不同应用中能够可靠地工作&#xff0c;需要满足一系列基本要求。下面安泰电子将详细介绍功率放大器的基本要求&#xff0c;以帮助读者了解其设计和应…

echarts关系图报错Graph nodes have duplicate name or id

生成的关系图&#xff0c;数据有了&#xff0c;展示报错nodes have duplicate name or id&#xff0c;提示节点有重复的名称或id&#xff0c;意思是可能有重复的节点&#xff0c;echarts graph 它不支持所以报错了。如下图 有几百条数据&#xff0c;要找到那条重复的&#xff…

kubernetes集群部署Confluence 7.2.0+mysql 5.7(自测有效)

背景介绍&#xff1a; Confluence是一个专业的企业知识管理与协同软件。使用简单&#xff0c;但它强大的编辑和站点管理特征能够帮助团队成员之间共享信息、文档协作、集体讨论&#xff0c;信息推送。 这里介绍的使用的是Confluence 7.2.0版本的。 一、在kubernetes集群部署 1…

申请SSL证书审核失败的原因和解决方法(DNS验证篇)

如果用户在提交SSL证书审核时使用DNS验证方式进行验证&#xff0c;检查配置时可能会收到未检测到DNS配置内容的返回结果。这种情况下的数字证书审核申请失败是由多个原因造成的。 为了更清楚了解失败的原因&#xff0c;建议使用以下方式查询DNS解析记录值&#xff0c;分析域名…

LNMP环境搭建(Linux+nginx+Mysql+PHP)超详细攻略

目录 一.LNMP简介 1.1LNMP架构的特点 二.详细安装步骤 2.1MySQL安装 2.1-1Yum安装 2.1-2 编译安装 2.1-3二进制安装 2.1-4 RPM安装 2.2Nginx安装 2.2-1编译安装nginx 2.2-2yum安装nginx 2.3验证Nginx安装 2.4PHP安装 2.4-1编译安装PHP 2.4-2yum安装PHP 2.5 Nginx 配…

OpenCSG all in one 安装

https://github.com/OpenCSGs/CSGHub/tree/main/deploy/all_in_one 先下载下来 记得前提是docker 和docker-compose 已经安装好了 进入到deploy 中得all_in_one中 修改.env 中得domain 地址本机地址 修改权限后 运行startup.sh $sudo ./startup.sh 运行相应得docker 信息 可以…

基本放大电路

以输入、输出信号的位置为判断依据&#xff1a; 信号由基极输入&#xff0c;集电极输出——共射极放大电路 信号由基极输入&#xff0c;发射极输出——共集极放大电路 信号由发射极输入&#xff0c;集电极输出——共基极放大电路 三种组态的特点及用途&#xff1a;共射极放大电…

软件设计之JDBC(1)

软件设计之JDBC(1) 此篇应在MySQL之后进行学习: 路线图推荐&#xff1a; 【Java学习路线-极速版】【Java架构师技术图谱】 尚硅谷2024最新JDBC教程 | jdbc基础到高级一套通关&#xff01; 资料可以去尚硅谷官网免费领取 学习内容&#xff1a; 前言JDBCPreparedStatement实现…

IAR查看程序占用的内存空间

参考&#xff1a;IAR分析内存重要的神器 - map文件全解析-CSDN博客 IAR软件*.map文件查看程序占用ROM和RAM大小_iar 通过map文件查看占用内存空间-CSDN博客 编译工程后&#xff0c;可以在MAP文件的最后面查看&#xff0c;程序占用空间的大小 readonly code和readonly data使用…

OPenCV结构分析与形状描述符(1)近似多边形轮廓顶点的函数approxPolyDP()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 按指定的精度近似一个多边形曲线 cv::approxPolyDP 函数使用另一条曲线或多边形来近似一条曲线或多边形&#xff0c;新曲线或多边形的顶点数较少…

PYTHON发送邮件详细流程

不求别的你要是觉得有用给我一个关注攒攒❤ 安装第三方库 dos命令窗口 pip install pyEmail 两个邮箱准备齐&#xff1a; 我让我的163邮箱做服务器向qq邮箱发邮件 互联网上的两个软件要想通信要有协议&#xff0c;因此开启协议 import smtplib #协议包 from email.mime.t…