不同的平台的汇编代码是不一样的,最早的汇编在50年代就发明了,比很多人的父母的年龄都大,老掉牙,不用学习怎么写汇编。一个公司有一个人知道怎么写汇编就够了。但要学习读汇编
为什么学习汇编?
1 性能 直接翻译为机器语言,性能最高。优秀的C语言效率只能达到汇编的80%左右。其他高级语言跟汇编一比差得更远。语言越高级性能越差。很多bootloader和BIOS用汇编写,汇编操作的是电脑,手机刚刚上电时,硬件和初始化的那些命令,它们的性能的要求比较高,效率高开机速度更快。
2 分析问题。个人认为,编程人与机器对话,我们写C,写JAVA,但是电脑并不认识这些语言,电脑只认识0和1;所以需要一个人来翻译这些语言,这个翻译官就是编译器,但是编译器不能百分之百准确的表达程序员的意思,也就是所谓的翻译有反义。例如,编译器为了性能好一点,可能会优化变量和语句,这个过程可能好心办坏事,把有用的操作优化了。因此只有看懂一些汇编语句,才能分析程序真正执行的流程。在问题难以定位的情况下,汇编可能是分析问题的最后一根稻草。
3 帮助理解硬件。有些学校的单片机课程是以汇编进行教学的,主要原因就是汇编更贴近硬件。不过我不赞成这种做法,C语言能快速做出一点东西,有利于学生在放弃之前,增加成就感,好坚持下去。但是汇编确实更贴近硬件,如何在KEIL下阅读汇编
按d进入debug模式,在view下选择disassembly window
看光标,c文件下指向了main函数的第一行。
汇编窗口也指向了对应的语句。但是,在执行C语言的第一行之前,仍然有许多操作要做,比如变量放在哪?在哪里调用了main函数等,这些操作都被集成开发环境IDE给封装起来了。我们必须知道,在执行main函数之前,有许多事情要做,只不过,初学的时候不必理会。以下是C语言源码,功能是点亮LED.
//main.c
#include <stm32f10x.h>
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拷贝
资料参考,可以搜索
http://blog.youkuaiyun.com/tanyouliang/article/details/6767011
http://blog.youkuaiyun.com/a1875566250/article/details/8507168
从内存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语句被翻译成了意料之中的汇编语句。或者说,经过分析这些汇编语句,我们发现,自己的意图被机器准确的理解了。再然后就是汇编变成机器码,这个过程本篇不讨论
汇编语言的重要性与实践
本文探讨了汇编语言在现代编程中的作用,包括提升性能、辅助问题诊断及加深对硬件的理解等方面。通过实例演示了如何在KEIL环境中阅读和理解C语言编译后的汇编代码,展示了汇编在实际应用中的价值。
3127





