发布网友
共4个回答
懂视网
编译器主要用来把源代码编译成目标文件,链接器则用来把目标文件和库文件链接成可执行文件。
编译器对源文件进行编译,在这个过程中,编译器会进行一系列的语法检查。如果编译通过,就会把对应的CPP转换成OBJ文件。链接器进行链接的时候,首先决定各个目标文件在最终可执行文件里的位置,然后访问所有目标文件的地址重定义表,对其中记录的地址进行重定向,然后遍历所有目标文件的未解决符号表,并且在所有的导出符号表里查找匹配的符号,并在未解决符号表中所记录的位置上填写实现地址。最后把所有的目标文件的内容写在各自的位置上,再作一些另的工作,就生成一个可执行文件。
热心网友
1、编译器:
编译器对源文件进行编译,就是把源文件中的文本形式存在的源代码翻译成机器语言形式的目标文件的过程,在这个过程中,编译器会进行一系列的语法检查。如果编译通过,就会把对应的CPP转换成OBJ文件。
2、链接器:
当链接器进行链接的时候,首先决定各个目标文件在最终可执行文件里的位置。然后访问所有目标文件的地址重定义表,对其中记录的地址进行重定向(加上一个偏移量,即该编译单元在可执行文件上的起始地址)。
然后遍历所有目标文件的未解决符号表,并且在所有的导出符号表里查找匹配的符号,并在未解决符号表中所记录的位置上填写实现地址。最后把所有的目标文件的内容写在各自的位置上,再作一些另的工作,就生成一个可执行文件。
热心网友
一。从源程序(.h .c文件)到可执行文件(ELF)的全过程如下:
(1)预处理
(2)转为汇编代码
(3)转为目标代码
(4)链接成可执行文件
二。分工
编译器工作阶段:(1) (2) (3)
链接器工作阶段:(4)
三。举例说明
1.实现功能:求两个全局整型变量 a b 的和。
2.编译 链接 过程产生文件
现有源文件3个:enter.c add.h add.c 。
经过程(1)
命令:gcc -Eadd.c-oadd.i
gcc -Eenter.c-oenter.i
产生2个文件:add.i enter.i(处理后的文件)
经过程(2)
命令:gcc -Sadd.i-oadd.s
gcc -Senter.i-oenter.s
产生2个文件:add.s enter.s(汇编代码文件)
经过程(3)
命令:gcc -cadd.s-oadd.o
gcc -center.s-oenter.o
产生2个文件:add.o enter.o(目标文件)
经过程(4)
命令:gccadd.o enter.o-oexe
产生1个文件:exe(可执行文件)
3.文件内容
————————————————————————————————————————————————————————————————————————————————
.c.h源文件
————————————————————————————————————————————————————————————————————————————————
//////////////////////////////////////////////////////
//enter.c 主函数 所在文件
//////////////////////////////////////////////////////
#include "add.h"
int main()
{
int c;
c=add();
return 0;
}
//////////////////////////////////////////////////////
//add.h 加法函数add(),整型数据int a,b 的声明
//////////////////////////////////////////////////////
#ifndef ADD_H
#define ADD_H
int a;
int b;
#endif
//////////////////////////////////////////////////////
//add.c 加法函数 add() 的定义
//////////////////////////////////////////////////////
#include "add.h"
a=1;
b=2;
int add()
{
return a+b;
}
————————————————————————————————————————————————————————————————————————————————
.i 处理后的文件
————————————————————————————————————————————————————————————————————————————————
//////////////////////////////////////////////////////
//add.i
//////////////////////////////////////////////////////
# 1 "add.c"
# 1 "<built-in>"
# 1 "<命令行>"
# 1 "add.c"
# 1 "add.h" 1
int a;
int b;
# 2 "add.c" 2
a=1;
b=2;
int add()
{
return a+b;
}
//////////////////////////////////////////////////////
//enter.i
//////////////////////////////////////////////////////
# 1 "enter.c"
# 1 "<built-in>"
# 1 "<命令行>"
# 1 "enter.c"
# 1 "add.h" 1
int a;
int b;
# 2 "enter.c" 2
int main()
{
int c;
c=add();
return 0;
}
————————————————————————————————————————————————————————————————————————————————
.s 汇编代码文件
————————————————————————————————————————————————————————————————————————————————
//////////////////////////////////////////////////////
//add.s
//////////////////////////////////////////////////////
.file"add.c"
.globla
.data
.align 4
.typea, @object
.sizea, 4
a:
.long1
.globlb
.align 4
.typeb, @object
.sizeb, 4
b:
.long2
.text
.globladd
.typeadd, @function
add:
.LFB0:
.cfi_startproc
pushl%ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl%esp, %ebp
.cfi_def_cfa_register 5
movla, %edx
movlb, %eax
addl%edx, %eax
popl%ebp
.cfi_def_cfa 4, 4
.cfi_restore 5
ret
.cfi_endproc
.LFE0:
.sizeadd, .-add
.ident"GCC: (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1"
.section.note.GNU-stack,"",@progbits
//////////////////////////////////////////////////////
//enter.s
//////////////////////////////////////////////////////
.file"enter.c"
.comma,4,4
.commb,4,4
.text
.globlmain
.typemain, @function
main:
.LFB0:
.cfi_startproc
pushl%ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl%esp, %ebp
.cfi_def_cfa_register 5
andl$-16, %esp
subl$16, %esp
calladd
movl%eax, 12(%esp)
movl$0, %eax
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE0:
.sizemain, .-main
.ident"GCC: (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1"
.section.note.GNU-stack,"",@progbits
————————————————————————————————————————————————————————————————————————————————
.o 目标文件(二进制文件)
————————————————————————————————————————————————————————————————————————————————
————————————————————————————————————————————————————————————————————————————————
exe可执行文件(二进制文件)
————————————————————————————————————————————————————————————————————————————————
热心网友
编译器:把源代码编译成目标文件
链接器:把目标文件和库文件链接成可执行文件