汇编告诉你为什么C++可以对函数重载

想搞搞自己的编程语言,暂时命名为Fun吧,希望最终的结果是这东西能用,大家觉得有趣,就可以了。虽然不一定能成功,但做到多少是多少吧。过程中学到的才是关键。

目标是要把语言最终翻译到native code。因为总不喜欢有虚拟机的语言,虽然平时用着也很爽。喜欢c的高效,但是也喜欢c#、Python之类的表达能力强的语言。貌似目前能翻译到native code的语言,表达能力是一个问题,至少没有一些高级特性的支持,编码量就一下子上去了。总是在考虑how to do,而不是what to do。

然后就想,能不能搞个试验,看能否把这几个结合起来,于是就有了上述的想法。先从linux开始吧,毕竟资料比较多,以后如果看着还有点用途,有人加入的话,才照顾windows吧。

综合衡量之后,大体方向是翻译到汇编语言(at&t语法,可以用as来编译),对接glibc的部分功能形成core。毕竟用汇编system call封api,linus、gnu那帮大牛早就做了。在这点上花时间不大值得。

只是兴趣,不喜欢的请绕路,别乱喷。

既然要用到glibc,必须在汇编层面把需要的东西都摸得一清二楚。

在本系列的文章中,我将比较深入地介绍有关汇编、c\c++、glibc之类的知识。也不能说 很系统全面,在做笔记之余,跟大家分享,希望对大家有点用途。

我将使用gnu tool chain系列的工具。

c\c++编译器为gcc,连接器为ld,汇编器为as

因为as虽然是用at&t语法,但是支持的cpu以及instruction都比较多,而且还有各种优化选项,比nasm强大点。毕竟是linux里头的国家队。哈哈。

系统为linux(本人有系统洁癖,同时是个更新控,使用archlinux,需要啥才装啥。卖个广告吧,速度的确非常快。之前贪新鲜装了Ubuntu11.10,对那个unity界面十分不爽,比gnome-shell差多了,而且漂亮是漂亮了,但是响应速度跟以前相比,降低的不是一个数量级呀。受不了,就折腾了一个星期东google,西baidu,终于装上archlinux以及配置好gnome-shell了)

当然,在windows平台上,结果也应该是一样的。有兴趣的可以使用mingw试试。

废话说多了,开始正题吧。这篇文章结构如下

1、比较c,c++对于类似的函数,翻译到汇编语言里头的区别

2、为什么这么多project,特别是库,要用C,而不用C++【这里纯属个人体会】

先看下面一段C函数  (文件名是1.c)

  1. #include <stdio.h>   
  2.   
  3. int func( int a ) {  
  4.         return a + 1;  
  5. }  
  6.   
  7. int main() {  
  8.         printf( "%d\n", func( 1 ) );  
  9.         return 0;  
  10. }  
非常简单。哈。使用下面命令把这段代码翻译到汇编,不翻译到二进制,不链接。

$ cc -S 1.c

$ ls
1.c  1.s

其中1.s的内容如下

  1.     .file   "1.c"  
  2.     .text  
  3.     .globl  func  
  4.     .type   func, @function  
  5. func:  
  6. .LFB0:  
  7.     .cfi_startproc  
  8.     pushl   %ebp  
  9.     .cfi_def_cfa_offset 8  
  10.     .cfi_offset 5, -8  
  11.     movl    %esp, %ebp  
  12.     .cfi_def_cfa_register 5  
  13.     movl    8(%ebp), %eax  
  14.     addl    $1, %eax  
  15.     popl    %ebp  
  16.     .cfi_def_cfa 4, 4  
  17.     .cfi_restore 5  
  18.     ret  
  19.     .cfi_endproc  
  20. .LFE0:  
  21.     .size   func, .-func  
  22.     .section    .rodata  
  23. .LC0:  
  24.     .string "%d\n"  
  25.     .text  
  26.     .globl  main  
  27.     .type   main, @function  
  28. main:  
  29. .LFB1:  
  30.     .cfi_startproc  
  31.     pushl   %ebp  
  32.     .cfi_def_cfa_offset 8  
  33.     .cfi_offset 5, -8  
  34.     movl    %esp, %ebp  
  35.     .cfi_def_cfa_register 5  
  36.     andl    $-16, %esp  
  37.     subl    $16, %esp  
  38.     movl    $1, (%esp)  
  39.     call    func  
  40.     movl    $.LC0, %edx  
  41.     movl    %eax, 4(%esp)  
  42.     movl    %edx, (%esp)  
  43.     call    printf  
  44.     movl    $0, %eax  
  45.     leave  
  46.     .cfi_restore 5  
  47.     .cfi_def_cfa 4, 4  
  48.     ret  
  49.     .cfi_endproc  
  50. .LFE1:  
  51.     .size   main, .-main  
  52.     .ident  "GCC: (GNU) 4.6.2"  
  53.     .section    .note.GNU-stack,"",@progbits  
而对于下面一段C++代码(p1.cpp)
  1. #include <stdio.h>   
  2.   
  3. int func( int a ) {  
  4.     return a + 1;  
  5. }  
  6.   
  7. int func( double a ) {  
  8.     return a + 1;  
  9. }  
  10.   
  11. int main() {  
  12.     printf( "%d\n", func( 1 ) );  
  13.     printf( "%f\n", func( 1.0 ) );  
  14.     return 0;  
  15. }  

相关推荐