[컴파일러] 컴파일, Tokenizer, lexer, parser
컴파일
컴파일이란 인간이 이해할 수 있는 고수준 언어로 구성된 소스 코드를 컴퓨터가 이해할 수 있는 저수준 언어로 바꾸는 과정이다.
컴파일 과정은 언어마다 다르지만 보통 전처리 → 컴파일링 → 어셈블링 → 링킹으로 구성된다.

그러면 C 언어를 기준으로 gcc를 사용하여 컴파일 되는 과정을 살펴보자.
우선 다음과 같은 hello.c를 만들어보자.
<hello.c>
#include <stdio.h>
int main(){
printf("hello world!");
return 0;
}
전처리
전처리 과정은 본격적인 컴파일에 앞서 소스 코드를 전처리하는 과정이다.
- 헤더 파일 : 외부에 선언된 헤더 파일을 소스코드에 포함시킨다.
- 주석 제거 : 주석을 모두 제거한다.
- 매크로 정의 : #define에 정의된 매크로를 저장하고 해당 매크로 이름을 사용하는 곳을 찾아 정의된 값으로 치환한다.
전처리를 수행하는 명령어는 다음과 같다.
gcc -E hello.c -o hello.i
<hello.i>
# 0 "hello.c"
# 0 "<built-in>"
# 0 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 0 "<command-line>" 2
# 1 "hello.c"
# 1 "/usr/include/stdio.h" 1 3 4
# 28 "/usr/include/stdio.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/libc-header-start.h" 1 3 4
# 33 "/usr/include/x86_64-linux-gnu/bits/libc-header-start.h" 3 4
# 1 "/usr/include/features.h" 1 3 4
# 394 "/usr/include/features.h" 3 4
# 1 "/usr/include/features-time64.h" 1 3 4
# 20 "/usr/include/features-time64.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/wordsize.h" 1 3 4
# 21 "/usr/include/features-time64.h" 2 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/timesize.h" 1 3 4
# 19 "/usr/include/x86_64-linux-gnu/bits/timesize.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/wordsize.h" 1 3 4
# 20 "/usr/include/x86_64-linux-gnu/bits/timesize.h" 2 3 4
# 22 "/usr/include/features-time64.h" 2 3 4
# 395 "/usr/include/features.h" 2 3 4
# 502 "/usr/include/features.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 1 3 4
# 576 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/wordsize.h" 1 3 4
# 577 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 2 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/long-double.h" 1 3 4
# 578 "/usr/include/x86_64-linux-gnu/sys/cdefs.h" 2 3 4
# 503 "/usr/include/features.h" 2 3 4
# 526 "/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
# 527 "/usr/include/features.h" 2 3 4
# 34 "/usr/include/x86_64-linux-gnu/bits/libc-header-start.h" 2 3 4
# 29 "/usr/include/stdio.h" 2 3 4
# 1 "/usr/lib/gcc/x86_64-linux-gnu/13/include/stddef.h" 1 3 4
# 214 "/usr/lib/gcc/x86_64-linux-gnu/13/include/stddef.h" 3 4
# 214 "/usr/lib/gcc/x86_64-linux-gnu/13/include/stddef.h" 3 4
typedef long unsigned int size_t;
# 35 "/usr/include/stdio.h" 2 3 4
# 1 "/usr/lib/gcc/x86_64-linux-gnu/13/include/stdarg.h" 1 3 4
# 40 "/usr/lib/gcc/x86_64-linux-gnu/13/include/stdarg.h" 3 4
typedef __builtin_va_list __gnuc_va_list;
# 38 "/usr/include/stdio.h" 2 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/types.h" 1 3 4
# 27 "/usr/include/x86_64-linux-gnu/bits/types.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/wordsize.h" 1 3 4
# 28 "/usr/include/x86_64-linux-gnu/bits/types.h" 2 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/timesize.h" 1 3 4
# 19 "/usr/include/x86_64-linux-gnu/bits/timesize.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/wordsize.h" 1 3 4
# 20 "/usr/include/x86_64-linux-gnu/bits/timesize.h" 2 3 4
# 29 "/usr/include/x86_64-linux-gnu/bits/types.h" 2 3 4
typedef unsigned char __u_char;
typedef unsigned short int __u_short;
typedef unsigned int __u_int;
typedef unsigned long int __u_long;
typedef signed char __int8_t;
typedef unsigned char __uint8_t;
typedef signed short int __int16_t;
typedef unsigned short int __uint16_t;
typedef signed int __int32_t;
typedef unsigned int __uint32_t;
typedef signed long int __int64_t;
typedef unsigned long int __uint64_t;
typedef __int8_t __int_least8_t;
typedef __uint8_t __uint_least8_t;
typedef __int16_t __int_least16_t;
typedef __uint16_t __uint_least16_t;
typedef __int32_t __int_least32_t;
typedef __uint32_t __uint_least32_t;
typedef __int64_t __int_least64_t;
typedef __uint64_t __uint_least64_t;
typedef long int __quad_t;
typedef unsigned long int __u_quad_t;
typedef long int __intmax_t;
typedef unsigned long int __uintmax_t;
# 141 "/usr/include/x86_64-linux-gnu/bits/types.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/typesizes.h" 1 3 4
# 142 "/usr/include/x86_64-linux-gnu/bits/types.h" 2 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/time64.h" 1 3 4
# 143 "/usr/include/x86_64-linux-gnu/bits/types.h" 2 3 4
typedef unsigned long int __dev_t;
typedef unsigned int __uid_t;
typedef unsigned int __gid_t;
typedef unsigned long int __ino_t;
typedef unsigned long int __ino64_t;
typedef unsigned int __mode_t;
typedef unsigned long int __nlink_t;
typedef long int __off_t;
typedef long int __off64_t;
typedef int __pid_t;
typedef struct { int __val[2]; } __fsid_t;
typedef long int __clock_t;
typedef unsigned long int __rlim_t;
typedef unsigned long int __rlim64_t;
typedef unsigned int __id_t;
typedef long int __time_t;
typedef unsigned int __useconds_t;
typedef long int __suseconds_t;
typedef long int __suseconds64_t;
typedef int __daddr_t;
typedef int __key_t;
typedef int __clockid_t;
typedef void * __timer_t;
typedef long int __blksize_t;
typedef long int __blkcnt_t;
typedef long int __blkcnt64_t;
typedef unsigned long int __fsblkcnt_t;
typedef unsigned long int __fsblkcnt64_t;
typedef unsigned long int __fsfilcnt_t;
typedef unsigned long int __fsfilcnt64_t;
typedef long int __fsword_t;
typedef long int __ssize_t;
typedef long int __syscall_slong_t;
typedef unsigned long int __syscall_ulong_t;
typedef __off64_t __loff_t;
typedef char *__caddr_t;
typedef long int __intptr_t;
typedef unsigned int __socklen_t;
typedef int __sig_atomic_t;
# 40 "/usr/include/stdio.h" 2 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h" 1 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h" 1 3 4
# 13 "/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h" 3 4
typedef struct
{
int __count;
union
{
unsigned int __wch;
char __wchb[4];
} __value;
} __mbstate_t;
# 6 "/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h" 2 3 4
typedef struct _G_fpos_t
{
__off_t __pos;
__mbstate_t __state;
} __fpos_t;
# 41 "/usr/include/stdio.h" 2 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h" 1 3 4
# 10 "/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h" 3 4
typedef struct _G_fpos64_t
{
__off64_t __pos;
__mbstate_t __state;
} __fpos64_t;
# 42 "/usr/include/stdio.h" 2 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/types/__FILE.h" 1 3 4
struct _IO_FILE;
typedef struct _IO_FILE __FILE;
# 43 "/usr/include/stdio.h" 2 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/types/FILE.h" 1 3 4
struct _IO_FILE;
typedef struct _IO_FILE FILE;
# 44 "/usr/include/stdio.h" 2 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h" 1 3 4
# 35 "/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h" 3 4
struct _IO_FILE;
struct _IO_marker;
struct _IO_codecvt;
struct _IO_wide_data;
typedef void _IO_lock_t;
struct _IO_FILE
{
int _flags;
char *_IO_read_ptr;
char *_IO_read_end;
char *_IO_read_base;
char *_IO_write_base;
char *_IO_write_ptr;
char *_IO_write_end;
char *_IO_buf_base;
char *_IO_buf_end;
char *_IO_save_base;
char *_IO_backup_base;
char *_IO_save_end;
struct _IO_marker *_markers;
struct _IO_FILE *_chain;
int _fileno;
int _flags2;
__off_t _old_offset;
unsigned short _cur_column;
signed char _vtable_offset;
char _shortbuf[1];
_IO_lock_t *_lock;
__off64_t _offset;
struct _IO_codecvt *_codecvt;
struct _IO_wide_data *_wide_data;
struct _IO_FILE *_freeres_list;
void *_freeres_buf;
size_t __pad5;
int _mode;
char _unused2[15 * sizeof (int) - 4 * sizeof (void *) - sizeof (size_t)];
};
# 45 "/usr/include/stdio.h" 2 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/types/cookie_io_functions_t.h" 1 3 4
# 27 "/usr/include/x86_64-linux-gnu/bits/types/cookie_io_functions_t.h" 3 4
typedef __ssize_t cookie_read_function_t (void *__cookie, char *__buf,
size_t __nbytes);
typedef __ssize_t cookie_write_function_t (void *__cookie, const char *__buf,
size_t __nbytes);
typedef int cookie_seek_function_t (void *__cookie, __off64_t *__pos, int __w);
typedef int cookie_close_function_t (void *__cookie);
typedef struct _IO_cookie_io_functions_t
{
cookie_read_function_t *read;
cookie_write_function_t *write;
cookie_seek_function_t *seek;
cookie_close_function_t *close;
} cookie_io_functions_t;
# 48 "/usr/include/stdio.h" 2 3 4
typedef __gnuc_va_list va_list;
# 64 "/usr/include/stdio.h" 3 4
typedef __off_t off_t;
# 78 "/usr/include/stdio.h" 3 4
typedef __ssize_t ssize_t;
typedef __fpos_t fpos_t;
# 129 "/usr/include/stdio.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/stdio_lim.h" 1 3 4
# 130 "/usr/include/stdio.h" 2 3 4
# 149 "/usr/include/stdio.h" 3 4
extern FILE *stdin;
extern FILE *stdout;
extern FILE *stderr;
extern int remove (const char *__filename) __attribute__ ((__nothrow__ , __leaf__));
extern int rename (const char *__old, const char *__new) __attribute__ ((__nothrow__ , __leaf__));
extern int renameat (int __oldfd, const char *__old, int __newfd,
const char *__new) __attribute__ ((__nothrow__ , __leaf__));
# 184 "/usr/include/stdio.h" 3 4
extern int fclose (FILE *__stream) __attribute__ ((__nonnull__ (1)));
# 194 "/usr/include/stdio.h" 3 4
extern FILE *tmpfile (void)
__attribute__ ((__malloc__)) __attribute__ ((__malloc__ (fclose, 1))) ;
# 211 "/usr/include/stdio.h" 3 4
extern char *tmpnam (char[20]) __attribute__ ((__nothrow__ , __leaf__)) ;
extern char *tmpnam_r (char __s[20]) __attribute__ ((__nothrow__ , __leaf__)) ;
# 228 "/usr/include/stdio.h" 3 4
extern char *tempnam (const char *__dir, const char *__pfx)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__malloc__)) __attribute__ ((__malloc__ (__builtin_free, 1)));
extern int fflush (FILE *__stream);
# 245 "/usr/include/stdio.h" 3 4
extern int fflush_unlocked (FILE *__stream);
# 264 "/usr/include/stdio.h" 3 4
extern FILE *fopen (const char *__restrict __filename,
const char *__restrict __modes)
__attribute__ ((__malloc__)) __attribute__ ((__malloc__ (fclose, 1))) ;
extern FILE *freopen (const char *__restrict __filename,
const char *__restrict __modes,
FILE *__restrict __stream) __attribute__ ((__nonnull__ (3)));
# 299 "/usr/include/stdio.h" 3 4
extern FILE *fdopen (int __fd, const char *__modes) __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__malloc__)) __attribute__ ((__malloc__ (fclose, 1))) ;
extern FILE *fopencookie (void *__restrict __magic_cookie,
const char *__restrict __modes,
cookie_io_functions_t __io_funcs) __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__malloc__)) __attribute__ ((__malloc__ (fclose, 1))) ;
extern FILE *fmemopen (void *__s, size_t __len, const char *__modes)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__malloc__)) __attribute__ ((__malloc__ (fclose, 1))) ;
extern FILE *open_memstream (char **__bufloc, size_t *__sizeloc) __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__malloc__)) __attribute__ ((__malloc__ (fclose, 1))) ;
# 334 "/usr/include/stdio.h" 3 4
extern void setbuf (FILE *__restrict __stream, char *__restrict __buf) __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__nonnull__ (1)));
extern int setvbuf (FILE *__restrict __stream, char *__restrict __buf,
int __modes, size_t __n) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern void setbuffer (FILE *__restrict __stream, char *__restrict __buf,
size_t __size) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern void setlinebuf (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int fprintf (FILE *__restrict __stream,
const char *__restrict __format, ...) __attribute__ ((__nonnull__ (1)));
extern int printf (const char *__restrict __format, ...);
extern int sprintf (char *__restrict __s,
const char *__restrict __format, ...) __attribute__ ((__nothrow__));
extern int vfprintf (FILE *__restrict __s, const char *__restrict __format,
__gnuc_va_list __arg) __attribute__ ((__nonnull__ (1)));
extern int vprintf (const char *__restrict __format, __gnuc_va_list __arg);
extern int vsprintf (char *__restrict __s, const char *__restrict __format,
__gnuc_va_list __arg) __attribute__ ((__nothrow__));
extern int snprintf (char *__restrict __s, size_t __maxlen,
const char *__restrict __format, ...)
__attribute__ ((__nothrow__)) __attribute__ ((__format__ (__printf__, 3, 4)));
extern int vsnprintf (char *__restrict __s, size_t __maxlen,
const char *__restrict __format, __gnuc_va_list __arg)
__attribute__ ((__nothrow__)) __attribute__ ((__format__ (__printf__, 3, 0)));
extern int vasprintf (char **__restrict __ptr, const char *__restrict __f,
__gnuc_va_list __arg)
__attribute__ ((__nothrow__)) __attribute__ ((__format__ (__printf__, 2, 0))) ;
extern int __asprintf (char **__restrict __ptr,
const char *__restrict __fmt, ...)
__attribute__ ((__nothrow__)) __attribute__ ((__format__ (__printf__, 2, 3))) ;
extern int asprintf (char **__restrict __ptr,
const char *__restrict __fmt, ...)
__attribute__ ((__nothrow__)) __attribute__ ((__format__ (__printf__, 2, 3))) ;
extern int vdprintf (int __fd, const char *__restrict __fmt,
__gnuc_va_list __arg)
__attribute__ ((__format__ (__printf__, 2, 0)));
extern int dprintf (int __fd, const char *__restrict __fmt, ...)
__attribute__ ((__format__ (__printf__, 2, 3)));
extern int fscanf (FILE *__restrict __stream,
const char *__restrict __format, ...) __attribute__ ((__nonnull__ (1)));
extern int scanf (const char *__restrict __format, ...) ;
extern int sscanf (const char *__restrict __s,
const char *__restrict __format, ...) __attribute__ ((__nothrow__ , __leaf__));
# 1 "/usr/include/x86_64-linux-gnu/bits/floatn.h" 1 3 4
# 119 "/usr/include/x86_64-linux-gnu/bits/floatn.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/floatn-common.h" 1 3 4
# 24 "/usr/include/x86_64-linux-gnu/bits/floatn-common.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/long-double.h" 1 3 4
# 25 "/usr/include/x86_64-linux-gnu/bits/floatn-common.h" 2 3 4
# 120 "/usr/include/x86_64-linux-gnu/bits/floatn.h" 2 3 4
# 438 "/usr/include/stdio.h" 2 3 4
# 463 "/usr/include/stdio.h" 3 4
extern int fscanf (FILE *__restrict __stream, const char *__restrict __format, ...) __asm__ ("" "__isoc99_fscanf")
__attribute__ ((__nonnull__ (1)));
extern int scanf (const char *__restrict __format, ...) __asm__ ("" "__isoc99_scanf")
;
extern int sscanf (const char *__restrict __s, const char *__restrict __format, ...) __asm__ ("" "__isoc99_sscanf") __attribute__ ((__nothrow__ , __leaf__))
;
# 490 "/usr/include/stdio.h" 3 4
extern int vfscanf (FILE *__restrict __s, const char *__restrict __format,
__gnuc_va_list __arg)
__attribute__ ((__format__ (__scanf__, 2, 0))) __attribute__ ((__nonnull__ (1)));
extern int vscanf (const char *__restrict __format, __gnuc_va_list __arg)
__attribute__ ((__format__ (__scanf__, 1, 0))) ;
extern int vsscanf (const char *__restrict __s,
const char *__restrict __format, __gnuc_va_list __arg)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__format__ (__scanf__, 2, 0)));
# 540 "/usr/include/stdio.h" 3 4
extern int vfscanf (FILE *__restrict __s, const char *__restrict __format, __gnuc_va_list __arg) __asm__ ("" "__isoc99_vfscanf")
__attribute__ ((__format__ (__scanf__, 2, 0))) __attribute__ ((__nonnull__ (1)));
extern int vscanf (const char *__restrict __format, __gnuc_va_list __arg) __asm__ ("" "__isoc99_vscanf")
__attribute__ ((__format__ (__scanf__, 1, 0))) ;
extern int vsscanf (const char *__restrict __s, const char *__restrict __format, __gnuc_va_list __arg) __asm__ ("" "__isoc99_vsscanf") __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__format__ (__scanf__, 2, 0)));
# 575 "/usr/include/stdio.h" 3 4
extern int fgetc (FILE *__stream) __attribute__ ((__nonnull__ (1)));
extern int getc (FILE *__stream) __attribute__ ((__nonnull__ (1)));
extern int getchar (void);
extern int getc_unlocked (FILE *__stream) __attribute__ ((__nonnull__ (1)));
extern int getchar_unlocked (void);
# 600 "/usr/include/stdio.h" 3 4
extern int fgetc_unlocked (FILE *__stream) __attribute__ ((__nonnull__ (1)));
# 611 "/usr/include/stdio.h" 3 4
extern int fputc (int __c, FILE *__stream) __attribute__ ((__nonnull__ (2)));
extern int putc (int __c, FILE *__stream) __attribute__ ((__nonnull__ (2)));
extern int putchar (int __c);
# 627 "/usr/include/stdio.h" 3 4
extern int fputc_unlocked (int __c, FILE *__stream) __attribute__ ((__nonnull__ (2)));
extern int putc_unlocked (int __c, FILE *__stream) __attribute__ ((__nonnull__ (2)));
extern int putchar_unlocked (int __c);
extern int getw (FILE *__stream) __attribute__ ((__nonnull__ (1)));
extern int putw (int __w, FILE *__stream) __attribute__ ((__nonnull__ (2)));
extern char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
__attribute__ ((__access__ (__write_only__, 1, 2))) __attribute__ ((__nonnull__ (3)));
# 694 "/usr/include/stdio.h" 3 4
extern __ssize_t __getdelim (char **__restrict __lineptr,
size_t *__restrict __n, int __delimiter,
FILE *__restrict __stream) __attribute__ ((__nonnull__ (4)));
extern __ssize_t getdelim (char **__restrict __lineptr,
size_t *__restrict __n, int __delimiter,
FILE *__restrict __stream) __attribute__ ((__nonnull__ (4)));
extern __ssize_t getline (char **__restrict __lineptr,
size_t *__restrict __n,
FILE *__restrict __stream) __attribute__ ((__nonnull__ (3)));
extern int fputs (const char *__restrict __s, FILE *__restrict __stream)
__attribute__ ((__nonnull__ (2)));
extern int puts (const char *__s);
extern int ungetc (int __c, FILE *__stream) __attribute__ ((__nonnull__ (2)));
extern size_t fread (void *__restrict __ptr, size_t __size,
size_t __n, FILE *__restrict __stream)
__attribute__ ((__nonnull__ (4)));
extern size_t fwrite (const void *__restrict __ptr, size_t __size,
size_t __n, FILE *__restrict __s) __attribute__ ((__nonnull__ (4)));
# 766 "/usr/include/stdio.h" 3 4
extern size_t fread_unlocked (void *__restrict __ptr, size_t __size,
size_t __n, FILE *__restrict __stream)
__attribute__ ((__nonnull__ (4)));
extern size_t fwrite_unlocked (const void *__restrict __ptr, size_t __size,
size_t __n, FILE *__restrict __stream)
__attribute__ ((__nonnull__ (4)));
extern int fseek (FILE *__stream, long int __off, int __whence)
__attribute__ ((__nonnull__ (1)));
extern long int ftell (FILE *__stream) __attribute__ ((__nonnull__ (1)));
extern void rewind (FILE *__stream) __attribute__ ((__nonnull__ (1)));
# 803 "/usr/include/stdio.h" 3 4
extern int fseeko (FILE *__stream, __off_t __off, int __whence)
__attribute__ ((__nonnull__ (1)));
extern __off_t ftello (FILE *__stream) __attribute__ ((__nonnull__ (1)));
# 829 "/usr/include/stdio.h" 3 4
extern int fgetpos (FILE *__restrict __stream, fpos_t *__restrict __pos)
__attribute__ ((__nonnull__ (1)));
extern int fsetpos (FILE *__stream, const fpos_t *__pos) __attribute__ ((__nonnull__ (1)));
# 860 "/usr/include/stdio.h" 3 4
extern void clearerr (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int feof (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int ferror (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern void clearerr_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int feof_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int ferror_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern void perror (const char *__s) __attribute__ ((__cold__));
extern int fileno (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int fileno_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
# 897 "/usr/include/stdio.h" 3 4
extern int pclose (FILE *__stream) __attribute__ ((__nonnull__ (1)));
extern FILE *popen (const char *__command, const char *__modes)
__attribute__ ((__malloc__)) __attribute__ ((__malloc__ (pclose, 1))) ;
extern char *ctermid (char *__s) __attribute__ ((__nothrow__ , __leaf__))
__attribute__ ((__access__ (__write_only__, 1)));
# 941 "/usr/include/stdio.h" 3 4
extern void flockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern int ftrylockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
# 959 "/usr/include/stdio.h" 3 4
extern int __uflow (FILE *);
extern int __overflow (FILE *, int);
# 983 "/usr/include/stdio.h" 3 4
# 2 "hello.c" 2
# 3 "hello.c"
int main(){
printf("hello world!");
return 0;
}
컴파일링
C 언어로 작성된 코드를 전처리 한 뒤, 어셈블리어로 작성된 코드로 변환한다.
gcc -S hello.i -o hello.s
<hello.s>
.file "hello.c"
.text
.section .rodata
.LC0:
.string "hello world!"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
endbr64
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
leaq .LC0(%rip), %rax
movq %rax, %rdi
movl $0, %eax
call printf@PLT
movl $0, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0"
.section .note.GNU-stack,"",@progbits
.section .note.gnu.property,"a"
.align 8
.long 1f - 0f
.long 4f - 1f
.long 5
0:
.string "GNU"
1:
.align 8
.long 0xc0000002
.long 3f - 2f
2:
.long 0x3
3:
.align 8
4:
어셈블링
어셈블리어로 작성된 코드를 0과 1로 된 오브젝트 코드로 바꾼다.
gcc -c hello.s -o hello.o
오브젝트 파일은 0과 1로 되어 있는데 단순 편집기를 사용해서 열면 내용이 깨지게 된다.
xxd를 사용해서 2진수 형태로 출력해보자.
xxd -b hello.o
<hello.o>
00000000: 01111111 01000101 01001100 01000110 00000010 00000001 .ELF..
00000006: 00000001 00000000 00000000 00000000 00000000 00000000 ......
0000000c: 00000000 00000000 00000000 00000000 00000001 00000000 ......
00000012: 00111110 00000000 00000001 00000000 00000000 00000000 >.....
00000018: 00000000 00000000 00000000 00000000 00000000 00000000 ......
0000001e: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000024: 00000000 00000000 00000000 00000000 01100000 00000010 ....`.
0000002a: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000030: 00000000 00000000 00000000 00000000 01000000 00000000 ....@.
00000036: 00000000 00000000 00000000 00000000 01000000 00000000 ....@.
0000003c: 00001110 00000000 00001101 00000000 11110011 00001111 ......
00000042: 00011110 11111010 01010101 01001000 10001001 11100101 ..UH..
00000048: 01001000 10001101 00000101 00000000 00000000 00000000 H.....
0000004e: 00000000 01001000 10001001 11000111 10111000 00000000 .H....
00000054: 00000000 00000000 00000000 11101000 00000000 00000000 ......
0000005a: 00000000 00000000 10111000 00000000 00000000 00000000 ......
00000060: 00000000 01011101 11000011 01101000 01100101 01101100 .].hel
00000066: 01101100 01101111 00100000 01110111 01101111 01110010 lo wor
0000006c: 01101100 01100100 00100001 00000000 00000000 01000111 ld!..G
00000072: 01000011 01000011 00111010 00100000 00101000 01010101 CC: (U
00000078: 01100010 01110101 01101110 01110100 01110101 00100000 buntu
0000007e: 00110001 00110011 00101110 00110011 00101110 00110000 13.3.0
00000084: 00101101 00110110 01110101 01100010 01110101 01101110 -6ubun
0000008a: 01110100 01110101 00110010 01111110 00110010 00110100 tu2~24
00000090: 00101110 00110000 00110100 00101001 00100000 00110001 .04) 1
00000096: 00110011 00101110 00110011 00101110 00110000 00000000 3.3.0.
0000009c: 00000000 00000000 00000000 00000000 00000100 00000000 ......
000000a2: 00000000 00000000 00010000 00000000 00000000 00000000 ......
000000a8: 00000101 00000000 00000000 00000000 01000111 01001110 ....GN
000000ae: 01010101 00000000 00000010 00000000 00000000 11000000 U.....
000000b4: 00000100 00000000 00000000 00000000 00000011 00000000 ......
000000ba: 00000000 00000000 00000000 00000000 00000000 00000000 ......
000000c0: 00010100 00000000 00000000 00000000 00000000 00000000 ......
000000c6: 00000000 00000000 00000001 01111010 01010010 00000000 ...zR.
000000cc: 00000001 01111000 00010000 00000001 00011011 00001100 .x....
000000d2: 00000111 00001000 10010000 00000001 00000000 00000000 ......
000000d8: 00011100 00000000 00000000 00000000 00011100 00000000 ......
000000de: 00000000 00000000 00000000 00000000 00000000 00000000 ......
000000e4: 00100011 00000000 00000000 00000000 00000000 01000101 #....E
000000ea: 00001110 00010000 10000110 00000010 01000011 00001101 ....C.
000000f0: 00000110 01011010 00001100 00000111 00001000 00000000 .Z....
000000f6: 00000000 00000000 00000000 00000000 00000000 00000000 ......
000000fc: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000102: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000108: 00000000 00000000 00000000 00000000 00000000 00000000 ......
0000010e: 00000000 00000000 00000001 00000000 00000000 00000000 ......
00000114: 00000100 00000000 11110001 11111111 00000000 00000000 ......
0000011a: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000120: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000126: 00000000 00000000 00000000 00000000 00000000 00000000 ......
0000012c: 00000011 00000000 00000001 00000000 00000000 00000000 ......
00000132: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000138: 00000000 00000000 00000000 00000000 00000000 00000000 ......
0000013e: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000144: 00000011 00000000 00000101 00000000 00000000 00000000 ......
0000014a: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000150: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000156: 00000000 00000000 00001001 00000000 00000000 00000000 ......
0000015c: 00010010 00000000 00000001 00000000 00000000 00000000 ......
00000162: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000168: 00100011 00000000 00000000 00000000 00000000 00000000 #.....
0000016e: 00000000 00000000 00001110 00000000 00000000 00000000 ......
00000174: 00010000 00000000 00000000 00000000 00000000 00000000 ......
0000017a: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000180: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000186: 00000000 00000000 00000000 01101000 01100101 01101100 ...hel
0000018c: 01101100 01101111 00101110 01100011 00000000 01101101 lo.c.m
00000192: 01100001 01101001 01101110 00000000 01110000 01110010 ain.pr
00000198: 01101001 01101110 01110100 01100110 00000000 00000000 intf..
0000019e: 00000000 00000000 00001011 00000000 00000000 00000000 ......
000001a4: 00000000 00000000 00000000 00000000 00000010 00000000 ......
000001aa: 00000000 00000000 00000011 00000000 00000000 00000000 ......
000001b0: 11111100 11111111 11111111 11111111 11111111 11111111 ......
000001b6: 11111111 11111111 00011000 00000000 00000000 00000000 ......
000001bc: 00000000 00000000 00000000 00000000 00000100 00000000 ......
000001c2: 00000000 00000000 00000101 00000000 00000000 00000000 ......
000001c8: 11111100 11111111 11111111 11111111 11111111 11111111 ......
000001ce: 11111111 11111111 00100000 00000000 00000000 00000000 .. ...
000001d4: 00000000 00000000 00000000 00000000 00000010 00000000 ......
000001da: 00000000 00000000 00000010 00000000 00000000 00000000 ......
000001e0: 00000000 00000000 00000000 00000000 00000000 00000000 ......
000001e6: 00000000 00000000 00000000 00101110 01110011 01111001 ....sy
000001ec: 01101101 01110100 01100001 01100010 00000000 00101110 mtab..
000001f2: 01110011 01110100 01110010 01110100 01100001 01100010 strtab
000001f8: 00000000 00101110 01110011 01101000 01110011 01110100 ..shst
000001fe: 01110010 01110100 01100001 01100010 00000000 00101110 rtab..
00000204: 01110010 01100101 01101100 01100001 00101110 01110100 rela.t
0000020a: 01100101 01111000 01110100 00000000 00101110 01100100 ext..d
00000210: 01100001 01110100 01100001 00000000 00101110 01100010 ata..b
00000216: 01110011 01110011 00000000 00101110 01110010 01101111 ss..ro
0000021c: 01100100 01100001 01110100 01100001 00000000 00101110 data..
00000222: 01100011 01101111 01101101 01101101 01100101 01101110 commen
00000228: 01110100 00000000 00101110 01101110 01101111 01110100 t..not
0000022e: 01100101 00101110 01000111 01001110 01010101 00101101 e.GNU-
00000234: 01110011 01110100 01100001 01100011 01101011 00000000 stack.
0000023a: 00101110 01101110 01101111 01110100 01100101 00101110 .note.
00000240: 01100111 01101110 01110101 00101110 01110000 01110010 gnu.pr
00000246: 01101111 01110000 01100101 01110010 01110100 01111001 operty
0000024c: 00000000 00101110 01110010 01100101 01101100 01100001 ..rela
00000252: 00101110 01100101 01101000 01011111 01100110 01110010 .eh_fr
00000258: 01100001 01101101 01100101 00000000 00000000 00000000 ame...
0000025e: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000264: 00000000 00000000 00000000 00000000 00000000 00000000 ......
0000026a: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000270: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000276: 00000000 00000000 00000000 00000000 00000000 00000000 ......
0000027c: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000282: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000288: 00000000 00000000 00000000 00000000 00000000 00000000 ......
0000028e: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000294: 00000000 00000000 00000000 00000000 00000000 00000000 ......
0000029a: 00000000 00000000 00000000 00000000 00000000 00000000 ......
000002a0: 00100000 00000000 00000000 00000000 00000001 00000000 .....
000002a6: 00000000 00000000 00000110 00000000 00000000 00000000 ......
000002ac: 00000000 00000000 00000000 00000000 00000000 00000000 ......
000002b2: 00000000 00000000 00000000 00000000 00000000 00000000 ......
000002b8: 01000000 00000000 00000000 00000000 00000000 00000000 @.....
000002be: 00000000 00000000 00100011 00000000 00000000 00000000 ..#...
000002c4: 00000000 00000000 00000000 00000000 00000000 00000000 ......
000002ca: 00000000 00000000 00000000 00000000 00000000 00000000 ......
000002d0: 00000001 00000000 00000000 00000000 00000000 00000000 ......
000002d6: 00000000 00000000 00000000 00000000 00000000 00000000 ......
000002dc: 00000000 00000000 00000000 00000000 00011011 00000000 ......
000002e2: 00000000 00000000 00000100 00000000 00000000 00000000 ......
000002e8: 01000000 00000000 00000000 00000000 00000000 00000000 @.....
000002ee: 00000000 00000000 00000000 00000000 00000000 00000000 ......
000002f4: 00000000 00000000 00000000 00000000 10100000 00000001 ......
000002fa: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000300: 00110000 00000000 00000000 00000000 00000000 00000000 0.....
00000306: 00000000 00000000 00001011 00000000 00000000 00000000 ......
0000030c: 00000001 00000000 00000000 00000000 00001000 00000000 ......
00000312: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000318: 00011000 00000000 00000000 00000000 00000000 00000000 ......
0000031e: 00000000 00000000 00100110 00000000 00000000 00000000 ..&...
00000324: 00000001 00000000 00000000 00000000 00000011 00000000 ......
0000032a: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000330: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000336: 00000000 00000000 01100011 00000000 00000000 00000000 ..c...
0000033c: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000342: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000348: 00000000 00000000 00000000 00000000 00000000 00000000 ......
0000034e: 00000000 00000000 00000001 00000000 00000000 00000000 ......
00000354: 00000000 00000000 00000000 00000000 00000000 00000000 ......
0000035a: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000360: 00101100 00000000 00000000 00000000 00001000 00000000 ,.....
00000366: 00000000 00000000 00000011 00000000 00000000 00000000 ......
0000036c: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000372: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000378: 01100011 00000000 00000000 00000000 00000000 00000000 c.....
0000037e: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000384: 00000000 00000000 00000000 00000000 00000000 00000000 ......
0000038a: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000390: 00000001 00000000 00000000 00000000 00000000 00000000 ......
00000396: 00000000 00000000 00000000 00000000 00000000 00000000 ......
0000039c: 00000000 00000000 00000000 00000000 00110001 00000000 ....1.
000003a2: 00000000 00000000 00000001 00000000 00000000 00000000 ......
000003a8: 00000010 00000000 00000000 00000000 00000000 00000000 ......
000003ae: 00000000 00000000 00000000 00000000 00000000 00000000 ......
000003b4: 00000000 00000000 00000000 00000000 01100011 00000000 ....c.
000003ba: 00000000 00000000 00000000 00000000 00000000 00000000 ......
000003c0: 00001101 00000000 00000000 00000000 00000000 00000000 ......
000003c6: 00000000 00000000 00000000 00000000 00000000 00000000 ......
000003cc: 00000000 00000000 00000000 00000000 00000001 00000000 ......
000003d2: 00000000 00000000 00000000 00000000 00000000 00000000 ......
000003d8: 00000000 00000000 00000000 00000000 00000000 00000000 ......
000003de: 00000000 00000000 00111001 00000000 00000000 00000000 ..9...
000003e4: 00000001 00000000 00000000 00000000 00110000 00000000 ....0.
000003ea: 00000000 00000000 00000000 00000000 00000000 00000000 ......
000003f0: 00000000 00000000 00000000 00000000 00000000 00000000 ......
000003f6: 00000000 00000000 01110000 00000000 00000000 00000000 ..p...
000003fc: 00000000 00000000 00000000 00000000 00101100 00000000 ....,.
00000402: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000408: 00000000 00000000 00000000 00000000 00000000 00000000 ......
0000040e: 00000000 00000000 00000001 00000000 00000000 00000000 ......
00000414: 00000000 00000000 00000000 00000000 00000001 00000000 ......
0000041a: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000420: 01000010 00000000 00000000 00000000 00000001 00000000 B.....
00000426: 00000000 00000000 00000000 00000000 00000000 00000000 ......
0000042c: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000432: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000438: 10011100 00000000 00000000 00000000 00000000 00000000 ......
0000043e: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000444: 00000000 00000000 00000000 00000000 00000000 00000000 ......
0000044a: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000450: 00000001 00000000 00000000 00000000 00000000 00000000 ......
00000456: 00000000 00000000 00000000 00000000 00000000 00000000 ......
0000045c: 00000000 00000000 00000000 00000000 01010010 00000000 ....R.
00000462: 00000000 00000000 00000111 00000000 00000000 00000000 ......
00000468: 00000010 00000000 00000000 00000000 00000000 00000000 ......
0000046e: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000474: 00000000 00000000 00000000 00000000 10100000 00000000 ......
0000047a: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000480: 00100000 00000000 00000000 00000000 00000000 00000000 .....
00000486: 00000000 00000000 00000000 00000000 00000000 00000000 ......
0000048c: 00000000 00000000 00000000 00000000 00001000 00000000 ......
00000492: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000498: 00000000 00000000 00000000 00000000 00000000 00000000 ......
0000049e: 00000000 00000000 01101010 00000000 00000000 00000000 ..j...
000004a4: 00000001 00000000 00000000 00000000 00000010 00000000 ......
000004aa: 00000000 00000000 00000000 00000000 00000000 00000000 ......
000004b0: 00000000 00000000 00000000 00000000 00000000 00000000 ......
000004b6: 00000000 00000000 11000000 00000000 00000000 00000000 ......
000004bc: 00000000 00000000 00000000 00000000 00111000 00000000 ....8.
000004c2: 00000000 00000000 00000000 00000000 00000000 00000000 ......
000004c8: 00000000 00000000 00000000 00000000 00000000 00000000 ......
000004ce: 00000000 00000000 00001000 00000000 00000000 00000000 ......
000004d4: 00000000 00000000 00000000 00000000 00000000 00000000 ......
000004da: 00000000 00000000 00000000 00000000 00000000 00000000 ......
000004e0: 01100101 00000000 00000000 00000000 00000100 00000000 e.....
000004e6: 00000000 00000000 01000000 00000000 00000000 00000000 ..@...
000004ec: 00000000 00000000 00000000 00000000 00000000 00000000 ......
000004f2: 00000000 00000000 00000000 00000000 00000000 00000000 ......
000004f8: 11010000 00000001 00000000 00000000 00000000 00000000 ......
000004fe: 00000000 00000000 00011000 00000000 00000000 00000000 ......
00000504: 00000000 00000000 00000000 00000000 00001011 00000000 ......
0000050a: 00000000 00000000 00001001 00000000 00000000 00000000 ......
00000510: 00001000 00000000 00000000 00000000 00000000 00000000 ......
00000516: 00000000 00000000 00011000 00000000 00000000 00000000 ......
0000051c: 00000000 00000000 00000000 00000000 00000001 00000000 ......
00000522: 00000000 00000000 00000010 00000000 00000000 00000000 ......
00000528: 00000000 00000000 00000000 00000000 00000000 00000000 ......
0000052e: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000534: 00000000 00000000 00000000 00000000 11111000 00000000 ......
0000053a: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000540: 10010000 00000000 00000000 00000000 00000000 00000000 ......
00000546: 00000000 00000000 00001100 00000000 00000000 00000000 ......
0000054c: 00000100 00000000 00000000 00000000 00001000 00000000 ......
00000552: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000558: 00011000 00000000 00000000 00000000 00000000 00000000 ......
0000055e: 00000000 00000000 00001001 00000000 00000000 00000000 ......
00000564: 00000011 00000000 00000000 00000000 00000000 00000000 ......
0000056a: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000570: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000576: 00000000 00000000 10001000 00000001 00000000 00000000 ......
0000057c: 00000000 00000000 00000000 00000000 00010101 00000000 ......
00000582: 00000000 00000000 00000000 00000000 00000000 00000000 ......
00000588: 00000000 00000000 00000000 00000000 00000000 00000000 ......
0000058e: 00000000 00000000 00000001 00000000 00000000 00000000 ......
00000594: 00000000 00000000 00000000 00000000 00000000 00000000 ......
0000059a: 00000000 00000000 00000000 00000000 00000000 00000000 ......
000005a0: 00010001 00000000 00000000 00000000 00000011 00000000 ......
000005a6: 00000000 00000000 00000000 00000000 00000000 00000000 ......
000005ac: 00000000 00000000 00000000 00000000 00000000 00000000 ......
000005b2: 00000000 00000000 00000000 00000000 00000000 00000000 ......
000005b8: 11101000 00000001 00000000 00000000 00000000 00000000 ......
000005be: 00000000 00000000 01110100 00000000 00000000 00000000 ..t...
000005c4: 00000000 00000000 00000000 00000000 00000000 00000000 ......
000005ca: 00000000 00000000 00000000 00000000 00000000 00000000 ......
000005d0: 00000001 00000000 00000000 00000000 00000000 00000000 ......
000005d6: 00000000 00000000 00000000 00000000 00000000 00000000 ......
000005dc: 00000000 00000000 00000000 00000000 ....
링킹
만약 프로그램이 여러 개의 파일로 존재한다면 링킹 과정을 수행한다.
여러 개의 오브젝트 파일을 합쳐 하나의 실행 파일을 만든다.
만약 자신이 작성한 코드가 아닌 라이브러리 코드를 사용한다면 해당 라이브러리 코드 또한 가져와서 실행 파일에 넣어준다.
gcc hello.o -o hello
실행 파일을 생성했다면 ./hello 명령어로 실행해보자.

"hello world!"가 잘 출력된다.
컴파일 과정을 직접 실습해보았다.
이제 컴파일 과정에서 수행되는 구문 분석에 대해 알아보자.
구문 분석
컴파일러가 소스 코드를 기계어로 변경할 때 구문 분석이라는 과정을 거치게 된다.
구분 분석 과정에서 소스 코드는 Tokenizer → Lexer → Parser를 거치면서 기계어로 변환된다.

Tokenizer
Tokenizer는 구문을 의미 있는 단위로 나누어 토큰화를 진행한다.
예를 들어 “I am a boy”라는 문장을 의미 있는 단위로 나눈다면 [ “I”, “am”, “a”, “boy” ]가 될 것이다.
토큰의 종류는 다음과 같은 구조로 이루어져 있다.
| 어휘소 | 토큰 분류 |
| sum | Identifier |
| = | Assignment operator |
| 3 | Integer literal |
| + | Addition operator |
| 2 | Integer literal |
| ; | End of statement |
Lexer
Tokenizer를 통해 구분을 의미 있는 단위로 쪼갰다면 토큰들의 의미를 분석하는 과정을 거친다.
어떠한 구문이 무슨 역할을 하는지 의미를 분석한다.
Tokenizer + Lexer의 과정을 Lexical Analyze라고 한다.
Parser
Tokenizer와 Lexer를 거친 데이터를 구조적으로 나타낸다.
Parser의 결과물은 보통 AST(Abstract Syntax Tree) 형태로 생성된다.
아래의 코드를 AST로 나타내면 다음과 같다.
while b ≠ 0
if a > b
a := a − b
else
b := b − a
return a

tokenizer, lexer, parser를 거쳐 단순 문자열이었던 코드가 컴파일러가 이해할 수 있는 트리 형태로 변경되었다.