Keil汇编相关知识

news2024/11/23 21:11:26

一、汇编的组成

1.汇编指令:在内存中占用内存,执行一条汇编指令会让处理器进行相关运算

分类:数据处理指令,跳转指令,内存读写指令,状态寄存器传送指令,软中断产生指令,协助处理器指令

2.伪操作:不是汇编指令,不占用指令周期,起到声明作用

3.伪指令:不是汇编指令,占用指令内存,当执行伪指令会让处理器进行对应的运算操作,通常伪指令是一条或多条汇编指令的另外一种用法

4.注释:

单行注释:@,其他架构汇编注释可能是;
多行注释:/**/
条件编译:
.if 逻辑值
代码段
.else
代码段
.endif

二、汇编指令的基本格式

<opcode>{<cond>}{s}        <Rd>,        <Rn>,        <shifter_operand>
<opcode>:汇编指令的指令码,由指令码决定现在是哪一个指令
cond:条件码,可以有可无,执行指令前先判断,满足才执行指令
s:指令码后加s,表示指令的运算结果会影响到CPSR寄存器的条件位
Rd:目标寄存器,指令运算结果会保存在目标寄存器中
Rn:第一操作寄存器,只能写寄存器,参与运算的第一个数值
shifter_operand:第二操作数,可以是寄存器,也可以是一个立即数
运算解释:先判断条件码对应条件是否满足,如满足则将第一操作数与第二操作数按指令码进行运算,运算的结果保存在目标寄存器中,并且结果影响CPSR条件位

三、数据搬移指令

1.mov{条件码} 目标寄存器,操作数vn
条件码可有可无,当存在条件码时,需满足条件才能1将操作数的数值搬移到目标寄存器
2.mvn{条件码} 目标寄存器,操作数
将操作数按位取反后的结果搬移到目标寄存器中
3.立即数
能够当作指令的一部分直接去执行的数据,操作数在当作指令的一部分执行时,需要对该操作数进行处理并保存到指令空间的[11:0]位中,如果处理完毕能够保存进去,说明该操作数是立即数。
处理方式:对该操作数进行循环右移偶数位,如果右移过程中,该操作数右移的值有在0-255这个范围内,说明该操作数是一个立即数,此时将循环右移的值保存在指令空间的[7:0]位,循环右移的偶数位数除以2的值保存到指令空间的[11:8]中(快速判断是否立即数:起始位为1和结束位为1之间的位数要小于7是立即数),当循环右移始终得不到0-255的数据,此时将其取反,如果取反值在0-255之间,该数据也是立即数
4.如果要将一个非立即数保存到寄存器中,可以使用伪指令LDR

四、数据移位指令

算术右移:除了最高符号位不变,最低位移出,最高位补0
逻辑右移:lsr{条件码},目标寄存器,第一操作寄存器,第二操作数
        最低位移出,最高位补0,将第一操作寄存器的数值右移第二操作数对应的位数
循环右移:ror{条件码},目标寄存器,第一操作寄存器,第二操作数
        最低位移出,补到最高位,将第一操作寄存器的数值循环右移第二操作数对应的位数
逻辑左移:lsl{条件码},目标寄存器,第一操作寄存器,第二操作数
        将第一操作寄存器的数值左移第二操作数对应的位数
在书写操作数时可以使用c风格移位运算:如:mov r1,#(oxff>>4);

五、位运算指令

与:与0置0,与1不变
and{条件码},目标寄存器,第一操作寄存器,第二操作数
将第一操作寄存器和第二操作数进行按位与操作,结果保存到目标寄存器中

或:或1置1,或0不变
orr{条件码},目标寄存器,第一操作寄存器,第二操作数
将第一操作寄存器和第二操作数进行按位或操作,结果保存到目标寄存器中

异或:相同为0,相异为1
eor{条件码},目标寄存器,第一操作寄存器,第二操作数
将第一操作寄存器和第二操作数进行按位异或操作,结果保存到目标寄存器中

按位取反
mvn{条件码},目标寄存器,操作数
将操作数进行按位取反操作,结果保存到目标寄存器中

按位清0:想要运算结果为0,则给一个运算数据1
bic{条件码},目标寄存器,第一操作寄存器,第二操作数
将第一操作寄存器和第二操作数进行按位清零操作,结果保存到目标寄存器中

六、算数运算指令
1.加法指令:
        add{条件码}{s}目标寄存器,第一操作寄存器,第二操作数
        将第一操作数寄存器的值加第二操作数,结果保存到目标寄存器,如果在指令后加s,结果会影响CPSR条件位
        adc{条件码}{s}目标寄存器,第一操作寄存器,第二操作数
         将第一操作数寄存器的值加第二操作数再加上CPSR的c位值,结果保存到目标寄存器,如果在指令后加s,结果会影响CPSR条件位
2.减法指令:
        sub{条件码}{s}目标寄存器,第一操作寄存器,第二操作数
        将第一操作数寄存器的值减去第二操作数,结果保存到目标寄存器,如果在指令后加s,结果会影响CPSR条件位
        sbc{条件码}{s}目标寄存器,第一操作寄存器,第二操作数
         将第一操作数寄存器的值减去第二操作数再减去CPSR的c位值取反,结果保存到目标寄存器,如果在指令后加s,结果会影响CPSR条件位
3.乘法指令:mul{条件码}{s}目标寄存器,第一操作寄存器,第二操作数
        将第一操作数寄存器的值乘以第二操作数,结果保存到目标寄存器,如果在指令后加s,结果会影响CPSR条件位
4.在32位的处理器上进行64位的数据运算:将64位数据保存两个寄存器中,先运算低32位,运算结果影响CPSR位,后运行高32位考虑CPSR位
七、比较指令

cmp 第一操作寄存器,第二操作数
        进行两个数的比较,比较指令的本质时两个数的减法运算,运算结果影响CPSR条件位,一般比较指令会和条件码一起使用,先通过比较指令产生条件,后面的指令加上条件码,判断条件码对应的条件是否满足

八、跳转指令

1.修改PC值实现跳转,如果修改的的PC值不是4的倍数,处理器会将这个数值的最低两位设置为0,凑成4的整数倍
2.跳转指令
        b label:程序跳转到标签lable位置去执行,只能实现跳转,LR寄存器不保存返回地址
        bl label:程序跳转到标签label位置去执行,LR寄存器保存返回地址

九、内存读写指令
Keil调试过程中内存的查看
1.查看读写权限范围

2.查看内存内容

3.单寄存器内存读写指令
将一个寄存器的值写入内存中或者从内存中读取数值放在寄存器中
        向内存中写入:
        1)str 目标寄存器,[目标地址],将目标目标寄存器的4字节数据保存到目标地址对应的内存空间
        2)strh 目标寄存器,[目标地址],将目标目标寄存器的2字节数据保存到目标地址对应的内存空间
        3)  strb 目标寄存器,[目标地址],将目标目标寄存器的1字节数据保存到目标地址对应的内存空间
        从内存中读:
        1)ldr 目标寄存器,[目标地址],从目标地址对应空间的空间中,读取4字节数据保存到寄存器中
        2)ldrh 目标寄存器,[目标地址],从目标地址对应空间的空间中,读取2字节数据保存到寄存器中
        3)   ldrb 目标寄存器,[目标地址],从目标地址对应空间的空间中,读取1字节数据保存到寄存器中
        单寄存器内存操作过程中的地址偏移:
        1)    str 目标寄存器,[基地址,偏移量],将目标目标寄存器的4字节数据保存到基地址+偏移量为首地址对应的内存空间
        2)  ldr 目标寄存器,[基地址,偏移量],从基地址+偏移量为首地址的内存中读取数据保存到目标寄存器
4.批量寄存器内存读写
通过指令将多个寄存器中的数据写入到内存或者从内存中读取多个数据保存到多个寄存器
        写入到内存:
        1) stm 目标地址,{寄存器列表},将寄存器列表中的每一个寄存器的值写入到目标地址对应的内存空间
        从内存中读取:
        1) ldm 目标地址,{寄存器列表},从目标地址对应的内存空间中读取多个数据保存到寄存器列表中的每一个寄存器中
        注意:
        寄存器列表书写模式可以使用“,”分割每个寄存器
        如果寄存器编号是连续的,可以使用“-”连接头尾
        无论寄存器列表的寄存器顺序是如何,始终都是小编号的寄存器对应低地址
        批量寄存器的地址增长:
        在操作多个寄存器时,只有一个寄存器保存操作的地址,正常情况下,操作完地址之后,保存操作地址寄存器里的地址要发生相应的增长,防止多次内存读写时,内存数据发生覆盖
 写入到内存:
        1) stm 目标地址!,{寄存器列表},将寄存器列表中的每一个寄存器的值写入到目标地址对应的内存空间,同时操作目标地址会改变
        从内存中读取:
        1) ldm 目标地址!,{寄存器列表},从目标地址对应的内存空间中读取多个数据保存到寄存器列表中的每一个寄存器中,同时操作目标地址会改变
        指令不同后缀可让地址进行不同方向增长:
        1)ia:先操作目标地址,再保存目标地址的寄存器的往地址大的方向增长
        2)ib:先将保存目标地址的寄存器的往地址大的方向增长,再操作目标地址
        3)da:先操作目标地址,再保存目标地址的寄存器的往地址小的方向增长
        4)db:先将保存目标地址的寄存器的往地址小的方向增长,再操作目标地址

十、栈内存读写
        栈是一段内存,是分配出来用于保存一些临时数据,通过SP栈指针寄存器保存栈顶地址
        栈的分类:
        增栈:压栈时,SP值往高地址方向增长
        减栈:压栈时,SP值往地址低方向增长
        空栈:压栈结束,栈指针寄存器对应的栈空间没有有效数据
        满栈:压栈结束,栈指针寄存器对应的栈空间有有效数据
        根据两种不同标准相互结合,分为:满增栈(FA),满减栈(FD),空增栈(EA),空减栈(ED)
        ARM处理器操作内存时默认使用满减栈
        满减栈的压栈与出栈
        压栈:
        push{寄存器列表},将寄存器列表中每一个寄存器的值压栈
        stmdb {寄存器列表}
        stmfd {寄存器列表}
        出栈:
        pop{寄存器列表},从栈内弹出数据保存到寄存器列表的每一个寄存器中
        ldmia {寄存器列表}
        ldmfd {寄存器列表}

十一、状态寄存器传送指令

状态寄存器CPSR保存程序相关状态,通过状态寄存器指令可读取状态寄存器的值或修改CPSR的值改变程序工作状态
        读状态寄存器
        MRS 目标寄存器,CPSR,将CPSR的数值读取到目标寄存器中
        修改CPSR值
        MSR CPSR,操作数,将操作数的数值写入到CPSR寄存器中
注意:在特权模式下可以修改CPSR的值切换到USER模式,但是USER模式下不可以通过修改CPSR的值切换到特权模式,只有在特定移除才可以从USER切换到其他特权模式

十二、软中断产生指令

1.swi 操作数,产生一个软中断,操作数是一个12位的立即数,用于表示不同的软中断
2.异常模式与异常源
        异常模式:产生异常之后处理器进入的工作模式
        异常源:引发处理器进入异常模式的源头就是异常源
        ARM有5中异常模式,7种异常源

异常模式异常源
FIQ触发FIQ中断
IRQ触发IRQ中断
SVC复位
SVC软中断
ABORT取数据异常
ABORT取指令异常
UNDEF遇到未定义的指令

3.异常向量表
异常向量表是一段内存,这段内存一般加载在硬件程序开头,异常向量表大小是32字节,分为8等分,一份对应一个异常源。在异常向量表中存储了索引异常源对应的异常处理程序指令,当触发异常后,处理器会根据异常源的类型在异常向量表中得到异常处理程序的位置,进而执行异常。每一个异常源在异常向量表中的位置是固定的。

4、异常处理过程分析

触发异常后,处理器做了四大步三小步完成异常处理的转变工作,该工作由处理器自动完成,程序员需要做的是编写异常处理程序,修改程序异常向量表
        1)保存产生异常时的程序状态(CPSR)到对应异常的SPSR寄存器中
        2)修改CPSR的数值切换程序工作状态
                a.将程序的工作模式切换到对应对应的异常模式[4:0]
                b.根据触发的异常的优先级,将FIQ和IRQ中断禁用[7:6]
                c.处理器的工作状态切换到ARM状态[5]

        3)将程序的返回地址保存到对应异常模式的LR寄存器中

        4)修改PC的值到异常源所在异常向量表中位置

练习:使用汇编实现1-100的累加

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

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

相关文章

生成式AI如何赋能教育?商汤发布《2024生成式AI赋能教育未来》白皮书

生成式AI正在各个行业中展现出巨大的应用前景。在关系国计民生的教育行业&#xff0c;生成式AI能够催生哪些创新模式&#xff1f; 6月28日&#xff0c;商汤科技受邀参加2024中国AIGC应用与发展峰会&#xff0c;并在会上发布《2024生成式AI赋能教育未来》白皮书&#xff0c;提出…

Django之阿里云短信

短信验证 短信验证,首先得选择一个短信发送服务器上,本文档使用阿里云实现短信发送功能 阿里云短信网 网址:短信服务_企业短信营销推广_验证码通知-阿里云 注册账号 新账号赠送100条,可以不用充值,即可进行测试 接入 短信 进行 个人实名认证 编写代码执行 安装依赖模块 p…

html5 video去除边框

video的属性&#xff1a; autoplay 视频在就绪后自动播放。 controls 显示控件&#xff0c;比如播放按钮。 height 设置视频播放器的高度。 width 设置视频播放器的宽度。 loop 循环播放 muted 视频的音频输出静音。 poster 视频加载时显示的图像&#xff0c;或者在用户点击播…

全球最大智能立体书库|北京:3万货位,715万册,自动出库、分拣、搬运

导语 大家好&#xff0c;我是社长&#xff0c;老K。专注分享智能制造和智能仓储物流等内容。 新书《智能物流系统构成与技术实践》 北京城市图书馆的立体书库采用了先进的WMS&#xff08;仓库管理系统&#xff09;和WCS&#xff08;仓库控制系统&#xff09;&#xff0c;与图书…

【机器学习】机器学习的重要技术——生成对抗网络:理论、算法与实践

引言 生成对抗网络&#xff08;Generative Adversarial Networks, GANs&#xff09;由Ian Goodfellow等人在2014年提出&#xff0c;通过生成器和判别器两个神经网络的对抗训练&#xff0c;成功实现了高质量数据的生成。GANs在图像生成、数据增强、风格迁移等领域取得了显著成果…

老师期末工作怎么减负?

期末&#xff0c;一个学期的尾声&#xff0c;也是老师们最为忙碌的时刻。在这段时间里&#xff0c;我们不仅要完成教学任务&#xff0c;还要准备期末考试、批改试卷、撰写学生评语、制定假期计划等一系列繁重的工作。那么&#xff0c;如何在这样紧张的期末工作中为自己减负呢&a…

Android高级面试_2_IPC相关

Android 高级面试-3&#xff1a;语言相关 1、Java 相关 1.1 缓存相关 问题&#xff1a;LruCache 的原理&#xff1f; 问题&#xff1a;DiskLruCache 的原理&#xff1f; LruCache 用来实现基于内存的缓存&#xff0c;LRU 就是最近最少使用的意思&#xff0c;LruCache 基于L…

RocketMQ源码学习笔记:Producer启动流程

这是本人学习的总结&#xff0c;主要学习资料如下 马士兵教育rocketMq官方文档 目录 1、Overview1.1、创建MQClientInstance1.1.1、检查1.1.1、MQClientInstance的ID 1.2、MQClientInstance.start() 1、Overview 这是发送信息的代码样例&#xff0c; DefaultMQProducer produ…

百强韧劲,进击新局 2023年度中国医药工业百强系列榜单发布

2024年&#xff0c;经济工作坚持稳中求进、以进促稳、先立后破等工作要求。医药健康行业以不懈进取的“韧劲”&#xff0c;立身破局&#xff0c;迎变启新。通过创新和迭代应对不确定性&#xff0c;进化韧性力量&#xff0c;坚持高质量发展&#xff0c;把握新时代经济和社会给予…

Python之三大基本库——Numpy(2)

接着上次的内容接着讲&#xff0c;连续号都续上哈 七、numpu中random的随机生成函数 以下总结的是比较常用到的函数&#xff1a; 下面分别介绍一下不用的用法&#xff1a; 首先导入创建函数 import numpy as np np.random.seed(666)1、 rand(d0,d1,d2,...,dn)&#xff1a;返…

Keysight是德 N9912A 手持式射频分析仪

Keysight是德 N9912A 手持式频谱分析仪 N9912A FieldFox 手持射频分析仪&#xff0c;4 GHz 和 6 GHz 轻盈耐用的电缆与天线分析仪、频谱分析仪、网络分析仪等等。 Keysight FieldFox 便携式分析仪可以在非常恶劣的工作环境中&#xff0c;轻松完成从日常维护到深入故障诊断的…

【Python】 模型训练数据归一化的原理

那年夏天我和你躲在 这一大片宁静的海 直到后来我们都还在 对这个世界充满期待 今年冬天你已经不在 我的心空出了一块 很高兴遇见你 让我终究明白 回忆比真实精彩 &#x1f3b5; 王心凌《那年夏天宁静的海》 在机器学习和深度学习中&#xff0c;数据归一化…

如何用DCA1000持续采集雷达数据

摘要&#xff1a;本文介绍一下如何通过mmwave studio软件&#xff0c;搭配DCA1000数据采集卡&#xff0c;对AWR1843BOOST进行不间断的数据采集。本文要求读者已经掌握了有关基础知识。 本文开放获取&#xff0c;无需关注。 到SensorConfig页面下&#xff0c;一步步操作&#xf…

吉时利 Keithley2601B-PULSE 脉冲数字源表

Keithley2601B-PULSE吉时利脉冲SMU数字源表 无需手动脉冲调整即可实现高脉冲保真度 通过 2601B-PULSE 控制回路系统&#xff0c;高达 3μH 的负载变化无需手动调整&#xff0c;从而确保在任何电流水平&#xff08;最高 10 安培&#xff09;下输出 10 μs 至 500 μs 脉冲时&a…

柯桥法语学习|学点黑话!法语中的「钱」可不止“argent”

法语中有哪些关于钱的“黑话”&#xff1f;一起来和法语君看一下吧&#xff01; bl 之所以繁杂&#xff0c;是因为这些词在诞生之初&#xff0c;不止涉及一个故事&#xff0c;而是一大堆小轶事&#xff0c;以“bl”指钱的起源如迷宫般复杂。 根据Trsor de la langue frana15857…

Android Graphics 显示系统 - BufferQueue的状态监测

“ BufferQueue作为连接生产者和消费者的桥梁&#xff0c;时刻掌握队列中每一块Buffer的状态&#xff0c;对于解决一些卡死卡顿问题很有帮助&#xff0c;辨别是否有生产者或消费者长期持有大量Buffer不放导致运行不畅的情况。” 01 — 前言 在Android系统中&#xff0c;应用U…

使用evo工具比较ORB-SLAM3的运行轨迹(从安装到解决报错)

ORB-SLAM2和ORB-SLAM3怎么跑出来&#xff0c;之前都有相关的保姆级的教程&#xff0c;下来给大家介绍一款evo工具&#xff0c;给科研加速&#xff01;&#xff01;&#xff01; 文章目录 1.下载evo2.生成轨迹3.evo别的功能使用 1.下载evo 输入命令下载 pip install -i https…

Redis的使用和原理

目录 1.初识Redis 1.1 Redis是什么&#xff1f; 1.2 Redis的特性 1.2.1 速度快 1.2.2 基于键值对的数据结构服务器 1.2.3 丰富的功能 1.2.4 简单稳定 1.2.5 持久化 1.2.6 主从复制 1.2.7 高可用和分布式 1.3 Redis的使用场景 1.3.1 缓存 1.3.2 排行榜系统 1.3.3 计数器应用 1.3…

Firefox 编译指南2024 Windows10-使用Git 管理您的Firefox(五)

1. 引言 在现代软件开发中&#xff0c;版本控制系统&#xff08;VCS&#xff09;是不可或缺的工具&#xff0c;它不仅帮助开发者有效管理代码的变化&#xff0c;还支持团队协作与项目管理。Mercurial 是一个高效且易用的分布式版本控制系统&#xff0c;其设计目标是简洁、快速…

第二十三课,再识字符串

前言&#xff0c;再识字符串 字符串是我们学习python编程第一眼见到的东西&#xff0c;一行print(“hello world”)可谓是太亲切了&#xff0c;但在此之前我们对字符串的认知也仅局限于如何用单引号、双引号、三引号去定义字符串并打印&#xff0c;今天开始我们就更深入地去理…