预处理、编译、汇编、链接、启动代码、相关command
被忽略的过程
对于C这种编译性语言,我们平时编译时,不管是通过IDE图形界面,还是通过命令行,总感觉编译一下就完成了,然后就得到了针对某OS和某CPU的二进制可执行文件(机器指令的文件)。但是实际上在源码到可执行文件中间隐藏了四个过程,这四个过程被OS默默的处理了。
编译四个过程:预处理、编译、汇编、链接
四个过程中的“编译”,特指其中的某个过程,这四个过程合在一起,我们也统称为编译,所以“编译”二字到底指的是第二个过程,还是全部过程的统称,这个就要看说话的“语境”了。其实统称的“编译”,完整的称法应该叫“编译链接”,只是简称为编译而已。
如果这四个过程是一次性编译完成的,这个四个过程分别会产生相应的文件,只不过中间产生的文件都是过渡性的临时文件,使用完成后就会被删除。
图解编译4过程:
编译并不是一个程序,而是一个集合。常用GCC代表编译器集合,gcc指集合中的gcc程序
四过程总览
实验代码
test.c
#include <stdio.h>
#include <stdlib.h> #define NUM 100 int main()
{
#if 0
printf("Test condition macro\n");
#endif printf("Hello World\n");
return ;
}
预编译(预处理)
如果编译过程是一次性完成的话,.i文件只是一个过渡性文件,.i被称为扩展后的c源码文件。
详细内容参考:宏
为什么还叫c源码文件呢?
因为预处理后,只是宏定义等东西不见了,但是C源码依然还在,比如main函数,各种自己写的子函数,依然存在,所以还是被称为c源码文件。打开.i文件后,我们是能够看的懂的,所以.i文件时ascii文件。
test.i
# "test.c"
# "<built-in>"
# "<command-line>"
# "test.c"
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdio.h"
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdio.h"
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/_mingw.h"
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/_mingw.h" # "C:/Program Files (x86)/CodeBlocks/MinGW/include/_mingw.h"
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdio.h" # "C:/Program Files (x86)/CodeBlocks/MinGW/lib/gcc/mingw32/4.9.2/include/stddef.h"
# "C:/Program Files (x86)/CodeBlocks/MinGW/lib/gcc/mingw32/4.9.2/include/stddef.h"
typedef unsigned int size_t;
# "C:/Program Files (x86)/CodeBlocks/MinGW/lib/gcc/mingw32/4.9.2/include/stddef.h"
typedef short unsigned int wchar_t;
# "C:/Program Files (x86)/CodeBlocks/MinGW/lib/gcc/mingw32/4.9.2/include/stddef.h"
typedef short unsigned int wint_t;
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdio.h" # "C:/Program Files (x86)/CodeBlocks/MinGW/lib/gcc/mingw32/4.9.2/include/stdarg.h"
# "C:/Program Files (x86)/CodeBlocks/MinGW/lib/gcc/mingw32/4.9.2/include/stdarg.h"
typedef __builtin_va_list __gnuc_va_list;
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdio.h"
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdio.h"
typedef struct _iobuf
{
char* _ptr;
int _cnt;
char* _base;
int _flag;
int _file;
int _charbuf;
int _bufsiz;
char* _tmpfname;
} FILE;
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdio.h"
extern __attribute__ ((__dllimport__)) FILE _iob[];
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdio.h"
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*);
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdio.h"
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);
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdio.h"
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);
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdio.h"
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);
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdio.h"
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__ int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) getc (FILE* __F)
{
return (--__F->_cnt >= )
? (int) (unsigned char) *__F->_ptr++
: _filbuf (__F);
} extern __inline__ int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) putc (int __c, FILE* __F)
{
return (--__F->_cnt >= )
? (int) (unsigned char) (*__F->_ptr++ = (char)__c)
: _flsbuf (__c, __F);
} extern __inline__ int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) getchar (void)
{
return (--(&_iob[])->_cnt >= )
? (int) (unsigned char) *(&_iob[])->_ptr++
: _filbuf ((&_iob[]));
} extern __inline__ int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) putchar(int __c)
{
return (--(&_iob[])->_cnt >= )
? (int) (unsigned char) (*(&_iob[])->_ptr++ = (char)__c)
: _flsbuf (__c, (&_iob[]));}
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdio.h"
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*);
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdio.h"
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*);
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdio.h"
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);
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdio.h"
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*);
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdio.h"
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/sys/types.h"
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/sys/types.h"
# "C:/Program Files (x86)/CodeBlocks/MinGW/lib/gcc/mingw32/4.9.2/include/stddef.h"
# "C:/Program Files (x86)/CodeBlocks/MinGW/lib/gcc/mingw32/4.9.2/include/stddef.h"
typedef int ptrdiff_t;
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/sys/types.h" typedef long __time32_t; typedef long long __time64_t;
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/sys/types.h"
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;
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdio.h"
extern __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__ off64_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) ftello64 (FILE * stream)
{
fpos_t pos;
if (fgetpos(stream, &pos))
return -1LL;
else
return ((off64_t) pos);
}
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdio.h"
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);
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdio.h"
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*);
# "test.c"
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdlib.h"
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdlib.h"
# "C:/Program Files (x86)/CodeBlocks/MinGW/lib/gcc/mingw32/4.9.2/include/stddef.h"
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdlib.h"
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdlib.h"
extern int _argc;
extern char** _argv; extern int* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __p___argc(void);
extern char*** __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __p___argv(void);
extern wchar_t*** __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __p___wargv(void);
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdlib.h"
extern __attribute__ ((__dllimport__)) int __mb_cur_max;
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdlib.h"
int* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _errno(void); int* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __doserrno(void);
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdlib.h"
extern char *** __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __p__environ(void);
extern wchar_t *** __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __p__wenviron(void);
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdlib.h"
extern __attribute__ ((__dllimport__)) int _sys_nerr;
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdlib.h"
extern __attribute__ ((__dllimport__)) char* _sys_errlist[];
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdlib.h"
extern unsigned __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) int* __p__osver(void);
extern unsigned __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) int* __p__winver(void);
extern unsigned __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) int* __p__winmajor(void);
extern unsigned __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) int* __p__winminor(void); extern __attribute__ ((__dllimport__)) unsigned int _osver;
extern __attribute__ ((__dllimport__)) unsigned int _winver;
extern __attribute__ ((__dllimport__)) unsigned int _winmajor;
extern __attribute__ ((__dllimport__)) unsigned int _winminor;
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdlib.h"
char** __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __p__pgmptr(void); wchar_t** __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __p__wpgmptr(void);
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdlib.h"
extern __attribute__ ((__dllimport__)) int _fmode;
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdlib.h"
double __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) atof (const char*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) atoi (const char*);
long __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) atol (const char*); double __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wtof (const wchar_t *);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wtoi (const wchar_t *);
long __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wtol (const wchar_t *); double __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __strtod (const char*, char**);
extern double __attribute__((__cdecl__)) __attribute__ ((__nothrow__))
strtod (const char* __restrict__ __nptr, char** __restrict__ __endptr);
float __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) strtof (const char * __restrict__, char ** __restrict__);
long double __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) strtold (const char * __restrict__, char ** __restrict__); long __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) strtol (const char*, char**, int);
unsigned long __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) strtoul (const char*, char**, int); long __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) wcstol (const wchar_t*, wchar_t**, int);
unsigned long __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) wcstoul (const wchar_t*, wchar_t**, int);
double __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) wcstod (const wchar_t*, wchar_t**); float __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) wcstof( const wchar_t * __restrict__, wchar_t ** __restrict__);
long double __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) wcstold (const wchar_t * __restrict__, wchar_t ** __restrict__); wchar_t* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wgetenv(const wchar_t*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wputenv(const wchar_t*);
void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wsearchenv(const wchar_t*, const wchar_t*, wchar_t*);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wsystem(const wchar_t*);
void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wmakepath(wchar_t*, const wchar_t*, const wchar_t*, const wchar_t*, const wchar_t*);
void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wsplitpath (const wchar_t*, wchar_t*, wchar_t*, wchar_t*, wchar_t*);
wchar_t* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wfullpath (wchar_t*, const wchar_t*, size_t); size_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) wcstombs (char*, const wchar_t*, size_t);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) wctomb (char*, wchar_t); int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) mblen (const char*, size_t);
size_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) mbstowcs (wchar_t*, const char*, size_t);
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) mbtowc (wchar_t*, const char*, size_t); int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) rand (void);
void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) srand (unsigned int); void* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) calloc (size_t, size_t) __attribute__ ((__malloc__));
void* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) malloc (size_t) __attribute__ ((__malloc__));
void* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) realloc (void*, size_t);
void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) free (void*);
void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) abort (void) __attribute__ ((__noreturn__));
void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) exit (int) __attribute__ ((__noreturn__)); int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) atexit (void (*)(void)); int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) system (const char*);
char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) getenv (const char*); void* __attribute__((__cdecl__)) bsearch (const void*, const void*, size_t, size_t,
int (*)(const void*, const void*));
void __attribute__((__cdecl__)) qsort(void*, size_t, size_t,
int (*)(const void*, const void*)); int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) abs (int) __attribute__ ((__const__));
long __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) labs (long) __attribute__ ((__const__));
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdlib.h"
typedef struct { int quot, rem; } div_t;
typedef struct { long quot, rem; } ldiv_t; div_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) div (int, int) __attribute__ ((__const__));
ldiv_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) ldiv (long, long) __attribute__ ((__const__)); void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _beep (unsigned int, unsigned int) __attribute__ ((__deprecated__)); void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _seterrormode (int) __attribute__ ((__deprecated__));
void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _sleep (unsigned long) __attribute__ ((__deprecated__)); void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _exit (int) __attribute__ ((__noreturn__)); typedef int (* _onexit_t)(void);
_onexit_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _onexit( _onexit_t ); int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _putenv (const char*);
void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _searchenv (const char*, const char*, char*); char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _ecvt (double, int, int*, int*);
char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _fcvt (double, int, int*, int*);
char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _gcvt (double, int, char*); void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _makepath (char*, const char*, const char*, const char*, const char*);
void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _splitpath (const char*, char*, char*, char*, char*);
char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _fullpath (char*, const char*, size_t); char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _itoa (int, char*, int);
char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _ltoa (long, char*, int);
char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _ultoa(unsigned long, char*, int);
wchar_t* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _itow (int, wchar_t*, int);
wchar_t* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _ltow (long, wchar_t*, int);
wchar_t* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _ultow (unsigned long, wchar_t*, int); long long __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _atoi64(const char *);
char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _i64toa(long long, char *, int);
char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _ui64toa(unsigned long long, char *, int);
long long __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wtoi64(const wchar_t *);
wchar_t* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _i64tow(long long, wchar_t *, int);
wchar_t* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _ui64tow(unsigned long long, wchar_t *, int); unsigned int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) (_rotl)(unsigned int, int) __attribute__ ((__const__));
unsigned int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) (_rotr)(unsigned int, int) __attribute__ ((__const__));
unsigned long __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) (_lrotl)(unsigned long, int) __attribute__ ((__const__));
unsigned long __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) (_lrotr)(unsigned long, int) __attribute__ ((__const__)); int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _set_error_mode (int);
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdlib.h"
int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) putenv (const char*);
void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) searchenv (const char*, const char*, char*); char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) itoa (int, char*, int);
char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) ltoa (long, char*, int); char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) ecvt (double, int, int*, int*);
char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fcvt (double, int, int*, int*);
char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) gcvt (double, int, char*);
# "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdlib.h"
void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _Exit(int) __attribute__ ((__noreturn__)); typedef struct { long long quot, rem; } lldiv_t; lldiv_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) lldiv (long long, long long) __attribute__ ((__const__)); long long __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) llabs(long long); long long __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) strtoll (const char* __restrict__, char** __restrict, int);
unsigned long long __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) strtoull (const char* __restrict__, char** __restrict__, int); long long __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) atoll (const char *); long long __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) wtoll (const wchar_t *);
char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) lltoa (long long, char *, int);
char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) ulltoa (unsigned long long , char *, int);
wchar_t* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) lltow (long long, wchar_t *, int);
wchar_t* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) ulltow (unsigned long long, wchar_t *, int);
# "test.c" int main()
{ printf("Hello World\n");
return ;
}
注意:
①.i文件展开了NUM,同时没有包含printf("Test condition macro\n");这句话。
② 预编译是以单个文件为单位来进行的
a.c ——————> a.i
b.c ——————> b.i
当然**.i的这个名字并不是固定的。可以使用-o参数指定。
预处理做了哪些工作?
①宏替换:将宏替换为真实的宏体,比如 程序性中有使用NUM这个宏,这个宏的定义为#define NUM 100,程序中所有的NUM都会被替换为100。
②包含头文件 将include包含的.h头文件内容,全部复制到.c文件中,因为头文件中定义了类型、宏、函数声明等等,这些都是函数调用会用到的,你调用某个函数时,就必须包含这个函数要的头文件。
疑问:头文件那么多内容,都包含进去的话,不会太多了吗?
编译时,编译器只使用要用的东西,用完后包含的内容都会被丢弃,实际上并不占空间。
③条件编译 处理#if #endif 这类的东西
④处理一些特殊的预处理关键字
编译
.s:汇编文件
test.s
.file "test.i"
.def ___main; .scl 2; .type 32; .endef
.section .rdata,"dr"
LC0:
.ascii "Hello World\0"
.text
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
pushl %ebp
movl %esp, %ebp
andl $-, %esp
subl $, %esp
call ___main
movl $LC0, (%esp)
call _puts
movl $, %eax
leave
ret
.ident "GCC: (tdm-1) 4.9.2"
.def _puts; .scl 2; .type 32; .endef
注意
①与预处理一样,同样也是以单个文件为单位来进行的
②.s是ascii码文件。因为汇编也是人能看懂的文字编码形式,所以.s汇编文件也是ASCII码文件。
编译做了什么
将c语法的c源码,翻译为汇编语法的汇编源码。
汇编
注意
①同样也是以文件为单位来进行的
②.o文件是纯二进制文件。因为.o中放的是纯二进制的机器指令,所以我们打开后看不懂。
汇编做了什么
将ASCII的汇编源码,翻译为能够被CPU执行的机器指令,.o文件中放的就是机器指令。但是.o文件还无法运行,需要链接后才能运行。
链接
链接(连接)做了什么
①将众多的.o合成一个完整的可执行文件。 .o实现相互依赖的,比如a.o中调用的函数,被定义在了b.o中,如果不链接在一起的话,是无法工作的。
②链接时,需要加入额外的启动代码。这个启动代码并不是我们自己写的,main函数是由启动代码调用的,我们的程序是从启动代码开始运行的。参考:剖析gcc -v输出
③链接为一个可执行文件时,需要进行符号解析和地址重定位。参考:静态链接 VS 动态链接
可执行文件命名问题
在windows下,可执行的尾缀时.exe,但是在Linux下,可执行文件没有固定的尾缀。
如果整个C工程就一个.c,最后得到的只有一个.o,此时还需要链接吗,可不可以直接执行呢?
同样的要链接后才能运行,因为链接后才有启动代码和重定位后的地址,否者无法运行。
补充:启动代码
如果排除汇编,C可以说是程序员角度最底层的语言了。C程序员都知道程序的入口时main函数(Windows下编程,像Win32 API那种不算,微软自己搞了一通)。但实际上main函数还不是真正的入口,启动代码才是。在剖析可执行文件ELF组成 一文中,可执行文件的ELF中有个.init节。 init节是由gcc提供的crt1.o、crti.o、crtbegin.o等.o构建而来的。
对于没有OS的情况,eg 单片机。 启动代码需要我们自己写
对于有OS的情况,eg Linux
四过程用到哪些程序
cpp:预处理
cpp helloworld.c -o helloworld.i
o选项用于指定目标文件,表示将预处理后的结果保存到.i文件中。
cc1:编译
其实cc1本身也包含cpp预处理的功能,也就是说可以直接使用cc1将.c——>.s,cc1会完成之前的预处理的功能。
cc1 helloworld.c -o helloworld.s
不过以上命令并不能被成功执行,因为还缺参数,他会提示找不到头文件,至于缺什么参数,我们这里就不关心了。
as:汇编
将汇编源码翻译为纯二进制的机器指令,放到.o文件中
collect2/ld:链接
将所有的.o文件(自己的、编译器提供的)和库(动态库、静态库)链接在一起,得到可以运行的可执行文件。
collect2 和 ld之间的关系?
collect2是对ld进一步封装得到的,这两个都可以用于链接。
实际上我们完全可以自己调用collect2和ld这两个程序(命令)来进行链接,但是链接并不是一件容易的事情,链接的时候需要跟大量的参数和选项,这些参数和选项我们自己并不清楚,所以我们自己调用collect2 和 ld来链接的话,实际上操作起来比较困难。所以链接的话,我们直接使用gcc程序来链接,gcc会自动调用collect2或者ld来链接,并且自动指定需要的各种的选项和参数,我们并不是需要关心。
gcc helloworld.o -o helloworld
或者
gcc helloworld.o (如果不指定可执行文件名字的话,默认为a.exe)
gcc:gcc编译时四个过程自动完成
在codeblock里面,我们可以找到gcc/mingW32-gcc/g++/c++,这几个都能编译c程序。
其中mingW32-gcc是对gcc继续做封装后得到的。
c++/g++是用来编译c++程序的,但是由于c++程序兼容c,所以c++/g++也能编译c程序。
正式因为编译集合中包含了g++,所以我们也能使用codeblocks来写c++程序的,而且codeblocks这个IDE本身好像就是c++写的。
gcc/mingW32-gcc/g++/c++程序的作用?
gcc/mingW32-gcc/g++/c++其实是总的调度程序,它按照需求去调用cpp/cc1/as/collect2/ld等程序,完成对应四个过程。
为什么要一个总的调度程序?
通过前面的讲解知道,虽然我们能够自己调用cpp/cc1/as/collect2/ld来完成四个过程,得到最后的可执行文件,但是存在如下缺点。
①每个阶段的程序名都不一样,不方便记忆。第一阶段叫cpp,第二阶段叫cc1等,不好记忆。
有了gcc这个总调度程序后,不管是哪个阶段,对于我们来说,只需要记住gcc这一个程序即可。你想实现那个阶段,通过gcc即可实现,通过给gcc指定不同的选项,gcc可以自动调用cpp/cc1/as/collect2/ld中所需要的程序来实现对应的过程。
②如果每个阶段都我们自己亲自执行cpp/cc1/as/collect2/ld这些程序来编译的话,速度太慢了。
有了gcc后,虽然可以通过指定选项,分别实现每个过程,但是实际上也可以调用gcc一次性快速完成四个过程,gcc会自动调用cpp/cc1/as/collect2/ld来完成。一次性完成时,中间产生的.i/.s/.o都是临时文件,编译后会被自动删除,这些文件我们并不关心,我们关心的只是最后的可执行文件。使用gcc这个总调度程序,一次性完成所有过程时,编译速度非常快,用起来非常方便。
gcc/mingW32-gcc/g++/c++的各种选项
它们几个的使用方式都是一样的,gcc 编译c++程序需要带上 -lstdc++ 指定使用c++库。
以gcc为例来讲解。
-E
只得到.i的扩展c源文件
演示
gcc -E helloworld.c -o helloworld.i
gcc会自动调用cpp或者cc1来进行预处理。如果不写目标文件,就直接输出到控制台。
- S(大写)
只编译到.s文件
演示
gcc -S helloworld.i -o helloworld.s
gcc会自动调用cc1,将.i编译为.s。如果不写目标文件,会自动保存为同名的.s文件。
疑问:gcc -S helloworld.c -o helloworld.s 可以吗?
可以,gcc自动调用cc1时,cc1先预编译,然后再编译。
- c(小写)
只编译得到.o文件
演示
gcc -c helloworld.s -o helloworld.o
自动调用as进行汇编,将.s中的汇编源码翻译为机器指令,并保存到.o文件中。
gcc -c helloworld.i -o helloworld.o
(a)调用cc1编译得到临时.s
(b)调用as将.s汇编得到.o
gcc -c helloworld.c -o helloworld.o
(a)调用cc1预编译、编译得到临时的.s
(b)调用as将.s汇编得到.o
如果不写目标文件,会自动的保存为同名的.o文件
直接得到可执行文件
gcc helloworld.c **.c -o helloworld.exe
gcc helloworld.i **.i -o helloworld.exe
gcc helloworld.s **.s -o helloworld.exe
gcc helloworld.o **.o -o helloworld.exe
-g
如果要进行debug调试的话,通过指定-g选项,会加入调试信息,没有调试信息是无法进行调试的。
-O0/O1/O2/Os/O3
指定优化级别,O0< O1 < O2 < Os < O3
gcc hellowolrd.c -o helloworld.exe -O3
如果不指定有优化级别的话,默认就是O1级别。
理论上-O3 选项可以生成执行效率最高的代码,但以为着更大的风险。通常, -O1 -O2 选项就可以满足绝大多数的优化要求。如, Nginx 编译就采用-O1
-Wall
gcc hellowolrd.c -o helloworld -Wall
表示编译时将所有的警告信息都显示出来,如果不指定的话,默认只显示重要的警告,不重要的警告就不显示。比如,有一个变量定义了但是没有使用,就是一个不重要的警告。如果指定了-Wall选项,会警告你没有使用,否者不提示这个警告。
警告真的不重要吗?
初学c的时候,老师会告诉你警告没关系,但是在实际开发中警告是不能有的,为什么?对于程序的警告来说,虽然不是“编译链接”严重错误,但是在程序的运行过程中,这些警告可能会演变为威胁程序正常运行的错误,所以警告是程序的隐患,因此在实际开发中,编译时必须将警告排除。
s(小写)
对可执行文件进行瘦身
gcc hellowolrd.c -o helloworld -s
不指定-s时,可执行文件都会包含调试等信息,用以实现程序的调试,但是当程序被调试没有bug后发布时,发布的程序就不再需要这些信息了,指定-s选项后,gcc编译时会对可执行文件进行瘦身,以去掉这些信息。
std
指定编译时遵守的语言标准,c的标准目前有c89、c90、c99、c11
gcc helloworld.c -o helloworld -std=c11 //编译时,按照c11标准来解析c语法格式
语言在发展的过程中,每过一段时间就会修改、增加语法特性,然后重新指定语法标准,编译器在编译时就是按照标准来翻译语言的语法格式,c语言也是这样的。如果gcc时指定某个c标准的话,就会使用该标准来编译,如果不指定的话,就使用gcc默认设置的标准来编译。一般来说,新的标准都是兼容旧标准的,但是反过来就不行,如果你的程序使用了最新标准的语法特性,而在编译时指定的确是旧标准的话,就会编译出错,因为旧标准没有这些新的特性。不过一般来说我们不用关心标准问题,因为我们使用的都是最常见c语法特性,不管哪个标准都是支持的,所以不用指定特定的标准,gcc设置的默认标准就支持。
v(小写)
gcc helloworld.c -o helloworld -v //显示预处理、编译、汇编、链接,所有过程的详细信息。
通过加-v选项,阅读编译过程的详细信息可以知道编译时使用的是as、cc1、collect2、ld这些程序。
疑问:单个过程可以加-v吗?
可以,显示的就是单个过程的详细信息,比如gcc -E helloworld.c -o helloworld.i -v //只显示预处理的详细信息。
参考:剖析gcc -v输出
-pipe
加快编译的速度,节约时间
编译器集合中其他程序
nm、strip、objdump、ar、readelf、debug这程序都在/usr/bin/目录下,可以使用which命令查看所在的目录。
nm:
查看.o、可执行文件中的各种符号
[root@localhost ~]# gcc -c test.c -o test.o
[root@localhost ~]# gcc test.c -o test
[root@localhost ~]# ls
anaconda-ks.cfg Desktop Downloads hello.c Music p2.c Pictures Python_project test test.o
a.out Documents file initial-setup-ks.cfg p1.c p.c Public Templates test.c Videos
[root@localhost ~]# nm test
000000000060102c B __bss_start
000000000060102c b completed.
D __data_start
W data_start
t deregister_tm_clones
00000000004004d0 t __do_global_dtors_aux
0000000000600e18 t __do_global_dtors_aux_fini_array_entry
00000000004005c8 R __dso_handle
0000000000600e28 d _DYNAMIC
000000000060102c D _edata
B _end
00000000004005b4 T _fini
00000000004004f0 t frame_dummy
0000000000600e10 t __frame_dummy_init_array_entry
r __FRAME_END__
d _GLOBAL_OFFSET_TABLE_
w __gmon_start__
00000000004005dc r __GNU_EH_FRAME_HDR
00000000004003c8 T _init
0000000000600e18 t __init_array_end
0000000000600e10 t __init_array_start
00000000004005c0 R _IO_stdin_used
0000000000600e20 d __JCR_END__
0000000000600e20 d __JCR_LIST__
00000000004005b0 T __libc_csu_fini
T __libc_csu_init
U __libc_start_main@@GLIBC_2.2.5
000000000040051d T main
U puts@@GLIBC_2.2.5
t register_tm_clones
T _start
D __TMC_END__
[root@localhost ~]# nm test.o
T main
U puts
strip:
对可执行文件进行瘦身
给gcc指定-s选项时,gcc就是调用strip来瘦身的。我们也可以gcc时先不指定-s,然后自己主动使用strip来瘦身。
[root@localhost ~]# ll test
-rwxr-xr-x. root root Aug : test
[root@localhost ~]# strip test
[root@localhost ~]# ll test
-rwxr-xr-x. root root Aug : test
objdump:
反汇编,将机器指令反翻译为可以被人识别的汇编指令,这就反汇编。反汇编结果默认输出到屏幕,可以重定向到文件
对.o文件进行反汇编
[root@localhost ~]# objdump test.o -D test.o: file format elf64-x86- Disassembly of section .text: <main>:
: push %rbp
: e5 mov %rsp,%rbp
: bf mov $0x0,%edi
: e8 callq e <main+0xe>
e: b8 mov $0x0,%eax
: 5d pop %rbp
: c3 retq Disassembly of section .rodata: <.rodata>:
: rex.W
: 6c gs insb (%dx),%es:(%rdi)
: 6c insb (%dx),%es:(%rdi)
: 6f outsl %ds:(%rsi),(%dx)
: 6f and %dl,0x6f(%rdi)
: 6c jb <main+0x76>
a: fs
... Disassembly of section .comment: <.comment>:
: add %al,0x43(%rdi)
: 3a rex.XB cmp (%r8),%spl
: 4e sub %al,0x4e(%rdi)
: push %rbp
a: sub %esp,(%rax)
c: 2e xor $0x2e,%al
e: 2e cmp %ch,(%rsi)
: xor $0x31303220,%eax
: xor $0x33323630,%eax
1a: and %ch,(%rax)
1c: push %rdx
1d: gs and %cl,%fs:0x61(%rax)
: je <main+0x44>
: 2e xor $0x2e,%al
: 2e cmp %ch,(%rsi)
: 2d xor $0x2938322d,%eax
... Disassembly of section .eh_frame: <.eh_frame>:
: adc $0x0,%al
: add %al,(%rax)
: add %al,(%rax)
: add %al,(%rax)
: 7a add %edi,0x52(%rdx)
b: add %al,(%rcx)
d: js 1f <.eh_frame+0x1f>
f: 1b add %ebx,(%rbx)
: 0c or $0x7,%al
: 1c or %dl,0x1c000001(%rax)
: add %al,(%rax)
1b: 1c add %bl,(%rax,%rax,)
1e: add %al,(%rax)
: add %al,(%rax)
: add %al,(%rax)
: adc $0x0,%eax
: 0e rex.B (bad)
2b: 0d adc %al,0x60d4302(%rsi)
: push %rax
: 0c or $0x7,%al
: or %al,(%rax)
...
[root@localhost ~]#
对可执行文件进行反汇编
[root@localhost ~]# objdump test -D test: file format elf64-x86- Disassembly of section .interp: <.interp>:
: 2f (bad)
: 6c insb (%dx),%es:(%rdi)
40023a: 2f 6c imul $0x646c2f34,0x36(%rdx),%esp
: 2d 6c 6e sub $0x756e696c,%eax
: 2d js <puts@plt-0x18b>
: js <puts@plt-0x17e>
40024a: 2d 2e ss sub $0x732e3436,%eax
: 6f outsl %ds:(%rsi),(%dx)
: 2e xor %cs:(%rax),%al Disassembly of section .note.ABI-tag: <.note.ABI-tag>:
: add $0x0,%al
: add %al,(%rax)
: adc %al,(%rax)
40025a: add %al,(%rax)
40025c: add %eax,(%rax)
40025e: add %al,(%rax)
: rex.RXB
: 4e rex.WRX push %rbp
: add %al,(%rax)
: add %al,(%rax)
: add %al,(%rdx)
: add %al,(%rax)
40026b: add %al,(%rsi)
40026d: add %al,(%rax)
40026f: add %ah,(%rax)
: add %al,(%rax)
... Disassembly of section .note.gnu.build-id: <.note.gnu.build-id>:
: add $0x0,%al
: add %al,(%rax)
: adc $0x0,%al
40027a: add %al,(%rax)
40027c: add (%rax),%eax
40027e: add %al,(%rax)
: rex.RXB
: 4e rex.WRX push %rbp
: aa c6 e5 add %ch,-0x1a39cbb7(%rdx)
: 6a pushq $0x73
40028b: a9 2a ae f5 test $0xf551ae2a,%eax
: c3 retq
: 9e sahf
: dc faddl 0x74(%rcx)
: 5f pop %rdi
: 8c f3 mov %?,%ebx Disassembly of section .gnu.hash: <.gnu.hash>:
: add %eax,(%rax)
40029a: add %al,(%rax)
40029c: add %eax,(%rax)
40029e: add %al,(%rax)
4002a0: add %eax,(%rax)
... Disassembly of section .dynsym: 00000000004002b8 <.dynsym>:
...
4002d0: 0b or (%rax),%eax
4002d2: add %al,(%rax)
4002d4: adc (%rax),%al
...
4002e6: add %al,(%rax)
4002e8: adc %al,(%rax)
4002ea: add %al,(%rax)
4002ec: adc (%rax),%al
...
4002fe: add %al,(%rax)
: and (%rax),%al
: add %al,(%rax)
: and %al,(%rax)
... Disassembly of section .dynstr: <.dynstr>:
: 6c add %ch,0x62(%rcx,%rbp,)
40031c: 2e movslq (%rsi),%ebp
40031e: 6f jae 40038f <puts@plt-0x71>
: 2e cs add %dh,%ss:0x75(%rax)
: je 40039a <puts@plt-0x66>
: 5f 5f add %bl,0x5f(%rdi)
40032a: 6c insb (%dx),%es:(%rdi)
40032b: 5f imul $0x6174735f,0x63(%rdx),%esp
: jb 4003a8 <puts@plt-0x58>
: 5f pop %rdi
: 6d insl (%dx),%es:(%rdi)
: (bad)
: 6e 5f 5f 6d imul $0x6d675f5f,0x0(%rsi),%ebp
40033e: 6f outsl %ds:(%rsi),(%dx)
40033f: 6e outsb %ds:(%rsi),(%dx)
: 5f pop %rdi
: jae 4003b7 <puts@plt-0x49>
: (bad)
: jb 4003ba <puts@plt-0x46>
: 5f pop %rdi
: 5f pop %rdi
: 4c add %al,0x4c(%rdi)
40034b: rex.WB
40034c: rex.X
40034d: 5f rex.XB pop %r15
40034f: 2e xor (%rsi),%ch
: 2e xor (%rsi),%ch
: .byte 0x35
... Disassembly of section .gnu.version: <.gnu.version>:
: add %al,(%rax)
: add (%rax),%al
40035a: add (%rax),%al
... Disassembly of section .gnu.version_r: <.gnu.version_r>:
: add %eax,(%rax)
: add %eax,(%rax)
: add %eax,(%rax)
: add %al,(%rax)
: adc %al,(%rax)
40036a: add %al,(%rax)
40036c: add %al,(%rax)
40036e: add %al,(%rax)
: 1a jne 40038c <puts@plt-0x74>
: imul $0x20000,(%rcx),%ecx
: xor %eax,(%rax)
40037a: add %al,(%rax)
40037c: add %al,(%rax)
... Disassembly of section .rela.dyn: <.rela.dyn>:
: f8 clc
: 0f punpcklbw (%rax),%mm0
: add %al,(%rax)
: add %al,(%rax)
: (bad)
: add %al,(%rax)
40038b: add %al,(%rbx)
... Disassembly of section .rela.plt: <.rela.plt>:
: sbb %dl,(%rax)
40039a: (bad)
40039b: add %al,(%rax)
40039d: add %al,(%rax)
40039f: add %al,(%rdi)
4003a1: add %al,(%rax)
4003a3: add %al,(%rcx)
...
4003ad: add %al,(%rax)
4003af: add %ah,(%rax)
4003b1: adc %ah,0x0(%rax)
4003b4: add %al,(%rax)
4003b6: add %al,(%rax)
4003b8: (bad)
4003b9: add %al,(%rax)
4003bb: add %al,(%rdx)
... Disassembly of section .init: 00000000004003c8 <.init>:
4003c8: ec sub $0x8,%rsp
4003cc: 8b 0c mov 0x200c25(%rip),%rax # 600ff8 <__libc_start_main@plt+0x200be8>
4003d3: c0 test %rax,%rax
4003d6: je 4003dd <puts@plt-0x23>
4003d8: e8 callq <__libc_start_main@plt+0x10>dd: c4 add $0x8,%rsp
4003e1: c3 retq Disassembly of section .plt: 00000000004003f0 <puts@plt-0x10>:
4003f0: ff 0c pushq 0x200c12(%rip) # <__libc_start_main@plt+0x200bf8>
4003f6: ff 0c jmpq *0x200c14(%rip) # <__libc_start_main@plt+0x200c00>
4003fc: 0f 1f nopl 0x0(%rax) <puts@plt>:
: ff 0c jmpq *0x200c12(%rip) # <__libc_start_main@plt+0x200c08>
: pushq $0x0
40040b: e9 e0 ff ff ff jmpq 4003f0 <puts@plt-0x10> <__libc_start_main@plt>:
: ff 0a 0c jmpq *0x200c0a(%rip) # <__libc_start_main@plt+0x200c10>
: pushq $0x1
40041b: e9 d0 ff ff ff jmpq 4003f0 <puts@plt-0x10> Disassembly of section .plt.got: <.plt.got>:
: ff d2 0b jmpq *0x200bd2(%rip) # 600ff8 <__libc_start_main@plt+0x200be8>
: xchg %ax,%ax Disassembly of section .text: <.text>:
: ed xor %ebp,%ebp
: d1 mov %rdx,%r9
: 5e pop %rsi
: e2 mov %rsp,%rdx
: e4 f0 and $0xfffffffffffffff0,%rsp
40043d: push %rax
40043e: push %rsp
40043f: c7 c0 b0 mov $0x4005b0,%r8
: c7 c1 mov $0x400540,%rcx
40044d: c7 c7 1d mov $0x40051d,%rdi
: e8 b7 ff ff ff callq <__libc_start_main@plt>
: f4 hlt
40045a: 0f 1f nopw 0x0(%rax,%rax,)
: b8 mov $0x601037,%eax
: push %rbp
: 2d sub $0x601030,%rax
40046c: f8 0e cmp $0xe,%rax
: e5 mov %rsp,%rbp
: ja <__libc_start_main@plt+0x67>
: 5d pop %rbp
: c3 retq
: b8 mov $0x0,%eax
40047c: c0 test %rax,%rax
40047f: f4 je <__libc_start_main@plt+0x65>
: 5d pop %rbp
: bf mov $0x601030,%edi
: ff e0 jmpq *%rax
: 0f 1f nopl 0x0(%rax)
: b8 mov $0x601030,%eax
: push %rbp
: 2d sub $0x601030,%rax
40049c: c1 f8 sar $0x3,%rax
4004a0: e5 mov %rsp,%rbp
4004a3: c2 mov %rax,%rdx
4004a6: c1 ea 3f shr $0x3f,%rdx
4004aa: d0 add %rdx,%rax
4004ad: d1 f8 sar %rax
4004b0: jne 4004b4 <__libc_start_main@plt+0xa4>
4004b2: 5d pop %rbp
4004b3: c3 retq
4004b4: ba mov $0x0,%edx
4004b9: d2 test %rdx,%rdx
4004bc: f4 je 4004b2 <__libc_start_main@plt+0xa2>
4004be: 5d pop %rbp
4004bf: c6 mov %rax,%rsi
4004c2: bf mov $0x601030,%edi
4004c7: ff e2 jmpq *%rdx
4004c9: 0f 1f nopl 0x0(%rax)
4004d0: 3d 0b cmpb $0x0,0x200b55(%rip) # 60102c <__libc_start_main@plt+0x200c1c>
4004d7: jne 4004ea <__libc_start_main@plt+0xda>
4004d9: push %rbp
4004da: e5 mov %rsp,%rbp
4004dd: e8 7e ff ff ff callq <__libc_start_main@plt+0x50>
4004e2: 5d pop %rbp
4004e3: c6 0b movb $0x1,0x200b42(%rip) # 60102c <__libc_start_main@plt+0x200c1c>
4004ea: f3 c3 repz retq
4004ec: 0f 1f nopl 0x0(%rax)
4004f0: 3d cmpq $0x0,0x200928(%rip) # 600e20 <__libc_start_main@plt+0x200a10>
4004f7:
4004f8: 1e je <__libc_start_main@plt+0x108>
4004fa: b8 mov $0x0,%eax
4004ff: c0 test %rax,%rax
: je <__libc_start_main@plt+0x108>
: push %rbp
: bf 0e mov $0x600e20,%edi
40050a: e5 mov %rsp,%rbp
40050d: ff d0 callq *%rax
40050f: 5d pop %rbp
: e9 7b ff ff ff jmpq <__libc_start_main@plt+0x80>
: 0f 1f nopl (%rax)
: e9 ff ff ff jmpq <__libc_start_main@plt+0x80>
40051d: push %rbp
40051e: e5 mov %rsp,%rbp
: bf d0 mov $0x4005d0,%edi
: e8 d5 fe ff ff callq <puts@plt>
40052b: b8 mov $0x0,%eax
: 5d pop %rbp
: c3 retq
: 2e 0f 1f nopw %cs:0x0(%rax,%rax,)
:
40053c: 0f 1f nopl 0x0(%rax)
: push %r15
: ff mov %edi,%r15d
: push %r14
: f6 mov %rsi,%r14
40054a: push %r13
40054c: d5 mov %rdx,%r13
40054f: push %r12
: 4c 8d b8 lea 0x2008b8(%rip),%r12 # 600e10 <__libc_start_main@plt+0x200a00>
: push %rbp
: 8d 2d b8 lea 0x2008b8(%rip),%rbp # 600e18 <__libc_start_main@plt+0x200a08>
: push %rbx
: 4c e5 sub %r12,%rbp
: db xor %ebx,%ebx
: c1 fd sar $0x3,%rbp
40056a: ec sub $0x8,%rsp
40056e: e8 fe ff ff callq 4003c8 <puts@plt-0x38>
: ed test %rbp,%rbp
: 1e je <__libc_start_main@plt+0x186>
: 0f 1f nopl 0x0(%rax,%rax,)
40057f:
: 4c ea mov %r13,%rdx
: 4c f6 mov %r14,%rsi
: ff mov %r15d,%edi
: ff dc callq *(%r12,%rbx,)
40058d: c3 add $0x1,%rbx
: eb cmp %rbp,%rbx
: ea jne <__libc_start_main@plt+0x170>
: c4 add $0x8,%rsp
40059a: 5b pop %rbx
40059b: 5d pop %rbp
40059c: 5c pop %r12
40059e: 5d pop %r13
4005a0: 5e pop %r14
4005a2: 5f pop %r15
4005a4: c3 retq
4005a5: nop
4005a6: 2e 0f 1f nopw %cs:0x0(%rax,%rax,)
4005ad:
4005b0: f3 c3 repz retq Disassembly of section .fini: 00000000004005b4 <.fini>:
4005b4: ec sub $0x8,%rsp
4005b8: c4 add $0x8,%rsp
4005bc: c3 retq Disassembly of section .rodata: 00000000004005c0 <.rodata>:
4005c0: add %eax,(%rax)
4005c2: add (%rax),%al
...
4005d0: rex.W
4005d1: 6c gs insb (%dx),%es:(%rdi)
4005d3: 6c insb (%dx),%es:(%rdi)
4005d4: 6f outsl %ds:(%rsi),(%dx)
4005d5: 6f and %dl,0x6f(%rdi)
4005d8: 6c jb <__libc_start_main@plt+0x236>
4005da: fs
... Disassembly of section .eh_frame_hdr: 00000000004005dc <.eh_frame_hdr>:
4005dc: 1b add %ebx,(%rbx)
4005de: 3b add (%rbx),%edi
4005e0: xor %al,(%rax)
4005e2: add %al,(%rax)
4005e4: add $0x14000000,%eax
4005e9: fe (bad)
4005ea: ff (bad)
4005eb: ff (bad)
4005ec: 7c jl 4005ee <__libc_start_main@plt+0x1de>
4005ee: add %al,(%rax)
4005f0: push %rsp
4005f1: fe (bad)
4005f2: ff (bad)
4005f3: ff 4c decl 0x0(%rax,%rax,)
4005f7: ff add %al,-0x1(%rcx)
4005fa: ff (bad)
4005fb: ff a4 ff jmpq *-0x9c0000(%rax,%rax,)
: ff (bad)
: ff c4 inc %esp
: add %al,(%rax)
: d4 add %dl,%ah
: ff (bad)
40060a: ff (bad)
40060b: ff 0c decl (%rcx,%rax,)
... Disassembly of section .eh_frame: <.eh_frame>:
: adc $0x0,%al
: add %al,(%rax)
: add %al,(%rax)
: add %al,(%rax)
: 7a add %edi,0x52(%rdx)
40061b: add %al,(%rcx)
40061d: js 40062f <__libc_start_main@plt+0x21f>
40061f: 1b add %ebx,(%rbx)
: 0c or $0x7,%al
: or %dl,0x14100701(%rax)
: add %al,(%rax)
40062b: 1c add %bl,(%rax,%rax,)
40062e: add %al,(%rax)
: fe add %bh,%dh
: ff (bad)
: ff 2a ljmp *(%rdx)
...
40063d: add %al,(%rax)
40063f: add %dl,(%rax,%rax,)
: add %al,(%rax)
: add %al,(%rax)
: add %al,(%rax)
: 7a add %edi,0x52(%rdx)
40064b: add %al,(%rcx)
40064d: js 40065f <__libc_start_main@plt+0x24f>
40064f: 1b add %ebx,(%rbx)
: 0c or $0x7,%al
: or %dl,0x24000001(%rax)
: add %al,(%rax)
40065b: 1c add %bl,(%rax,%rax,)
40065e: add %al,(%rax)
: nop
: fd std
: ff (bad)
: ff pushq (%rax)
: add %al,(%rax)
: add %al,(%rax)
: 0e (bad)
40066a: 0e adc %al,0xe(%rsi)
40066d: 4a 0f sbb %cl,0xf(%rdx)
: 0b or 0x8(%rdi),%esi
: 3f addb $0x3f,(%rax)
: 1a 3b sbb (%rbx),%bh
: 2a sub (%rbx),%dh
40067a: and $0x22,%al
40067c: add %al,(%rax)
40067e: add %al,(%rax)
: 1c sbb $0x0,%al
: add %al,(%rax)
: add %r8b,(%rax)
: fe ff ff add %dl,0x15fffffe(%rbp)
40068d: add %al,(%rax)
40068f: add %al,(%rax)
: 0e rex.B (bad)
: 0d adc %al,0x60d4302(%rsi)
: push %rax
40069a: 0c or $0x7,%al
40069c: or %al,(%rax)
40069e: add %al,(%rax)
4006a0: add %r8b,(%rax)
4006a3: add %ah,0x0(%rax,%rax,)
4006a7: fe ff ff add %bl,0x65fffffe(%rax)
4006ad: add %al,(%rax)
4006af: add %al,(%rax)
4006b1: 0e rex.X (bad)
4006b3: 8f 0e adc %cl,0x180e4502(%rdi)
4006b9: 8e mov (%rbx),%es
4006bb: 0e rex.RB (bad)
4006bd: 8d 0e and %cl,0x280e4504(%rbp)
4006c3: 8c 0e mov %es,-0x79cff1b8(%rip) # ffffffff86701511 <__libc_start_main@plt+0xffffffff86301101>
4006c9: (bad)
4006ca: 0e rex.W (bad)
4006cc: 4d 0e cmp %al,0x400e4d07(%rbx)
4006d2: 6c insb (%dx),%es:(%rdi)
4006d3: 0e (bad)
4006d4: 0e cmp %al,0xe(%rcx)
4006d7: 0e xor %al,0xe(%rcx)
4006da: 0e sub %al,0xe(%rdx)
4006dd: 0e and %al,0xe(%rdx)
4006e0: 0e sbb %al,0xe(%rdx)
4006e3: 0e adc %al,0xe(%rdx)
4006e6: or %al,(%rax)
4006e8: adc $0x0,%al
4006ea: add %al,(%rax)
4006ec: ac lods %ds:(%rsi),%al
4006ed: add %al,(%rax)
4006ef: c0 add %al,%al
4006f1: fe (bad)
4006f2: ff (bad)
4006f3: ff incl (%rdx)
... Disassembly of section .init_array: 0000000000600e10 <.init_array>:
600e10: f0 lock add $0x40,%al
600e13: add %al,(%rax)
600e15: add %al,(%rax)
... Disassembly of section .fini_array: 0000000000600e18 <.fini_array>:
600e18: d0 rolb (%rax,%rax,)
600e1b: add %al,(%rax)
600e1d: add %al,(%rax)
... Disassembly of section .jcr: 0000000000600e20 <.jcr>:
... Disassembly of section .dynamic: 0000000000600e28 <.dynamic>:
600e28: add %eax,(%rax)
600e2a: add %al,(%rax)
600e2c: add %al,(%rax)
600e2e: add %al,(%rax)
600e30: add %eax,(%rax)
600e32: add %al,(%rax)
600e34: add %al,(%rax)
600e36: add %al,(%rax)
600e38: 0c or $0x0,%al
600e3a: add %al,(%rax)
600e3c: add %al,(%rax)
600e3e: add %al,(%rax)
600e40: c8 enterq $0x4003,$0x0
600e44: add %al,(%rax)
600e46: add %al,(%rax)
600e48: 0d or $0x0,%eax
600e4d: add %al,(%rax)
600e4f: b4 add %dh,0x40(%rbp,%rax,)
600e56: add %al,(%rax)
600e58: sbb %eax,(%rax)
600e5a: add %al,(%rax)
600e5c: add %al,(%rax)
600e5e: add %al,(%rax)
600e60: 0e adc %cl,(%rsi)
600e62: (bad)
600e63: add %al,(%rax)
600e65: add %al,(%rax)
600e67: 1b add %bl,(%rbx)
600e69: add %al,(%rax)
600e6b: add %al,(%rax)
600e6d: add %al,(%rax)
600e6f: add %cl,(%rax)
600e71: add %al,(%rax)
600e73: add %al,(%rax)
600e75: add %al,(%rax)
600e77: 1a add %bl,(%rdx)
600e79: add %al,(%rax)
600e7b: add %al,(%rax)
600e7d: add %al,(%rax)
600e7f: add %bl,(%rax)
600e81: 0e (bad)
600e82: (bad)
600e83: add %al,(%rax)
600e85: add %al,(%rax)
600e87: 1c add %bl,(%rax,%rax,)
600e8a: add %al,(%rax)
600e8c: add %al,(%rax)
600e8e: add %al,(%rax)
600e90: or %al,(%rax)
600e92: add %al,(%rax)
600e94: add %al,(%rax)
600e96: add %al,(%rax)
600e98: f5 cmc
600e99: fe (bad)
600e9a: ff 6f ljmp *0x0(%rdi)
600e9d: add %al,(%rax)
600e9f: add %bl,0x4002(%rax)
600ea5: add %al,(%rax)
600ea7: add %al,0x0(%rip) # 600ead <__libc_start_main@plt+0x200a9d>
600ead: add %al,(%rax)
600eaf: add %bl,(%rax)
600eb1: add 0x0(%rax),%eax
600eb4: add %al,(%rax)
600eb6: add %al,(%rax)
600eb8: (bad)
600eb9: add %al,(%rax)
600ebb: add %al,(%rax)
600ebd: add %al,(%rax)
600ebf: b8 add %bh,0x4002(%rax)
600ec5: add %al,(%rax)
600ec7: 0a add %cl,(%rdx)
600ec9: add %al,(%rax)
600ecb: add %al,(%rax)
600ecd: add %al,(%rax)
600ecf: 3d add %bh,0x0(%rip) # 600ed5 <__libc_start_main@plt+0x200ac5>
600ed5: add %al,(%rax)
600ed7: 0b add %cl,(%rbx)
600ed9: add %al,(%rax)
600edb: add %al,(%rax)
600edd: add %al,(%rax)
600edf: add %bl,(%rax)
600ee1: add %al,(%rax)
600ee3: add %al,(%rax)
600ee5: add %al,(%rax)
600ee7: add %dl,0x0(%rip) # 600eed <__libc_start_main@plt+0x200add>
...
600ef5: add %al,(%rax)
600ef7: add %al,(%rbx)
...
600f01: adc %ah,0x0(%rax)
600f04: add %al,(%rax)
600f06: add %al,(%rax)
600f08: add (%rax),%al
600f0a: add %al,(%rax)
600f0c: add %al,(%rax)
600f0e: add %al,(%rax)
600f10: xor %al,(%rax)
600f12: add %al,(%rax)
600f14: add %al,(%rax)
600f16: add %al,(%rax)
600f18: adc $0x0,%al
600f1a: add %al,(%rax)
600f1c: add %al,(%rax)
600f1e: add %al,(%rax)
600f20: (bad)
600f21: add %al,(%rax)
600f23: add %al,(%rax)
600f25: add %al,(%rax)
600f27: add %dl,(%rdi)
600f29: add %al,(%rax)
600f2b: add %al,(%rax)
600f2d: add %al,(%rax)
600f2f: add %bl,0x4003(%rax)
600f35: add %al,(%rax)
600f37: add %al,(%rdi)
600f39: add %al,(%rax)
600f3b: add %al,(%rax)
600f3d: add %al,(%rax)
600f3f: add %al,0x4003(%rax)
600f45: add %al,(%rax)
600f47: add %cl,(%rax)
600f49: add %al,(%rax)
600f4b: add %al,(%rax)
600f4d: add %al,(%rax)
600f4f: add %bl,(%rax)
600f51: add %al,(%rax)
600f53: add %al,(%rax)
600f55: add %al,(%rax)
600f57: add %cl,(%rcx)
600f59: add %al,(%rax)
600f5b: add %al,(%rax)
600f5d: add %al,(%rax)
600f5f: add %bl,(%rax)
600f61: add %al,(%rax)
600f63: add %al,(%rax)
600f65: add %al,(%rax)
600f67: fe add %bh,%dh
600f69: ff (bad)
600f6a: ff 6f ljmp *0x0(%rdi)
600f6d: add %al,(%rax)
600f6f: add %ah,0x3(%rax)
600f72: add %al,(%rax)
600f75: add %al,(%rax)
600f77: ff add %bh,%bh
600f79: ff (bad)
600f7a: ff 6f ljmp *0x0(%rdi)
600f7d: add %al,(%rax)
600f7f: add %al,(%rcx)
600f81: add %al,(%rax)
600f83: add %al,(%rax)
600f85: add %al,(%rax)
600f87: f0 add %dh,%al
600f89: ff (bad)
600f8a: ff 6f ljmp *0x0(%rdi)
600f8d: add %al,(%rax)
600f8f: add %dl,0x3(%rsi)
600f92: add %al,(%rax)
... Disassembly of section .got: 0000000000600ff8 <.got>:
... Disassembly of section .got.plt: <.got.plt>:
: 0e sub %cl,(%rsi)
: (bad)
...
: add %al,(%rsi)
: add $0x40,%al
60101b: add %al,(%rax)
60101d: add %al,(%rax)
60101f: add %dl,(%rsi)
: add $0x40,%al
: add %al,(%rax)
: add %al,(%rax)
... Disassembly of section .data: <.data>:
: add %al,(%rax)
... Disassembly of section .bss: 000000000060102c <.bss>:
60102c: add %al,(%rax)
... Disassembly of section .comment: <.comment>:
: rex.RXB
: rex.XB
: 3a rex.XB cmp (%r8),%spl
: 4e sub %al,0x4e(%rdi)
: push %rbp
: sub %esp,(%rax)
b: 2e xor $0x2e,%al
d: 2e cmp %ch,(%rsi)
f: xor $0x31303220,%eax
: xor $0x33323630,%eax
: and %ch,(%rax)
1b: push %rdx
1c: gs and %cl,%fs:0x61(%rax)
: je <puts@plt-0x4003bd>
: 2e xor $0x2e,%al
: 2e cmp %ch,(%rsi)
: 2d xor $0x2938322d,%eax
...
[root@localhost ~]#
反汇编的意义
其实对于做应用程序开发的我们来说,反汇编的意义不大,但是对于做逆向开发的人来说,这就很有意义,因为做逆向开发的人,需要分析二进制的机器指令,但是纯二进制的机器指令很难阅读,所以必须将二进制机器指令反翻译为ascii的汇编指令,才能阅读。
ar:
用来制作静态库文件
参考:静态库 VS 动态库
readelf:
读取elf格式信息
参考: 剖析可执行文件ELF组成
debug
调试程序用
预处理、编译、汇编、链接、启动代码、相关command的更多相关文章
- C语言预处理 编译 汇编 链接四个阶段
c程序(源代码)转换成可以在硬件上运行的程序(可执行代码),需要进行编译和链接. 编译过程 编译过程又可以分成两个阶段:编译和会汇编. 编译 编译是读取源程序(字符流),对之进行词法和语法的分析,将高 ...
- C/C++程序编译流程(预处理->编译->汇编->链接)
程序的基本流程如图: 1. 预处理 预处理相当于根据预处理指令组装新的C/C++程序.经过预处理,会产生一个没有宏定义,没有条件编译指令,没有特殊符号的输出文件,这个文件的含义同原本的文件无异,只是内 ...
- Linux | GCC如何实现代码编译&&汇编&&链接过程
正文: 每次我们程序员所写的 代码 是给程序员看的呢?还是给电脑看的?其实我们所写的代码只是我们程序员之间交流的一样特殊语言,电脑是看不懂的.那么我们如何实现人机交流呢?这就不得不请出我们我们今天 ...
- gcc 编译 汇编 链接
要想研究使用 gcc, gcc-multilib 这个包是一定要安装的, 它允许通过 -m32 和 -m64 选项来选择生成 32 位或者 64 的 ELF 文件. 我们知道程序的默认起点是 _sta ...
- Linux环境下的编译,链接与库的使用
参考博客: http://www.cnblogs.com/qytan36/archive/2010/05/25/1743955.html http://m.blog.csdn.net/article/ ...
- Linux内核启动代码分析二之开发板相关驱动程序加载分析
Linux内核启动代码分析二之开发板相关驱动程序加载分析 1 从linux开始启动的函数start_kernel开始分析,该函数位于linux-2.6.22/init/main.c start_ke ...
- STM32启动代码分析及其汇编学习-ARM
STM32 启动代码 Author By YuCloud 边看启动文件边学汇编 汇编 see ARM: Assembler User Guide see: https://blog.csdn.net/ ...
- C++生成二级制文件过程(预处理->编译->链接 )
转载请注明出处 Windows下C++编程,通过VC生成工程,编写C++源文件,点运行,代码没问题直接出结果.VC什么都帮我们搞了,不了解其中过程也完全没问题. 转到linux下写c++,总觉得有点虚 ...
- GCC编译和链接多个文件(包括源文件、目标文件、汇编文件等)
编译多个源代码文件会生成多个目标文件,每个目标文件都包含一个源文件的机器码和相关数据的符号表.除非使用-c选项指示 GCC 只编译不链接,否则 GCC 会使用临时文件作为目标文件输出: $ gcc - ...
随机推荐
- MapReduce\Tez\Storm\Spark四个框架的异同
1) MapReduce:是一种离线计算框架,将一个算法抽象成Map和Reduce两个阶段进行 处理,非常适合数据密集型计算. 2) Spark:MapReduce计算框架不适合迭代计算和交互式计算, ...
- elk收集tomcat日志
1.elk收集tomcat普通日志: 只在logstash节点增加如下文件,重启logstash即可: cat >>/home/logstash-6.3.0/config/tomcat_t ...
- iOS——使用FMDB进行数据库操作(转载)
iOS 使用FMDB进行数据库操作 https://github.com/ccgus/fmdb [摘要]本文介绍iOS 使用FMDB进行数据库操作,并提供详细的示例代码供参考. FMDB 使用方法 A ...
- Egret入门学习日记 --- 第九篇(书中 2.7~2.8节 内容)
第九篇(书中 2.7~2.8节 内容) 昨天记录到了 2.6节 ,那么今天就从 2.7节 开始. 这个 2.7节 有7个小段,有点长,总结一下重点: 1.调试项目的两种方法. 2.运行项目的两种窗口选 ...
- C#使用Castle实现AOP面向切面编程
Castle.Core 本质是创建继承原来类的代理类,重写虚方法实现AOP功能.个人觉得比Autofac用着爽 使用方式比较简单,先新建一个控制台项目,然后在Nuget上搜索Castle.Core并安 ...
- golang json解析到map中
package main import ( "fmt" "encoding/json" ) type ItemMessage struct { ItemType ...
- leetCode:reverseInteger 反向整数 【JAVA实现】
反向整数 给定一个 32 位有符号整数,将整数中的数字进行反转,如果超出整数的最大或者最小范围返回0 更多文章查看个人博客 个人博客地址:反向整数 方法一 利用StringBuilder的revers ...
- [转帖]【JVM 知识体系框架总结】
[JVM 知识体系框架总结] https://www.cnblogs.com/mousycoder/p/11612448.html JVM 内存分布 线程共享数据区:方法区->类信息,静态变量堆 ...
- C++中const关键字用法总结
看完了c++ primer的基础篇,对const还是有点陌生,在这里小小地总结一下吧. 1) const与变量 在变量的定义前加上 const 修饰符即可完成const对象的创建. const int ...
- PAT(B) 1005 继续(3n+1)猜想(Java)
题目链接:1005 继续(3n+1)猜想 分析 找出所有的被"覆盖"的数,然后再将输入的数中不在被"覆盖"的数中的数添加到"关健数"中.输 ...