嵌入式软件开发为何要学点汇编?(以MCU为例)

1、前言

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

一个嵌入式技术进阶公众号,定期分享C语言,C++、MCU(如stm32等)、DSP、ARM、嵌入式Linux等“独门”软件设计技巧和知识归纳总结,同时分享应用程序设计、物联网、滤波及控制算法推导和仿真设计等嵌入式硬核知识技巧!欢迎大家关注!
156篇原创内容
公众号

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 。
看光标,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)
汇编窗口往上翻,确实很多语句,先看这几行代码的汇编:
先说最常用的两句汇编:
LDR r0,[r1] r0 = *r1
STR r0,[r1] *r1 = r0
MOV r0,r1    r1->r0拷贝 
从内存0x0800 017c的32位数据拷贝到r0:
r0 = * 0x0800 017c
我们看到的 1000 4002其实 就是0x4002 1000。这里边有个知识点叫做大小端模式,以下简单讲解,不能理解就记住。
这个数据是在地址是这么存放的:
  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的操作。再分析下一句 :
前两句给r0分配空间,r0 = *0x4001 0c00
然后用BIC清除数据位,把4-7位清零,结果再赋值给r0。
*0x4001 0c00 &= ~(0xf0) r1 = *0x4001 0c00 *0x4001 0c00 &= ~(0xf0)
剩下的不再详细分析,直接给答案 :
***0x4001 0c00 |= 0x20 0x4001 0c0c &= ~(0x02)*

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

bug菌 : 当我们遇到缩写的C代码功能与运行效果不一致的时候,可以通过查找对应的汇编代码进行机器层面的分析,最终找到问题!

(0)

相关推荐

  • arm汇编

    (汇编)指令是CPU机器指令的助记符,经过编译后会得到一串10组成的机器码,可以由CPU读取执行. (汇编)伪指令本质上不是指令(只是和指令一起写在代码中),它是编译器环境提供的,目的是用来指导编译过 ...

  • 5. 从0学ARM

    一.程序状态寄存器访问指令 ARM微处理器支持程序状态寄存器访问指令,用于在程序状态寄存器和通用寄存器之间传送数据. MRS MRS{条件} 通用寄存器,程序状态寄存器(CPSR或SPSR) MRS指 ...

  • STM8S103中文数据手册解读.1

    你能从本文学到什么? 你可以和我一起读STN8S103的中文数据手册,可以和我"初步"了解里面的各种名词,还可以收集到各种相关的资料. 从官网上了解到,STM8 系列有三个大类:S ...

  • 符合 ISO 26262 标准的MBD嵌入式软件开发技术培训课程简介

    符合 ISO 26262 标准的MBD嵌入式软件开发技术 - 挑战和有效解决方案 MES学院简介 MES学院隶属MES公司,多年来为世界各地的软件工程师们提供专业的培训服务,其中包括功能安全.ISO ...

  • 做了7年开源数据库开发,我学到了什么?

    做了7年开源数据库开发,我学到了什么?

  • 文创产品开发:全世界都在学这家博物馆!

    没有了门票收入,取而代之的是博物馆自身经营,衍生品的收入,而这项收入逐步成为了如今大英博物馆的主要收入来源. 当我们走进博物馆内,这些纪念品商店一般都会设在进入博物馆大门的显眼位置. 在大英博物馆的大 ...

  • 浅谈嵌入式软件开发之影响嵌入式MCU中断延迟(Interrupt Latency)的因素总结

    内容提要 引言(何为中断延迟) 1. 存储中断向量表和中断ISR代码的存储器访问速度 2. CPU内核Cache命中(hit)与否 3. 中断ISR代码的复杂程度(是否需要压栈) 4. 中断ISR代码 ...

  • 脊髓栓系综合征影像学表现,看这 5 例就够了

    脊髓栓系综合征 (tethered cord syndrome, TCS) 为脊髓.脊椎等结构的先天性发育异常,为脊髓圆锥位置下移并被栓系在椎管内,并伴发其他畸形,从而产生一系列神经功能障碍的综合症. ...

  • 必转收藏 | 必学的历代名篇名句400例,建议打印早读背诵!

    先秦名篇名句 <诗经> 1. 关关雎鸠,在河之洲:窈窕淑女,君子好逑. 2. 昔我往矣,杨柳依依:今我来思,雨雪霏霏. 3. 投我以木桃,报之以琼瑶. 4. 他山之石,可以攻玉. 5. 如 ...

  • 青山学凉菜:再送几例经典凉菜做法

    凉拌黑木耳 食材 木耳(水发)20克.蒜瓣3瓣.火麻油适量.白糖少许.陈醋1勺.生抽7ml.鸡精粉少许.剁椒酱2勺.食盐适量 步骤 1.将黑木耳用冷水泡发,变软后冼净 2.锅中倒入清水,煮开,放入木耳 ...

  • 丹霞景观旅游资源如何开发与保护——以穿岩十九峰景区旅游总体规划为例

    丹霞一词最早出自曹丕的<芙蓉池作诗>--" 丹霞夹明月,华星出云间."丹霞地貌的旅游价值,很早就被人们认识并利用.丹霞地貌最初并未与旅游资源开发联系起来,近十几年来,丹 ...

  • 颊针疗法丨“针灸小白”学颊针治失眠2例

    颊针班开课了 18年8月道生13.14期颊针精品班(上海) 点击下方"阅读原文"报名参加 大家好,我是广东省中医院欧阳博文医生,今晚我总结了颊针医案库几位老师治疗失眠的医案,结合自 ...