涉及到有限状态机
使用正则表达式解析识别源文件中的各个词,为其打上标签。
根据词法分析得到的各种标签组合。识别出各语句短的语法规则,分析语句块究竟想进行什么逻辑运算。
编译是一个把源文件(source)转化成目标文件(object)的过程。
编译器是具有编译功能的一个工具。往往分为多个模块,各模块负责单独的功能。 编译器除了编译功能外还有其他很多功能。下面单步调试GCC,可以了解编译器在编译过程中究竟做了哪些事情。
新建C语言源文件asm_test.c
#include <stdio.h>
int add(int a,int b)
{
return a+b;
}
int main()
{
int a = 1234;
int b = 156;
int c=add(a,b);
return 0;
}
GCC执行gcc -E asm_test.c > pre_asm_test.c
此时GCC将asm_test.c
预编译,并将输出重定向至pre_asm_test.c
pre_asm_test.c
内容如下
# 1 "asm_test.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "asm_test.c"
# 1 "GCC_PATH/include/stdio.h" 1 3
# 19 "GCC_PATH/include/stdio.h" 3
# 1 "GCC_PATH/include/_mingw.h" 1 3
# 32 "GCC_PATH/include/_mingw.h" 3
# 33 "GCC_PATH/include/_mingw.h" 3
# 20 "GCC_PATH/include/stdio.h" 2 3
# 1 "GCC_PATH/lib/gcc/mingw32/5.1.0/include/stddef.h" 1 3 4
# 216 "GCC_PATH/lib/gcc/mingw32/5.1.0/include/stddef.h" 3 4
# 216 "GCC_PATH/lib/gcc/mingw32/5.1.0/include/stddef.h" 3 4
typedef unsigned int size_t;
# 328 "GCC_PATH/lib/gcc/mingw32/5.1.0/include/stddef.h" 3 4
typedef short unsigned int wchar_t;
# 357 "GCC_PATH/lib/gcc/mingw32/5.1.0/include/stddef.h" 3 4
typedef short unsigned int wint_t;
# 27 "GCC_PATH/include/stdio.h" 2 3
# 1 "GCC_PATH/lib/gcc/mingw32/5.1.0/include/stdarg.h" 1 3 4
# 40 "GCC_PATH/lib/gcc/mingw32/5.1.0/include/stdarg.h" 3 4
typedef __builtin_va_list __gnuc_va_list;
# 29 "GCC_PATH/include/stdio.h" 2 3
# 129 "GCC_PATH/include/stdio.h" 3
typedef struct _iobuf
{
char* _ptr;
int _cnt;
char* _base;
int _flag;
int _file;
int _charbuf;
int _bufsiz;
char* _tmpfname;
} FILE;
# 154 "GCC_PATH/include/stdio.h" 3
extern __attribute__ ((__dllimport__)) FILE _iob[];
# 169 "GCC_PATH/include/stdio.h" 3
FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fopen (const char*, const char*);
FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) freopen (const char*, const char*, FILE*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fflush (FILE*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fclose (FILE*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) remove (const char*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) rename (const char*, const char*);
FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) tmpfile (void);
char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) tmpnam (char*);
char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _tempnam (const char*, const char*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _rmtmp(void);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _unlink (const char*);
char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) tempnam (const char*, const char*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) rmtmp(void);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) unlink (const char*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) setvbuf (FILE*, char*, int, size_t);
void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) setbuf (FILE*, char*);
# 204 "GCC_PATH/include/stdio.h" 3
extern int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __mingw_fprintf(FILE*, const char*, ...);
extern int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __mingw_printf(const char*, ...);
extern int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __mingw_sprintf(char*, const char*, ...);
extern int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __mingw_snprintf(char*, size_t, const char*, ...);
extern int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __mingw_vfprintf(FILE*, const char*, __gnuc_va_list);
extern int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __mingw_vprintf(const char*, __gnuc_va_list);
extern int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __mingw_vsprintf(char*, const char*, __gnuc_va_list);
extern int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __mingw_vsnprintf(char*, size_t, const char*, __gnuc_va_list);
# 293 "GCC_PATH/include/stdio.h" 3
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fprintf (FILE*, const char*, ...);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) printf (const char*, ...);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) sprintf (char*, const char*, ...);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vfprintf (FILE*, const char*, __gnuc_va_list);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vprintf (const char*, __gnuc_va_list);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vsprintf (char*, const char*, __gnuc_va_list);
# 308 "GCC_PATH/include/stdio.h" 3
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __msvcrt_fprintf(FILE*, const char*, ...);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __msvcrt_printf(const char*, ...);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __msvcrt_sprintf(char*, const char*, ...);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __msvcrt_vfprintf(FILE*, const char*, __gnuc_va_list);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __msvcrt_vprintf(const char*, __gnuc_va_list);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __msvcrt_vsprintf(char*, const char*, __gnuc_va_list);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _snprintf (char*, size_t, const char*, ...);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _vsnprintf (char*, size_t, const char*, __gnuc_va_list);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _vscprintf (const char*, __gnuc_va_list);
# 331 "GCC_PATH/include/stdio.h" 3
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) snprintf (char *, size_t, const char *, ...);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vsnprintf (char *, size_t, const char *, __gnuc_va_list);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vscanf (const char * __restrict__, __gnuc_va_list);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vfscanf (FILE * __restrict__, const char * __restrict__,
__gnuc_va_list);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vsscanf (const char * __restrict__,
const char * __restrict__, __gnuc_va_list);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fscanf (FILE*, const char*, ...);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) scanf (const char*, ...);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) sscanf (const char*, const char*, ...);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fgetc (FILE*);
char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fgets (char*, int, FILE*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fputc (int, FILE*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fputs (const char*, FILE*);
char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) gets (char*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) puts (const char*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) ungetc (int, FILE*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _filbuf (FILE*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _flsbuf (int, FILE*);
extern inline __attribute__((__gnu_inline__)) int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) getc (FILE* __F)
{
return (--__F->_cnt >= 0)
? (int) (unsigned char) *__F->_ptr++
: _filbuf (__F);
}
extern inline __attribute__((__gnu_inline__)) int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) putc (int __c, FILE* __F)
{
return (--__F->_cnt >= 0)
? (int) (unsigned char) (*__F->_ptr++ = (char)__c)
: _flsbuf (__c, __F);
}
extern inline __attribute__((__gnu_inline__)) int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) getchar (void)
{
return (--(&_iob[0])->_cnt >= 0)
? (int) (unsigned char) *(&_iob[0])->_ptr++
: _filbuf ((&_iob[0]));
}
extern inline __attribute__((__gnu_inline__)) int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) putchar(int __c)
{
return (--(&_iob[1])->_cnt >= 0)
? (int) (unsigned char) (*(&_iob[1])->_ptr++ = (char)__c)
: _flsbuf (__c, (&_iob[1]));}
# 412 "GCC_PATH/include/stdio.h" 3
size_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fread (void*, size_t, size_t, FILE*);
size_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fwrite (const void*, size_t, size_t, FILE*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fseek (FILE*, long, int);
long __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) ftell (FILE*);
void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) rewind (FILE*);
# 455 "GCC_PATH/include/stdio.h" 3
typedef long long fpos_t;
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fgetpos (FILE*, fpos_t*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fsetpos (FILE*, const fpos_t*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) feof (FILE*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) ferror (FILE*);
# 480 "GCC_PATH/include/stdio.h" 3
void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) clearerr (FILE*);
void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) perror (const char*);
FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _popen (const char*, const char*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _pclose (FILE*);
FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) popen (const char*, const char*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) pclose (FILE*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _flushall (void);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _fgetchar (void);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _fputchar (int);
FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _fdopen (int, const char*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _fileno (FILE*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _fcloseall (void);
FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _fsopen (const char*, const char*, int);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _getmaxstdio (void);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _setmaxstdio (int);
# 522 "GCC_PATH/include/stdio.h" 3
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fgetchar (void);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fputchar (int);
FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fdopen (int, const char*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fileno (FILE*);
# 534 "GCC_PATH/include/stdio.h" 3
# 1 "GCC_PATH/include/sys/types.h" 1 3
# 21 "GCC_PATH/include/sys/types.h" 3
# 1 "GCC_PATH/lib/gcc/mingw32/5.1.0/include/stddef.h" 1 3 4
# 149 "GCC_PATH/lib/gcc/mingw32/5.1.0/include/stddef.h" 3 4
typedef int ptrdiff_t;
# 22 "GCC_PATH/include/sys/types.h" 2 3
typedef long __time32_t;
typedef long long __time64_t;
# 45 "GCC_PATH/include/sys/types.h" 3
typedef __time32_t time_t;
typedef long _off_t;
typedef _off_t off_t;
typedef unsigned int _dev_t;
typedef _dev_t dev_t;
typedef short _ino_t;
typedef _ino_t ino_t;
typedef int _pid_t;
typedef _pid_t pid_t;
typedef unsigned short _mode_t;
typedef _mode_t mode_t;
typedef int _sigset_t;
typedef _sigset_t sigset_t;
typedef int _ssize_t;
typedef _ssize_t ssize_t;
typedef long long fpos64_t;
typedef long long off64_t;
typedef unsigned int useconds_t;
# 535 "GCC_PATH/include/stdio.h" 2 3
extern inline __attribute__((__gnu_inline__)) FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fopen64 (const char* filename, const char* mode)
{
return fopen (filename, mode);
}
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fseeko64 (FILE*, off64_t, int);
extern inline __attribute__((__gnu_inline__)) off64_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) ftello64 (FILE * stream)
{
fpos_t pos;
if (fgetpos(stream, &pos))
return -1LL;
else
return ((off64_t) pos);
}
# 563 "GCC_PATH/include/stdio.h" 3
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fwprintf (FILE*, const wchar_t*, ...);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) wprintf (const wchar_t*, ...);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _snwprintf (wchar_t*, size_t, const wchar_t*, ...);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vfwprintf (FILE*, const wchar_t*, __gnuc_va_list);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vwprintf (const wchar_t*, __gnuc_va_list);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _vsnwprintf (wchar_t*, size_t, const wchar_t*, __gnuc_va_list);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _vscwprintf (const wchar_t*, __gnuc_va_list);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fwscanf (FILE*, const wchar_t*, ...);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) wscanf (const wchar_t*, ...);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) swscanf (const wchar_t*, const wchar_t*, ...);
wint_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fgetwc (FILE*);
wint_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fputwc (wchar_t, FILE*);
wint_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) ungetwc (wchar_t, FILE*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) swprintf (wchar_t*, const wchar_t*, ...);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vswprintf (wchar_t*, const wchar_t*, __gnuc_va_list);
wchar_t* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fgetws (wchar_t*, int, FILE*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fputws (const wchar_t*, FILE*);
wint_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) getwc (FILE*);
wint_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) getwchar (void);
wchar_t* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _getws (wchar_t*);
wint_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) putwc (wint_t, FILE*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _putws (const wchar_t*);
wint_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) putwchar (wint_t);
FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wfdopen(int, const wchar_t *);
FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wfopen (const wchar_t*, const wchar_t*);
FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wfreopen (const wchar_t*, const wchar_t*, FILE*);
FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wfsopen (const wchar_t*, const wchar_t*, int);
wchar_t* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wtmpnam (wchar_t*);
wchar_t* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wtempnam (const wchar_t*, const wchar_t*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wrename (const wchar_t*, const wchar_t*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wremove (const wchar_t*);
void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wperror (const wchar_t*);
FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wpopen (const wchar_t*, const wchar_t*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) snwprintf (wchar_t* s, size_t n, const wchar_t* format, ...);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vsnwprintf (wchar_t* s, size_t n, const wchar_t* format, __gnuc_va_list arg);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vwscanf (const wchar_t * __restrict__, __gnuc_va_list);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vfwscanf (FILE * __restrict__,
const wchar_t * __restrict__, __gnuc_va_list);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vswscanf (const wchar_t * __restrict__,
const wchar_t * __restrict__, __gnuc_va_list);
# 625 "GCC_PATH/include/stdio.h" 3
FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) wpopen (const wchar_t*, const wchar_t*);
wint_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _fgetwchar (void);
wint_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _fputwchar (wint_t);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _getw (FILE*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _putw (int, FILE*);
wint_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fgetwchar (void);
wint_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fputwchar (wint_t);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) getw (FILE*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) putw (int, FILE*);
# 2 "asm_test.c" 2
# 3 "asm_test.c"
int add(int a,int b)
{
return a+b;
}
int main()
{
int a = 1234;
int b = 156;
int c=add(a,b);
return 0;
}
在add(int a,int b)
之前#include <stdio.h>
被展开了。
展开的这些函数就是依赖C语言库的部分。
再次执行
gcc -S pre_asm_test.c -o asm_test.s
asm_test.s
.file "pre_asm_test.c"
.text
.globl _add
.def _add; .scl 2; .type 32; .endef
_add:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %edx
movl 12(%ebp), %eax
addl %edx, %eax
popl %ebp
ret
.def ___main; .scl 2; .type 32; .endef
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $32, %esp
call ___main
movl $1234, 28(%esp)
movl $156, 24(%esp)
movl 24(%esp), %eax
movl %eax, 4(%esp)
movl 28(%esp), %eax
movl %eax, (%esp)
call _add
movl %eax, 20(%esp)
movl $0, %eax
leave
ret
.ident "GCC: (tdm-1) 5.1.0"
此时编译器将pre_asm_test.c
编译成asm_test.s
gcc -c asm_test.s
GCC将对asm_test.s做汇编操作.-c
说明只编译不链接.
此时会生成一个asm_test.o
的目标文件.
此时编译工作就完成了.
ld
再把asm_test.o链接上就可以生成可执行文件了。