LCC编译器的源程序分析(1)C编译器的目标

本文通过一个简单的C语言程序示例,详细介绍了C编译器如何将其转换为NASM汇编代码的过程。该过程揭示了编译器如何处理源代码、生成中间代码并最终输出可执行文件。
先从简单的目标来分析这个大规模的C编译器,毕竟它的功能比较复杂,并且源程序的行数也是非常多的。因此,把简单的目标定出来,然后再分析它,这样才会有的放矢。接着再跟着编译运行的主线来分析它的源程序。下面先看一下简单的C例子,如下:
#001#include <stdio.h>
#002
#003int main(void)
#004{
#005int nTest1 = 1;
#006int nTest2 = 2;
#007int nTest3;
#008int i;
#009
#010nTest3 = nTest1 + nTest2;
#011printf("nTest3 = %d/r/n",nTest3);
#012
#013for (i = 0; i < 5; i++)
#014{
#015 printf("%d/r/n",nTest3+i);
#016}
#017
#018printf(__TIME__" "__DATE__"/r/nhello world/n");
#019return 0;
#020}
#021
上面的程序就是用来说明编译器工作的例子,它在第一行里包含了头文件stdio.h,由于后面调用printf函数输出显示到屏幕里。第二行空行,第三行是main函数,它是C程序的入口函数。在main函数里,定义了几个局部变量,分别第5678行的变量。第10行作两个变量nTest1nTest2的加法,然后赋值给变量nTest3。第11行显示变量nTest3的值,是用10进制输出显示。在第1316行是5次输出nTest3+i值。在第18行里输出编译这个程序的时间和hello world的字符串。
C编译器的任务,就是把上面的源程序变换到汇编代码输出,或者变成其它中间代码输出。在这里LCC编译器是输出汇编代码的,所以就不介绍其它的中间代码输出。那么LCC把上面的源程序变成什么样的汇编输出呢?下面就先把它的目标代码看一下,如下:
#001[global $main]
#002[section .text]
#003$main:
#004push ebx
#005push esi
#006push edi
#007push ebp
#008mov ebp, esp
#009sub esp, 16
#010mov dword [ebp + -12], 1
#011mov dword [ebp + -16], 2
#012mov edi, dword [ebp + -12]
#013mov esi, dword [ebp + -16]
#014lea edi, [esi + edi]
#015mov dword [ebp + -8], edi
#016mov edi, dword [ebp + -8]
#017push dword edi
#018lea edi, [$L2]
#019push dword edi
#020call $printf
#021add esp, 8
#022mov dword [ebp + -4], 0
#023$L3:
#024mov edi, dword [ebp + -8]
#025mov esi, dword [ebp + -4]
#026lea edi, [esi + edi]
#027push dword edi
#028lea edi, [$L7]
#029push dword edi
#030call $printf
#031add esp, 8
#032$L4:
#033inc dword [ebp + -4]
#034cmp dword [ebp + -4], 5
#035jl near $L3
#036lea edi, [$L8]
#037push dword edi
#038call $printf
#039add esp, 4
#040mov eax, 0
#041$L1:
#042mov esp, ebp
#043pop ebp
#044pop edi
#045pop esi
#046pop ebx
#047ret
#048[extern $printf]
#049[section .data]
#050times ($-$$) & 0 nop
#051$L8:
#052db '00:30:28 Apr 07 2007', 13, 10, 'hello world', 10, 0
#053times ($-$$) & 0 nop
#054$L7:
#055db '%d', 13, 10, 0
#056times ($-$$) & 0 nop
#057$L2:
#058db 'nTest3 = %d', 13, 10, 0
#059
LCC是可以生成很多目标代码的C编译器,在这里主要介绍生成X86NASM汇编的代码。上面的汇编代码就是NASM的汇编格式,可以使用NASM编译生成目标文件,然后再用连接程序生成可执行文件。如果不能看懂上面的NASM汇编,就需要去看NASM手册了,这个手册在网上有下载。如果想更深入理解汇编生成机器码的过程,当然也可以深入分析NASM的程序实现。
从上面的C和汇编也可以看出,汇编代码比C代码要复杂,行数也比较多,还分了数据段和代码段。所以使用C编译器是可以大大地提高生产效率的,并且更容易理解,这样就容易降低软件的成本,容易开发大规模的软件工程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值