我知道在预处理程序进程中,包含和标题将被复制到源文件中。
我使用gcc编译文件。
源文件(.c文件):
#include <stdio.h>
int main(){
printf("Hello World!!!");
return 0;
}
我可以在&#34; .i&#34;档案
# 1 "test.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "test.c"
# 1 "/usr/include/stdio.h" 1 3 4
# 27 "/usr/include/stdio.h" 3 4
# 1 "/usr/include/features.h" 1 3 4
# 367 "/usr/include/features.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 1 3 4
# 410 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/wordsize.h" 1 3 4
# 411 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 2 3 4
# 368 "/usr/include/features.h" 2 3 4
# 391 "/usr/include/features.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/gnu/stubs.h" 1 3 4
# 10 "/usr/include/x86_64-linux-gnu/gnu/stubs.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/gnu/stubs-64.h" 1 3 4
# 11 "/usr/include/x86_64-linux-gnu/gnu/stubs.h" 2 3 4
# 392 "/usr/include/features.h" 2 3 4
# 28 "/usr/include/stdio.h" 2 3 4
.......
但是,在生成程序集文件(.s)后,似乎所有这些文件都已消失。
.file "test.c"
.section .rodata
.LC0:
.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
movl $.LC0, %edi
movl $0, %eax
call printf
movl $0, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609"
.section .note.GNU-stack,"",@progbits
我的问题是:
在汇编文件中,我在源代码中添加的include stdio.h在哪里?
编译期间包含和标题的作用是什么?它们如何影响编译过程?
提前致谢!
答案 0 :(得分:0)
C和C ++中的头文件为编译器提供信息
它需要解析您所在的源文件
#include
他们。你在源文件中#include
使编译器能够做到这一点。解析了一个来源
文件和所有#include
- ed头文件,编译器
能够生成能够的目标代码文件
在可执行文件中与其他人链接在一起。那个联系
由您的linker
所有人都没有必要 启用编译器解析源的信息 要以任何形式复制到目标文件中的文件。一旦它 已经服务于解析的目的,绝大多数 它通常没有进一步的用途。食谱使您可以烹饪菜肴。什么时候 你做了这道菜,你不希望在里面找到食谱。
如果生成并检查编译器的汇编代码 从一些输入源文件生成,你正在看的是 目标文件的汇编语言翻译 编译器将从相同的输入产生。任何信息 是不必要的,并且在目标代码中不存在同样是不必要的 并且在汇编代码中没有。
典型头文件中的大部分信息都定义了, 在代码中,软件设施的编程接口是您自己的代码 将使用,但已经在一些外部库中编译自己的对象 代码需要与之链接。这个信息使 编译器生成的对象代码可以与之链接 外部图书馆以预期和正确的方式。
例如,在汇编列表中,您可以看到程序初始化寄存器
拨打printf
如你所知,这是一个标准C功能,已实施
在您的程序将链接的C运行时库中,
其接口由<stdio.h>
中的函数声明指定,您#included
。
编译器仅需要<stdio.h>
来验证设置printf
以这种方式调用符合printf
期望的调用过程
在C运行时库中。好吧,在printf
调用 的目标代码中
完全如您在装配中看到的那样设置,<stdio.h>
一旦完成就是废料。
您可能会被this answer
进一步开悟