Next: About this document ...
Up: Compilers
Previous: Structure of a compiler
Several other programs may be required to produce an EXECUTABLE
target program.
- A PREPROCESSOR produces an input to a compiler.
To do so it may perform the following tasks.
- Collecting files.
- A source program may be divided into modules stored in different files.
The PREPROCESSOR will collect these modules (for instance
inclusion of header files in C) and generate the source program file.
- Macro processing.
- The preprocessor will expand shorthands, called
MACROS.
- Language extension.
- Some language facilities (data structures, case statements) may
be added to the language by BUILT-IN macros
expanded by the he preprocessor.
- An ASSEMBLER translates
- ASSEMBLY CODE that is a mnemonic version of machine code
where names are used instead of binary codes for
- operations,
- memory addresses
- into RELOCATABLE MACHINE CODE that is a machine code that
can be loaded from any location of the memory
(hence, if is added to all addresses in the code, all references
will remain correct).
- A LOADER/LINK-EDITOR performs the following tasks.
- The link-editor makes a single file from several files of
relocatable machine code.
- The loader
- translates a relocatable machine code into an absolute machine code,
- places it in memory at the proper locations.
We consider now an example.
The above file addAndPrint.c
is a C program.
We compile it with the cc compiler
using the -save-temps option which
allows to save temporary files.
In our example these files are
- addAndPrint.i which is the output of the preprocessor,
- addAndPrint.s which is the assembly code generated by cc,
- addAndPrint.o which is the relocatable machine code
generated by the assembler of cc from addAndPrint.s,
- a.out which is the executable machine code
generated by the linker from addAndPrint.o.
DIV ALIGN="CENTER">
[moreno@iguanodon tmp]$ more addAndPrint.c
#define ADD +
#define PRINT__floats__x__and__y printf("x = % d y = % d\n", x, y);
main()
{
int x,y;
x=20; y=3;
x = x ADD y*10;
PRINT__floats__x__and__y;
}
[moreno@iguanodon tmp]$ cc -save-temps addAndPrint.c
[moreno@iguanodon tmp]$ ls
addAndPrint.c addAndPrint.i addAndPrint.o addAndPrint.s a.out
[moreno@iguanodon tmp]$ more addAndPrint.i
# 4 "addAndPrint.c"
main()
{
int x,y;
x=20; y=3;
x = x + y*10;
printf("x = % d y = % d\n", x, y);;
}
[moreno@iguanodon tmp]$ file addAndPrint.s
addAndPrint.s: ASCII assembler program text
[moreno@iguanodon tmp]$ more addAndPrint.s
.file "addAndPrint.c"
.version "01.01"
gcc2_compiled.:
.section .rodata
.LC0:
.string "x = % d y = % d\n"
.text
.align 4
.globl main
.type main,@function
main:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
movl $20, -4(%ebp)
movl $3, -8(%ebp)
movl -8(%ebp), %edx
movl %edx, %eax
sall $2, %eax
addl %edx, %eax
leal (%eax,%eax), %edx
leal -4(%ebp), %eax
addl %edx, (%eax)
subl $4, %esp
pushl -8(%ebp)
pushl -4(%ebp)
pushl $.LC0
call printf
addl $16, %esp
leave
ret
.Lfe1:
.size main,.Lfe1-main
.ident "GCC: (GNU) 2.96 20000731 (Red Hat Linux 7.3 2.96-110)"
[moreno@iguanodon tmp]$ file addAndPrint.o
addAndPrint.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped
[moreno@iguanodon tmp]$ file a.out
a.out: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), not stripped
Next: About this document ...
Up: Compilers
Previous: Structure of a compiler
Marc Moreno Maza
2004-12-02