打印

从哪里来,到哪里去——全面阐述汇编与C的关系

[复制链接]
15188|79
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zlg315|  楼主 | 2011-2-16 06:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 zlg315 于 2011-2-16 07:46 编辑

全面阐述汇编与C的关系(1)

      有网友问我,周工——你懂几种汇编?八十年代初期,我熟练掌握了X86的汇编,后来由于长时间不用,当然也就生疏了。如果遇到对C语言理解不透的问题,我则更多地结合80C51的反汇编来分析,所以最精通的还是80C51的汇编。有了这样的基础,从理论上来讲,拿到任何一种微处理器的手册,我都能够使用汇编完成所需要的工作。

     如果你希望成为高手或专家,仅仅熟练“使用”(即不等于彻底掌握和精通)C是远远不够的。只有两方面结合起来,才能做到知其然知其所以然,结论不言自明。很多人都说自己“精通”这个“精通”那个,“精通”二字不是张口就可以说出来的。

     其实,不要小瞧80C51单片机而高看32位ARM,如果你真的“精通”了80C51单片机,那是一件不得了的事情,无论学什么都是小儿科。很多人以为自己会编程,做了几个项目就自以为自己“精通”了,而事实上大多数开发人员仅仅是一个熟练工而已,离精通还相差十万八千里,就开始夜郎自大了。

    挑战:无论是基于前后台还是操作系统的软件设计,都可以无障碍地被所有的项目复用,从而跨越前后台与基于操作系统编程的鸿沟。我们中间有几个人能够做到将前后台的代码一字不改用于操作系统应用程序之中呢?

     其实从事嵌入式软件开发的几乎都是聪明的高素质人才,但是,我们成功了吗?有多少人真正完成了我们新年时定下的设计计划呢?虽然软件的价值是无穷的,看起来任何人都会写代码,但我从创办企业以来,深深地体会到在现实的生活中,只有真正的专家,才可能通过各种各样的方法设计出高质量、不超过预算、能按时提交的软件。我们看了很多书,我们写了很多代码,但实际上有多少人从中得到了帮助呢?如何改变我们的工作,最重要的方法是改变我们的做事方式。

      以下是我的读书笔记,也可以算是我对“精通”的一点理解吧!一旦你掌握了开启智慧大门的钥匙,一切的问题都不是问题,什么ARM,Linux、WinCE都不在话下,因为万变不离其宗。

     关于函数调用
      我们知道,函数调用是C语言最基本的操作之一。C语言的函数可以没有参数,也可以有一个或多个参数。 最简单的C语言函数调用就是无参数函数调用,其应用示例详见程序清单1.1,经过SDCC51编译后,其相应的汇编代码详见程序清单1.2  

程序清单1.1 无参数函数调用的C语言代码(call1.c)
1   extern void func2(void);
2  
3   void func1 (void)
4  {
5        while (1) {
6              func2();
7        }
8  }

程序清单1.2  无参数函数调用的汇编代码(call1.asm)
99    _func1:
110  00102$:
113  LCALL  _func2
116  SJMP    00102$
   

    由此可见,无参数函数调用(参考程序清单1.1(6))对应的汇编代码非常简单,仅有一条LCALL指令(程序清单1.2(113))。
    当然,还有单字节、双字节、三字节与四字节函数以及两个参数与三个参数的函数调用的情况,在此也就不再一一列出来了。

    关于函数返回
    C语言的函数可以没有返回值,也可以有一个返回值。限于80C51体系结构,SDCC51的汇编语言对有符号变量和无符号变量不加区分。因此变量类型仅限于变量的尺寸,函数返回只有无返回值,返回单字节变量、返回双字节变量、返回三字节变量和返回四字节变量5种情况。   
       1.无返回值   

    无返回值的函数参考代码详见程序清单1.3,与之对应的汇编语言详见程序清单1.4

程序清单1.3  无返回值C语言代码(ret1.c)
1    void func2 (void)
2   {
3   }

程序清单1.4  无返回值汇编语言代码(ret1.asm)
99    _func2:
112  RET
   

   通过程序清单1.3程序清单1.4可以看出,无返回值的函数返回代码非常简单,仅一条RET指令而已(程序清单1.4(112))。
       2.单字节返回值   

    单字节返回值的函数参考代码见程序清单1.5,其对应的汇编语言见程序清单1.6.

程序清单1.5  单字节返回值C语言代码(ret2.c)
1   unsigned char func2 (void)
2  {
3       return 1;
4   }


程序清单1.6  单字节返回值汇编语言代码(ret2.asm)
99    _func2:
110  MOV   DPL, #0x01
113  RET
   
    通过程序清单1.5程序清单1.6可以看出,函数的返回值是保存在特殊寄存器DPL程序清单1.6(110))中的,函数通过RET指令返回(程序清单1.6 (113))。
    ......
    函数的返回值通过特殊寄存器传递,根据参数大小依次使用特殊寄存器DPLDPTRDPTR+BDPTR+B+A

    当然,还有很多,在此也就不一一“作秀”了,因为这毕竟是“小儿科”,希望起到抛砖引玉的作用。

    昨夜因为辛苦,吃了晚饭八点钟就上床睡觉了,因此今天起得早,闲来无事加之很久不上网了,于是写下几句话寄语新一代富有上进心的年轻人。
评分
参与人数 6威望 +15 收起 理由
tuzihog + 1 很好的论述!受教了!谢谢周工! ...
NE5532 + 10
qisewai + 1
123jj + 1
HWM + 1 比较实在

查看全部评分

相关帖子

沙发
心静自然凉| | 2011-2-16 08:16 | 只看该作者
本帖最后由 心静自然凉 于 2011-2-16 08:23 编辑

周工你好
我觉得,您以上所论述的也是关于一个知识结构的问题,所有的物质现象都可以追究到原子甚至更微小的物质现象。
汇编和C有联系,并不等于就需要你两种语言都会才能做好相关研发工作。
目前来说,个人觉得汇编和C都还不是完美的计算机语言(将来肯定会出现更厉害的计算机语言),
你可以只会汇编,也可以只会C,可以缺胳膊少腿,但需要达到一个目的:做出在本行业具有竞争力的产品,而这不是只讨论汇编和C就能做到的。

当然,我并不是要否定周工您的观点,知识是无穷尽的,而我相信,真正具有强烈求知欲和兴趣的人们,会随着某一条路一直走下去。

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
maxhai + 1
板凳
zlg315|  楼主 | 2011-2-16 08:45 | 只看该作者
本帖最后由 zlg315 于 2011-2-16 08:47 编辑

现在不是讨论如何做出有竞争力的产品,而是针对初学者来说,如何打好基础的问题?因此讨论问题不要跑题。

C语言那么好用,我还需要使用汇编吗?如果你不知道汇编能给我们带来什么帮助,纵然再简单的语言也没有兴趣学下去,关键要善用它们之间的联系来思考问题、发现问题和解决问题。

为什么现在越来越多的企业注重“三好学生(数学好、编程好、团队精神好)”式的人才呢?其中,一条就是编程好而不是仅仅会编程。有了一定的基础,其它的问题将迎刃而解。

使用特权

评论回复
地板
思考| | 2011-2-16 08:47 | 只看该作者
周工,你好! 顶!

使用特权

评论回复
5
sheriff| | 2011-2-16 08:49 | 只看该作者
顶周工,受教了

使用特权

评论回复
6
yewuyi| | 2011-2-16 09:05 | 只看该作者
呵呵,俺最多只能算熟练使用,所以从来不敢说自己精通什么。

使用特权

评论回复
7
nan_banqiu| | 2011-2-16 10:17 | 只看该作者
谢谢 周工

使用特权

评论回复
8
highgear| | 2011-2-16 10:26 | 只看该作者
顶。

作为嵌入式开发人员, 只精通汇编,而不会 c, 是不可思议的; 同样, 只懂 c, 而不精通汇编也不能称为真正的高手。数字逻辑, 模拟电路,cpu 结构, 汇编以及 c, 或许还要加上 c++, 这些都是嵌入式开发人员必备的基本技能,不可或缺。

使用特权

评论回复
评分
参与人数 1威望 +10 收起 理由
hotpower + 10 !!!
9
zlg315|  楼主 | 2011-2-16 10:58 | 只看该作者
本帖最后由 zlg315 于 2011-2-16 11:01 编辑

除了不可思议的原因,比如,年龄大退休了或做领导后无暇顾及开发,精通汇编的没有不精通C的,而会用C的不一定会用汇编。

出道之前,整个社会当时的技术都比较原始,我自认为还算当时佼佼者;创业之后,既要做生意又要搞技术,很难做到两者兼顾,于是,我暂时放弃了技术;等公司有了一定的规模之后,我又回过头来专心搞技术。因为基础在那里,新的东西很快就上手了。一直到现在,我每天10小时以上的时间在做技术,虽然四十有七,但丝毫不觉得比年轻人迟钝。

使用特权

评论回复
10
highgear| | 2011-2-16 11:08 | 只看该作者
没错,汇编是嵌入式开发中基础的基础,你可以不用汇编,但不能不精通汇编。

使用特权

评论回复
11
china_fog| | 2011-2-16 11:20 | 只看该作者
47了还在钻研,学习的对象。

使用特权

评论回复
12
gaowb2010| | 2011-2-16 11:30 | 只看该作者
10楼的,我顶你!

使用特权

评论回复
13
OpCode| | 2011-2-16 11:41 | 只看该作者
能用C#解决的绝不用C++,
能用C++解决的绝不用C,
能用C解决的绝不用汇编,
最后没办法了直接上汇编。
项目允许的情况下,优先选择高级语言来开发,开发速度要快一个数量级!
(前提是从低级语言到高级语言你都要会用,哈哈。)

使用特权

评论回复
14
dinosaur45| | 2011-2-16 11:56 | 只看该作者
顶!!

使用特权

评论回复
15
highgear| | 2011-2-16 12:26 | 只看该作者
哈哈, 15楼正是我想说的,也是这么做的。不过从学习的角度看,就要倒过来:
汇编精通了,c就很容易掌握;
c精通了,c++,呃,还是会掌握的快一些;
c++精通了, c#就不在话下。

使用特权

评论回复
16
sysdriver| | 2011-2-16 13:18 | 只看该作者
我喜欢这句话:
无论是基于前后台还是操作系统的软件设计,都可以无障碍地被所有的项目复用,从而跨越前后台与基于操作系统编程的鸿沟。

我经常试图写出一些通用的东西。哪怕是简单的汇编,都想着去把最基本的底层的应用写出来。
然后再搭些基本的框架,这样。同一个系列的工程,我基本上只是改动一些端口设置就能用了。
所以,同系列的工程我只是需要考虑“工程的框架”,开发的时间缩短很多。
不知周工是否理解我的话,对这个思想有什么看法。

使用特权

评论回复
17
zlg315|  楼主 | 2011-2-16 14:59 | 只看该作者
本帖最后由 zlg315 于 2011-2-16 15:17 编辑

架构的前提软件要进行准确地分层设计,层与层之间的接口规范制定以及如何降低它们耦合度,这些才是关键。

原则上,简单的嵌入式软件可以分为设备驱动程序、虚拟驱动程序与应用程序,设备驱动程序只负责与硬件有关的部分,而与硬件无关的部分将放到虚拟驱动程序之中。比如,数码管扫描程序(省略了其它文件,如驱动配置文件)
    设备驱动程序:
    extern void LedDisplayScant(void);        // 输入参数与返回值:无
    虚拟驱动程序:     
     extern char Virshowputs(char *pcStr); // 输入参数:pcStr——要输出的字符串,返回值:0——成功,-1——失败
    在前后台中仅需将上述函数名改为“extern LedDisplyputs(char *pcStr); ”,代码完全一样。
     清屏程序也很简单,比如:
     char LedDisplayClr(void)
     {
          memset(GucLedDisplayshowBuf, 0, 6);      // 将显示缓冲区清0
     }   // 函数原型:void *memset(void *s, int ch, unsigned n);

     当然,不要在这些代码中使用定时器中断等,如果需要使用定时器中断,那么,只需要另外再加2个函数即可。比如:
     extern void time0ISR(void) _interrupt1;
     extern void time0Init(void);
     最后再写一个测试用例,比如:
    void main(void)
      {
            LedDisplayInit();                        // 显示器初始化
            time0Init();                                // 定时器初始化
            EA = 1;                                     //  允许中断
      
            LedDisplayPuts("60.7-5.9");         // 显示字符串

            while(){
            }
      }
   

     当然,在某些情况下,前后台的程序移植到OS中,还需要作稍许的修改,这也是无法避免的,但工作很少。

     由于学习任务繁重以及工作太忙,因此,没有太多的时间及时参与大家的讨论,敬请谅解!谢谢。

使用特权

评论回复
18
123jj| | 2011-2-16 15:03 | 只看该作者
周工分析的精辟!顶!!

使用特权

评论回复
19
http2008| | 2011-2-16 16:34 | 只看该作者
拜读了,谢谢

使用特权

评论回复
20
icecut| | 2011-2-16 18:35 | 只看该作者
计算机组成与设计(附光盘硬件\软件接口原书第3版)/计算机科学丛书

看完这个,......

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

5287

主题

5977

帖子

9

粉丝