学习自狄泰软件学院唐佐临老师C语言课程,文章中图片取自老师的PPT,仅用于个人笔记。



实验1
19-1.h
/*
This is a header file.
*/
char* p = "Delphi";
int i = 0;
19-1.c
#include "19-1.h"
// Begin to define macro
#define GREETING "Hello world!"
#define INC(x) x++
// End
int main()
{
p = GREETING;
INC(i);
return 0;
}
马宝宝是个坏宝宝
mhr@ubuntu:~/work/C$
mhr@ubuntu:~/work/C$ gcc -E 19-1.c -o 19-1.i
mhr@ubuntu:~/work/C$ ll
total 20
drwxrwxr-x 2 mhr mhr 4096 Dec 31 23:18 ./
drwxrwxr-x 4 mhr mhr 4096 Dec 15 03:18 ../
-rw------- 1 mhr mhr 196 Nov 2 2014 19-1.c
-rw------- 1 mhr mhr 85 Nov 2 2014 19-1.h
-rw-rw-r-- 1 mhr mhr 279 Dec 31 23:18 19-1.i
mhr@ubuntu:~/work/C$
预处理器处理过后生成的中间文件 : 19-1.i
# 1 "19-1.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "19-1.c"
# 1 "19-1.h" 1
# 9 "19-1.h"
char* p = "Delphi";
int i = 0;
# 2 "19-1.c" 2
# 11 "19-1.c"
int main()
{
p = "Hello world!";
i++;
return 0;
}
变化:
1 所有的注释都被删掉了
2 直接将头文件中的全局变量复制过来
3 以 “ # ” 开头的:包含 #include 并且紧接着就展开被包含的文件内容
4 头文件中的宏不见了,已经被展开并且替换到对应的位置了

mhr@ubuntu:~/work/C$ gcc -S 19-1.i -o 19-1.s
mhr@ubuntu:~/work/C$ ll
total 24
drwxrwxr-x 2 mhr mhr 4096 Dec 31 23:32 ./
drwxrwxr-x 4 mhr mhr 4096 Dec 15 03:18 ../
-rw------- 1 mhr mhr 196 Nov 2 2014 19-1.c
-rw------- 1 mhr mhr 85 Nov 2 2014 19-1.h
-rw-rw-r-- 1 mhr mhr 279 Dec 31 23:18 19-1.i
-rw-rw-r-- 1 mhr mhr 677 Dec 31 23:32 19-1.s
mhr@ubuntu:~/work/C$
编译得到的汇编文件:19-1.s
.file "19-1.c"
.globl p
.section .rodata
.LC0:
.string "Delphi"
.data
.align 8
.type p, @object
.size p, 8
p:
.quad .LC0
.globl i
.bss
.align 4
.type i, @object
.size i, 4
i:
.zero 4
.section .rodata
.LC1:
.string "Hello world!"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movq $.LC1, p(%rip)
movl i(%rip), %eax
addl $1, %eax
movl %eax, i(%rip)
movl $0, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu 5.3.1-14ubuntu2) 5.3.1 20160413"
.section .note.GNU-stack,"",@progbits

生成目标文件 19-1.o ,是不可以执行的,需要链接器链接。
mhr@ubuntu:~/work/C$ gcc -c 19-1.s -o 19-1.o
mhr@ubuntu:~/work/C$ ll
total 28
drwxrwxr-x 2 mhr mhr 4096 Dec 31 23:38 ./
drwxrwxr-x 4 mhr mhr 4096 Dec 15 03:18 ../
-rw------- 1 mhr mhr 196 Nov 2 2014 19-1.c
-rw------- 1 mhr mhr 85 Nov 2 2014 19-1.h
-rw-rw-r-- 1 mhr mhr 279 Dec 31 23:18 19-1.i
-rw-rw-r-- 1 mhr mhr 1696 Dec 31 23:38 19-1.o
-rw-rw-r-- 1 mhr mhr 677 Dec 31 23:32 19-1.s
mhr@ubuntu:~/work/C$
链接器链接目标文件 生成最终的可执行程序 a.out, 可以运行 ./a.out
mhr@ubuntu:~/work/C$ gcc 19-1.o
lmhr@ubuntu:~/work/C$ ll
total 40
drwxrwxr-x 2 mhr mhr 4096 Dec 31 23:43 ./
drwxrwxr-x 4 mhr mhr 4096 Dec 15 03:18 ../
-rw------- 1 mhr mhr 196 Nov 2 2014 19-1.c
-rw------- 1 mhr mhr 85 Nov 2 2014 19-1.h
-rw-rw-r-- 1 mhr mhr 279 Dec 31 23:18 19-1.i
-rw-rw-r-- 1 mhr mhr 1696 Dec 31 23:38 19-1.o
-rw-rw-r-- 1 mhr mhr 677 Dec 31 23:39 19-1.s
-rwxrwxr-x 1 mhr mhr 8600 Dec 31 23:43 a.out*
mhr@ubuntu:~/work/C$
mhr@ubuntu:~/work/C$ ./a.out
mhr@ubuntu:~/work/C$

本文通过一个实例深入解析C语言中的宏定义与预处理器的工作流程,包括宏的定义与展开,预处理器如何处理头文件包含及注释删除等,展示了从源代码到汇编代码的整个编译过程。

被折叠的 条评论
为什么被折叠?



