c语言程序从编译到运行

以c语言为例,编译器为gcc,讲解程序从编译到运行的过程产物
摘要由CSDN通过智能技术生成

以c语言为例,编译器为gcc,讲解程序从编译到运行的过程的产物

// hello.h
/*这个是注释*/
#ifndef __HELLO_H
#define __HELLO_H
#define WELCOME "welcome"
extern char name[];
int hello(void);
#endif

// hello.c
#include "hello.h"
#include <stdio.h>

char name[] = "world";
int hello(void) {
    printf("hello %s, %s\n ", name, WELCOME);
    return 0;
}

// main.c
#include "hello.h"

int main(void) {
    hello();
    return 0;
}


// 下面是编译运行
// gcc main.c hello.c
// ./a.out

在链接前,每个源文件都是单独进行处理

一、预处理

//只执行预处理
gcc -E hello.c > hello.i

预处理器是一个小软件(gcc包含)。按例子做如下处理:

1、将例子中的注释行删除,替换成一个空行

2、#ifndef,#endif按条件判断来决定是否使用这段代码,这样避免多文件包含同一个头时重复定义,定义宏__HELLO_H为1,将#ifndef与#endif本来替换成空行

3、#define定义宏WELCOME,将代码中的WELCOME替换成welcome,这行替换成空行

4、#include将对应的头文件内容复制到包含文件中。它有两种形式,#include <> 用于C语言自身库的头文件定义,会搜索系统头文件所在的目录(/usr/include或指定的-I); #include " " 用于所有其它头文件,先搜索当前目录,再搜索系统头文件所在目录,编译时指定的-I目录。所以用户自定义的头文件最好不要用<>,除非编译时添加-I,并把头文件放置在-I路径下;自身库虽然可以用""形式,但搜索时间增加,最好使用<>。用空行替换include所在行

5、有些预处理器指令有编译提示作用,在预处理阶段并不处理,如#pragma。

可以看出预编译器会将删除后的指令替换成一个空行

二、编译

// 大写S
gcc -S hello.c

编译过程分成:词法分析、语法分析、语义分析、中间代码生成、汇编代码生成

这部分略过,只要大致知道编译器根据语言开发者定义的语法表,语法分析器分析一边分析语法以一边去词法分析器里取词,生成语法树,在分析语法的过程中如果发现语法错误报syntax error;语义分析阶段会检查函数实参与形参类型是否匹配,变量是否声明等。

来看看生成的最终汇编代码hello.s,".file"这样前面带.是伪指令

  1         .file   "hello.c"
  2         .text //代码段
  3         .globl  name //全局变量
  4         .data //数据段
  5         .type   name, @object //name为对象类型
  6         .size   name, 6 //加上\0的长度
  7 name: //name的实现
  8         .string "world" //name的值
  9         .section        .rodata //属于只读数据块
 10 .LC0: //局部变量标号,用于表示字符串的地址
 11         .string "welcome"  //LC0值
 12 .LC1: //局部变量标号,用于表示字符串的地址
 13         .string "hello %s, %s\n " //LC1值
 14         .text //代码段
 15         .globl  hello //全局变量
 16         .type   hello, @function // hello是一个函数hello()
 17 hello: //下面是hello具体实现
 18 .LFB0: //FUNC_BEGIN_LABEL开始标记
 19         .cfi_startproc
 20         endbr64
 21         pushq   %rbp
 22         .cfi_def_cfa_offset 16
 23         .cfi_offset 6, -16
 24         movq    %rsp, %rbp
 25         .cfi_def_cfa_register 6
 26         leaq    .LC0(%rip), %rdx
 27         leaq    name(%rip), %rsi
 28         leaq    .LC1(%rip), %rdi
 29         movl    $0
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值