0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

为什么学习STM32时还要学习汇编

电子设计 来源:电子设计 作者:电子设计 2022-02-16 13:43 次阅读

不同的平台的汇编代码是不一样的,最早的汇编在50年代就发明了,比很多人的父母的年龄都大,老掉牙,不用学习怎么写汇编。一个公司有一个人知道怎么写汇编就够了。但要学习读汇编,为什么学习汇编?

1、性能

直接翻译为机器语言,性能最高。优秀的C语言效率只能达到汇编的80%左右。其他高级语言跟汇编一比差得更远。语言越高级性能越差。很多bootloader和BIOS用汇编写,汇编操作的是电脑手机刚刚上电时,硬件和初始化的那些命令,它们的性能的要求比较高,效率高开机速度更快。

分析问题

个人认为,编程人与机器对话,我们写C,写JAVA,但是电脑并不认识这些语言,电脑只认识0和1;所以需要一个人来翻译这些语言,这个翻译官就是编译器,但是编译器不能百分之百准确的表达程序员的意思,也就是所谓的翻译有反义。例如,编译器为了性能好一点,可能会优化变量和语句,这个过程可能好心办坏事,把有用的操作优化了。因此只有看懂一些汇编语句,才能分析程序真正执行的流程。在问题难以定位的情况下,汇编可能是分析问题的最后一根稻草。
帮助理解硬件

有些学校的单片机课程是以汇编进行教学的,主要原因就是汇编更贴近硬件。不过我不赞成这种做法,C语言能快速做出一点东西,有利于学生在放弃之前,增加成就感,好坚持下去。但是汇编确实更贴近硬件。

LDR指令

为了便于理解下文,先介绍下LDR指令,其格式如下:

LDR{条件} 目的寄存器 <存储器地址>

作用:将 存储器地址 所指地址处连续的4个字节(1个字)的数据传送到目的寄存器中。LDR指令的寻址方式比较灵活,实例如下:

LDR R0,[R1] ;将存储器地址为R1的字数据读入寄存器R0。
LDR R0,[R1,R2] ;将存储器地址为R1+R2的字数据读入寄存器R0。
LDR R0,[R1,#8] ;将存储器地址为R1+8的字数据读入寄存器R0。
LDR R0,[R1],R2 ;将存储器地址为R1的字数据读入寄存器R0,并将R1+R2的值存入R1。
LDR R0,[R1],#8 ;将存储器地址为R1的字数据读入寄存器R0,并将R1+8的值存入R1。
LDR R0,[R1,R2]! ;将存储器地址为R1+R2的字数据读入寄存器R0,并将R1+R2的值存入R1。
LDR R0,[R1,LSL #3] ;将存储器地址为R1*8的字数据读入寄存器R0。
LDR R0,[R1,R2,LSL #2] ;将存储器地址为R1+R2*4的字数据读入寄存器R0。
LDR R0,[R1,,R2,LSL #2]!;将存储器地址为R1+R2*4的字数据读入寄存器R0,并将R1+R2*4的值存入R1。
LDR R0,[R1],R2,LSL #2 ;将存储器地址为R1的字数据读入寄存器R0,并将R1+R2*4的值存入R1。
LDR R0,Label ;Label为程序标号,Label必须是当前指令的-4~4KB范围内。

要注意的是:

LDR Rd,[Rn],#0x04 ;这里Rd不允许是R15。

另外LDRB 的指令格式与LDR相似,只不过它是将存储器地址中的8位(1个字节)读到目的寄存器中。LDRH的指令格式也与LDR相似,它是将内存中的16位(半字)读到目的寄存器中。

LDR R0,=0xff

这里的LDR不是arm指令,而是伪指令。这个时候与MOVE很相似,只不过MOV指令后的立即数是有限制的。这个立即数必须是0X00-OXFF范围内的数经过偶数次右移得到的数,所以MOV用起来比较麻烦,因为有些数不那么容易看出来是否合法。

2、如何在KEIL下阅读汇编

按d进入debug模式,在view下选择disassembly window 。

100059172-113890-1.png

看光标,c文件下指向了main函数的第一行。

汇编窗口也指向了对应的语句。但是,在执行C语言的第一行之前,仍然有许多操作要做,比如变量放在哪?在哪里调用了main函数等,这些操作都被集成开发环境IDE给封装起来了。我们必须知道,在执行main函数之前,有许多事情要做,只不过,初学的时候不必理会。以下是C语言源码,功能是点亮LED

//main.c #include int main(void) { RCC->APB2ENR |= RCC_APB2ENR_IOPBEN; GPIOB->CRL &= ~(0xf<<(1*4)); GPIOB->CRL |= 0x2<<(1*4); GPIOB->ODR &= ~(1<<1); return 0; } //main.h #define RCC_APB2ENR (*(unsigned int *)0x40021018) #define GPIOB_CRL (*(unsigned int *)0x40010c00) #define GPIOB_ODR (*(unsigned int *)0x40010c0c)

汇编窗口往上翻,确实很多语句,先看这几行代码的汇编:

100059172-113891-2.jpg

先说最常用的两句汇编:

LDR r0,[r1] r0 = *r1

STR r0,[r1] *r1 = r0

MOV r0,r1 r1->r0拷贝

100059172-113892-3.png

从内存0x0800 017c的32位数据拷贝到r0:

r0 = * 0x0800 017c

我们看到的 1000 4002其实 就是0x4002 1000。这里边有个知识点叫做大小端模式,以下简单讲解,不能理解就记住。

100059172-113893-4.jpg

这个数据是在地址是这么存放的:

7C 7D 7E 7F
00 10 02 40

实际数据是0x4002 1000

* 0x0800 017c=0x4002 1000

然后r0的值+0x18也就是24 因为这个是第6号(第6号就是第7个的意思)元素

得到r0 = *0x4002 1018,r0的值由一个地址,变成了地址所存放的数据。

然后是或0x08操作,结果再复制给r0,*0x4002 1018 |=0x08

给r1分配地址,这个地址也是0x4002 1000, r1 = *0x4002 1000

把r0存放的值,(不是r0的地址,)存到r1+18的空间上

*(r1+0x18) = r0
*0x4002 1018 = (*0x4002 1018 |=0x08)
*0x4002 1018|=0x08

最终结果:地址4002 1018的数,执行了或0x08的操作。再分析下一句 :

100059172-113895-6.jpg

前两句给r0分配空间,r0 = *0x4001 0c00

然后用BIC清除数据位,把4-7位清零,结果再赋值给r0。

*0x4001 0c00 &= ~(0xf0)
r1 = *0x4001 0c00
*0x4001 0c00 &= ~(0xf0)

剩下的不再详细分析,直接给答案 :

100059172-113894-5.jpg

***0x4001 0c00 |= 0x20
0x4001 0c0c &= ~(0x02)*

最终,可以看到C语句被翻译成了意料之中的汇编语句,自己的意图被机器准确的理解了。

来源 | STM32嵌入式开发
整理文章为传播相关技术,版权归原作者所有,如有侵权,请联系删除
审核编辑:何安

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • STM32
    +关注

    关注

    2265

    文章

    10870

    浏览量

    354717
收藏 人收藏

    评论

    相关推荐

    什么是机器学习?通过机器学习方法能解决哪些问题?

    来源:Master编程树“机器学习”最初的研究动机是让计算机系统具有人的学习能力以便实现人工智能。因为没有学习能力的系统很难被认为是具有智能的。目前被广泛采用的机器学习的定义是“利用经
    的头像 发表于 11-16 01:07 194次阅读
    什么是机器<b class='flag-5'>学习</b>?通过机器<b class='flag-5'>学习</b>方法能解决哪些问题?

    GPU深度学习应用案例

    GPU在深度学习中的应用广泛且重要,以下是一些GPU深度学习应用案例: 一、图像识别 图像识别是深度学习的核心应用领域之一,GPU在加速图像识别模型训练方面发挥着关键作用。通过利用GPU的并行计算
    的头像 发表于 10-27 11:13 324次阅读

    人工智能、机器学习和深度学习存在什么区别

    人工智能指的是在某种程度上显示出类似人类智能的设备。AI有很多技术,但其中一个很大的子集是机器学习——让算法从数据中学习
    发表于 10-24 17:22 2442次阅读
    人工智能、机器<b class='flag-5'>学习</b>和深度<b class='flag-5'>学习</b>存在什么区别

    AI大模型与深度学习的关系

    AI大模型与深度学习之间存在着密不可分的关系,它们互为促进,相辅相成。以下是对两者关系的介绍: 一、深度学习是AI大模型的基础 技术支撑 :深度学习是一种机器学习的方法,通过多层神经网
    的头像 发表于 10-23 15:25 354次阅读

    嵌入式学习建议

    原理的嵌入式操作系统进行学习。不要一开始就学习几种操作系统,理解了基本原理,实践中确有实际需要再学习也不迟。人总是要不断学习的。 ⑨关于汇编
    发表于 10-22 11:41

    入门?毕设?竞赛?项目练手?STM32/嵌入式/物联网学习,有这几款开发板就够了!

    针对STM32单片机、嵌入式Linux、物联网初学者,我们精心梳理了从“入门到项目进阶”完整学习路径,并配有详细的教程、视频讲解、源代码以及丰富的实战案例资料。可广泛用于高校教学、学生毕设、个人学习
    的头像 发表于 10-10 16:31 255次阅读
    入门?毕设?竞赛?项目练手?<b class='flag-5'>STM32</b>/嵌入式/物联网<b class='flag-5'>学习</b>,有这几款开发板就够了!

    深度学习中的无监督学习方法综述

    深度学习作为机器学习领域的一个重要分支,近年来在多个领域取得了显著的成果,特别是在图像识别、语音识别、自然语言处理等领域。然而,深度学习模型的强大性能往往依赖于大量有标签的数据进行训练,这在实际
    的头像 发表于 07-09 10:50 486次阅读

    人工智能、机器学习和深度学习是什么

    在科技日新月异的今天,人工智能(Artificial Intelligence, AI)、机器学习(Machine Learning, ML)和深度学习(Deep Learning, DL)已成为
    的头像 发表于 07-03 18:22 1096次阅读

    深度学习与传统机器学习的对比

    在人工智能的浪潮中,机器学习和深度学习无疑是两大核心驱动力。它们各自以其独特的方式推动着技术的进步,为众多领域带来了革命性的变化。然而,尽管它们都属于机器学习的范畴,但深度学习和传统机
    的头像 发表于 07-01 11:40 1178次阅读

    stm32单片机学习路线

    第一步 编程及硬件基础知识 1.掌握C语言基础 作为STM32的主要编程语言,C语言的基础知识是必不可少的。建议通过书籍、在线课程或者教学视频系统地学习C语言的基础知识,包括语法、数据类型
    发表于 05-10 15:34

    深度学习与度量学习融合的综述

    如今,机器学习的应用广泛,包括人脸识别、医疗诊断等,为复杂问题和大量数据提供解决方案。机器学习算法能基于数据产生成功的分类模型,但每个数据都有其问题,需定义区别特征进行正确分类。
    发表于 04-24 09:49 387次阅读
    深度<b class='flag-5'>学习</b>与度量<b class='flag-5'>学习</b>融合的综述

    STM32高手进阶之路与实用学习步骤

    CPU是相通的,相信大部分的同学都学习过单片机,是有一定基础的。如果你碰到问题,去尝试了,自己把问题解决了,你会很有成就感!
    的头像 发表于 03-13 09:38 561次阅读

    为什么深度学习的效果更好?

    导读深度学习是机器学习的一个子集,已成为人工智能领域的一项变革性技术,在从计算机视觉、自然语言处理到自动驾驶汽车等广泛的应用中取得了显著的成功。深度学习的有效性并非偶然,而是植根于几个基本原则和进步
    的头像 发表于 03-09 08:26 592次阅读
    为什么深度<b class='flag-5'>学习</b>的效果更好?

    C语言能够实现单片机功能,为什么还要使用汇编呢?

    C语言能够实现单片机功能,为什么还要使用汇编呢? C语言是一种高级编程语言,它具有跨平台、可移植性强、易于使用的特点,使得开发人员能够快速且方便地编写复杂的程序。然而,尽管C语言在许多方面都非常强大
    的头像 发表于 01-15 14:59 958次阅读

    什么是深度学习?机器学习和深度学习的主要差异

    2016年AlphaGo 击败韩国围棋冠军李世石,在媒体报道中,曾多次提及“深度学习”这个概念。
    的头像 发表于 01-15 10:31 1016次阅读
    什么是深度<b class='flag-5'>学习</b>?机器<b class='flag-5'>学习</b>和深度<b class='flag-5'>学习</b>的主要差异