被忽略的過程
對於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 0; }
預編譯(預處理)
如果編譯過程是一次性完成的話,.i文件只是一個過渡性文件,.i被稱為擴展后的c源碼文件。
詳細內容參考:宏
為什么還叫c源碼文件呢?
因為預處理后,只是宏定義等東西不見了,但是C源碼依然還在,比如main函數,各種自己寫的子函數,依然存在,所以還是被稱為c源碼文件。打開.i文件后,我們是能夠看的懂的,所以.i文件時ascii文件。
test.i

1 # 1 "test.c" 2 # 1 "<built-in>" 3 # 1 "<command-line>" 4 # 1 "test.c" 5 # 1 "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdio.h" 1 3 6 # 19 "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdio.h" 3 7 # 1 "C:/Program Files (x86)/CodeBlocks/MinGW/include/_mingw.h" 1 3 8 # 32 "C:/Program Files (x86)/CodeBlocks/MinGW/include/_mingw.h" 3 9 10 # 33 "C:/Program Files (x86)/CodeBlocks/MinGW/include/_mingw.h" 3 11 # 20 "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdio.h" 2 3 12 13 14 15 16 17 18 # 1 "C:/Program Files (x86)/CodeBlocks/MinGW/lib/gcc/mingw32/4.9.2/include/stddef.h" 1 3 4 19 # 212 "C:/Program Files (x86)/CodeBlocks/MinGW/lib/gcc/mingw32/4.9.2/include/stddef.h" 3 4 20 typedef unsigned int size_t; 21 # 324 "C:/Program Files (x86)/CodeBlocks/MinGW/lib/gcc/mingw32/4.9.2/include/stddef.h" 3 4 22 typedef short unsigned int wchar_t; 23 # 353 "C:/Program Files (x86)/CodeBlocks/MinGW/lib/gcc/mingw32/4.9.2/include/stddef.h" 3 4 24 typedef short unsigned int wint_t; 25 # 27 "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdio.h" 2 3 26 27 # 1 "C:/Program Files (x86)/CodeBlocks/MinGW/lib/gcc/mingw32/4.9.2/include/stdarg.h" 1 3 4 28 # 40 "C:/Program Files (x86)/CodeBlocks/MinGW/lib/gcc/mingw32/4.9.2/include/stdarg.h" 3 4 29 typedef __builtin_va_list __gnuc_va_list; 30 # 29 "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdio.h" 2 3 31 # 129 "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdio.h" 3 32 typedef struct _iobuf 33 { 34 char* _ptr; 35 int _cnt; 36 char* _base; 37 int _flag; 38 int _file; 39 int _charbuf; 40 int _bufsiz; 41 char* _tmpfname; 42 } FILE; 43 # 154 "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdio.h" 3 44 extern __attribute__ ((__dllimport__)) FILE _iob[]; 45 # 169 "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdio.h" 3 46 FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fopen (const char*, const char*); 47 FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) freopen (const char*, const char*, FILE*); 48 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fflush (FILE*); 49 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fclose (FILE*); 50 51 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) remove (const char*); 52 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) rename (const char*, const char*); 53 FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) tmpfile (void); 54 char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) tmpnam (char*); 55 56 57 char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _tempnam (const char*, const char*); 58 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _rmtmp(void); 59 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _unlink (const char*); 60 61 62 char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) tempnam (const char*, const char*); 63 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) rmtmp(void); 64 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) unlink (const char*); 65 66 67 68 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) setvbuf (FILE*, char*, int, size_t); 69 70 void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) setbuf (FILE*, char*); 71 # 204 "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdio.h" 3 72 extern int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __mingw_fprintf(FILE*, const char*, ...); 73 extern int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __mingw_printf(const char*, ...); 74 extern int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __mingw_sprintf(char*, const char*, ...); 75 extern int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __mingw_snprintf(char*, size_t, const char*, ...); 76 extern int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __mingw_vfprintf(FILE*, const char*, __gnuc_va_list); 77 extern int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __mingw_vprintf(const char*, __gnuc_va_list); 78 extern int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __mingw_vsprintf(char*, const char*, __gnuc_va_list); 79 extern int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __mingw_vsnprintf(char*, size_t, const char*, __gnuc_va_list); 80 # 293 "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdio.h" 3 81 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fprintf (FILE*, const char*, ...); 82 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) printf (const char*, ...); 83 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) sprintf (char*, const char*, ...); 84 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vfprintf (FILE*, const char*, __gnuc_va_list); 85 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vprintf (const char*, __gnuc_va_list); 86 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vsprintf (char*, const char*, __gnuc_va_list); 87 # 308 "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdio.h" 3 88 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __msvcrt_fprintf(FILE*, const char*, ...); 89 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __msvcrt_printf(const char*, ...); 90 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __msvcrt_sprintf(char*, const char*, ...); 91 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __msvcrt_vfprintf(FILE*, const char*, __gnuc_va_list); 92 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __msvcrt_vprintf(const char*, __gnuc_va_list); 93 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __msvcrt_vsprintf(char*, const char*, __gnuc_va_list); 94 95 96 97 98 99 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _snprintf (char*, size_t, const char*, ...); 100 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _vsnprintf (char*, size_t, const char*, __gnuc_va_list); 101 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _vscprintf (const char*, __gnuc_va_list); 102 # 331 "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdio.h" 3 103 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) snprintf (char *, size_t, const char *, ...); 104 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vsnprintf (char *, size_t, const char *, __gnuc_va_list); 105 106 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vscanf (const char * __restrict__, __gnuc_va_list); 107 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vfscanf (FILE * __restrict__, const char * __restrict__, 108 __gnuc_va_list); 109 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vsscanf (const char * __restrict__, 110 const char * __restrict__, __gnuc_va_list); 111 112 113 114 115 116 117 118 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fscanf (FILE*, const char*, ...); 119 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) scanf (const char*, ...); 120 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) sscanf (const char*, const char*, ...); 121 122 123 124 125 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fgetc (FILE*); 126 char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fgets (char*, int, FILE*); 127 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fputc (int, FILE*); 128 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fputs (const char*, FILE*); 129 char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) gets (char*); 130 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) puts (const char*); 131 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) ungetc (int, FILE*); 132 133 134 135 136 137 138 139 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _filbuf (FILE*); 140 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _flsbuf (int, FILE*); 141 142 143 144 extern __inline__ int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) getc (FILE* __F) 145 { 146 return (--__F->_cnt >= 0) 147 ? (int) (unsigned char) *__F->_ptr++ 148 : _filbuf (__F); 149 } 150 151 extern __inline__ int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) putc (int __c, FILE* __F) 152 { 153 return (--__F->_cnt >= 0) 154 ? (int) (unsigned char) (*__F->_ptr++ = (char)__c) 155 : _flsbuf (__c, __F); 156 } 157 158 extern __inline__ int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) getchar (void) 159 { 160 return (--(&_iob[0])->_cnt >= 0) 161 ? (int) (unsigned char) *(&_iob[0])->_ptr++ 162 : _filbuf ((&_iob[0])); 163 } 164 165 extern __inline__ int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) putchar(int __c) 166 { 167 return (--(&_iob[1])->_cnt >= 0) 168 ? (int) (unsigned char) (*(&_iob[1])->_ptr++ = (char)__c) 169 : _flsbuf (__c, (&_iob[1]));} 170 # 412 "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdio.h" 3 171 size_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fread (void*, size_t, size_t, FILE*); 172 size_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fwrite (const void*, size_t, size_t, FILE*); 173 174 175 176 177 178 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fseek (FILE*, long, int); 179 long __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) ftell (FILE*); 180 void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) rewind (FILE*); 181 # 455 "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdio.h" 3 182 typedef long long fpos_t; 183 184 185 186 187 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fgetpos (FILE*, fpos_t*); 188 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fsetpos (FILE*, const fpos_t*); 189 190 191 192 193 194 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) feof (FILE*); 195 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) ferror (FILE*); 196 # 480 "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdio.h" 3 197 void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) clearerr (FILE*); 198 void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) perror (const char*); 199 200 201 202 203 204 205 FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _popen (const char*, const char*); 206 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _pclose (FILE*); 207 208 209 FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) popen (const char*, const char*); 210 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) pclose (FILE*); 211 212 213 214 215 216 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _flushall (void); 217 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _fgetchar (void); 218 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _fputchar (int); 219 FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _fdopen (int, const char*); 220 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _fileno (FILE*); 221 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _fcloseall (void); 222 FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _fsopen (const char*, const char*, int); 223 224 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _getmaxstdio (void); 225 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _setmaxstdio (int); 226 # 522 "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdio.h" 3 227 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fgetchar (void); 228 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fputchar (int); 229 FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fdopen (int, const char*); 230 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fileno (FILE*); 231 # 534 "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdio.h" 3 232 # 1 "C:/Program Files (x86)/CodeBlocks/MinGW/include/sys/types.h" 1 3 233 # 21 "C:/Program Files (x86)/CodeBlocks/MinGW/include/sys/types.h" 3 234 # 1 "C:/Program Files (x86)/CodeBlocks/MinGW/lib/gcc/mingw32/4.9.2/include/stddef.h" 1 3 4 235 # 147 "C:/Program Files (x86)/CodeBlocks/MinGW/lib/gcc/mingw32/4.9.2/include/stddef.h" 3 4 236 typedef int ptrdiff_t; 237 # 22 "C:/Program Files (x86)/CodeBlocks/MinGW/include/sys/types.h" 2 3 238 239 240 241 242 243 typedef long __time32_t; 244 245 246 247 248 typedef long long __time64_t; 249 # 45 "C:/Program Files (x86)/CodeBlocks/MinGW/include/sys/types.h" 3 250 typedef __time32_t time_t; 251 252 253 254 255 256 257 typedef long _off_t; 258 259 260 typedef _off_t off_t; 261 262 263 264 265 266 267 268 typedef unsigned int _dev_t; 269 270 271 272 273 274 typedef _dev_t dev_t; 275 276 277 278 279 280 281 typedef short _ino_t; 282 283 284 typedef _ino_t ino_t; 285 286 287 288 289 290 291 typedef int _pid_t; 292 293 294 typedef _pid_t pid_t; 295 296 297 298 299 300 301 typedef unsigned short _mode_t; 302 303 304 typedef _mode_t mode_t; 305 306 307 308 309 310 311 typedef int _sigset_t; 312 313 314 typedef _sigset_t sigset_t; 315 316 317 318 319 320 typedef int _ssize_t; 321 322 323 typedef _ssize_t ssize_t; 324 325 326 327 328 329 typedef long long fpos64_t; 330 331 332 333 334 typedef long long off64_t; 335 336 337 338 typedef unsigned int useconds_t; 339 # 535 "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdio.h" 2 3 340 extern __inline__ FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fopen64 (const char* filename, const char* mode) 341 { 342 return fopen (filename, mode); 343 } 344 345 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fseeko64 (FILE*, off64_t, int); 346 347 348 349 350 351 352 extern __inline__ off64_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) ftello64 (FILE * stream) 353 { 354 fpos_t pos; 355 if (fgetpos(stream, &pos)) 356 return -1LL; 357 else 358 return ((off64_t) pos); 359 } 360 # 563 "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdio.h" 3 361 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fwprintf (FILE*, const wchar_t*, ...); 362 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) wprintf (const wchar_t*, ...); 363 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _snwprintf (wchar_t*, size_t, const wchar_t*, ...); 364 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vfwprintf (FILE*, const wchar_t*, __gnuc_va_list); 365 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vwprintf (const wchar_t*, __gnuc_va_list); 366 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _vsnwprintf (wchar_t*, size_t, const wchar_t*, __gnuc_va_list); 367 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _vscwprintf (const wchar_t*, __gnuc_va_list); 368 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fwscanf (FILE*, const wchar_t*, ...); 369 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) wscanf (const wchar_t*, ...); 370 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) swscanf (const wchar_t*, const wchar_t*, ...); 371 wint_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fgetwc (FILE*); 372 wint_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fputwc (wchar_t, FILE*); 373 wint_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) ungetwc (wchar_t, FILE*); 374 375 376 377 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) swprintf (wchar_t*, const wchar_t*, ...); 378 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vswprintf (wchar_t*, const wchar_t*, __gnuc_va_list); 379 380 381 382 wchar_t* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fgetws (wchar_t*, int, FILE*); 383 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fputws (const wchar_t*, FILE*); 384 wint_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) getwc (FILE*); 385 wint_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) getwchar (void); 386 wchar_t* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _getws (wchar_t*); 387 wint_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) putwc (wint_t, FILE*); 388 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _putws (const wchar_t*); 389 wint_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) putwchar (wint_t); 390 FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wfdopen(int, const wchar_t *); 391 FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wfopen (const wchar_t*, const wchar_t*); 392 FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wfreopen (const wchar_t*, const wchar_t*, FILE*); 393 FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wfsopen (const wchar_t*, const wchar_t*, int); 394 wchar_t* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wtmpnam (wchar_t*); 395 wchar_t* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wtempnam (const wchar_t*, const wchar_t*); 396 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wrename (const wchar_t*, const wchar_t*); 397 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wremove (const wchar_t*); 398 void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wperror (const wchar_t*); 399 FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wpopen (const wchar_t*, const wchar_t*); 400 401 402 403 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) snwprintf (wchar_t* s, size_t n, const wchar_t* format, ...); 404 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vsnwprintf (wchar_t* s, size_t n, const wchar_t* format, __gnuc_va_list arg); 405 406 407 408 409 410 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vwscanf (const wchar_t * __restrict__, __gnuc_va_list); 411 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vfwscanf (FILE * __restrict__, 412 const wchar_t * __restrict__, __gnuc_va_list); 413 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) vswscanf (const wchar_t * __restrict__, 414 const wchar_t * __restrict__, __gnuc_va_list); 415 # 625 "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdio.h" 3 416 FILE* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) wpopen (const wchar_t*, const wchar_t*); 417 418 419 420 421 422 423 wint_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _fgetwchar (void); 424 wint_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _fputwchar (wint_t); 425 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _getw (FILE*); 426 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _putw (int, FILE*); 427 428 429 wint_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fgetwchar (void); 430 wint_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fputwchar (wint_t); 431 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) getw (FILE*); 432 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) putw (int, FILE*); 433 # 2 "test.c" 2 434 # 1 "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdlib.h" 1 3 435 # 21 "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdlib.h" 3 436 # 1 "C:/Program Files (x86)/CodeBlocks/MinGW/lib/gcc/mingw32/4.9.2/include/stddef.h" 1 3 4 437 # 22 "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdlib.h" 2 3 438 # 71 "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdlib.h" 3 439 extern int _argc; 440 extern char** _argv; 441 442 443 444 445 extern int* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __p___argc(void); 446 extern char*** __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __p___argv(void); 447 extern wchar_t*** __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __p___wargv(void); 448 # 112 "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdlib.h" 3 449 extern __attribute__ ((__dllimport__)) int __mb_cur_max; 450 # 137 "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdlib.h" 3 451 int* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _errno(void); 452 453 454 int* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __doserrno(void); 455 # 149 "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdlib.h" 3 456 extern char *** __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __p__environ(void); 457 extern wchar_t *** __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __p__wenviron(void); 458 # 172 "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdlib.h" 3 459 extern __attribute__ ((__dllimport__)) int _sys_nerr; 460 # 196 "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdlib.h" 3 461 extern __attribute__ ((__dllimport__)) char* _sys_errlist[]; 462 # 209 "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdlib.h" 3 463 extern unsigned __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) int* __p__osver(void); 464 extern unsigned __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) int* __p__winver(void); 465 extern unsigned __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) int* __p__winmajor(void); 466 extern unsigned __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) int* __p__winminor(void); 467 468 469 470 471 472 473 474 extern __attribute__ ((__dllimport__)) unsigned int _osver; 475 extern __attribute__ ((__dllimport__)) unsigned int _winver; 476 extern __attribute__ ((__dllimport__)) unsigned int _winmajor; 477 extern __attribute__ ((__dllimport__)) unsigned int _winminor; 478 # 260 "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdlib.h" 3 479 char** __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __p__pgmptr(void); 480 481 wchar_t** __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __p__wpgmptr(void); 482 # 293 "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdlib.h" 3 483 extern __attribute__ ((__dllimport__)) int _fmode; 484 # 303 "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdlib.h" 3 485 double __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) atof (const char*); 486 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) atoi (const char*); 487 long __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) atol (const char*); 488 489 double __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wtof (const wchar_t *); 490 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wtoi (const wchar_t *); 491 long __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wtol (const wchar_t *); 492 493 494 double __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) __strtod (const char*, char**); 495 extern double __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) 496 strtod (const char* __restrict__ __nptr, char** __restrict__ __endptr); 497 float __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) strtof (const char * __restrict__, char ** __restrict__); 498 long double __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) strtold (const char * __restrict__, char ** __restrict__); 499 500 501 502 503 long __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) strtol (const char*, char**, int); 504 unsigned long __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) strtoul (const char*, char**, int); 505 506 507 508 long __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) wcstol (const wchar_t*, wchar_t**, int); 509 unsigned long __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) wcstoul (const wchar_t*, wchar_t**, int); 510 double __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) wcstod (const wchar_t*, wchar_t**); 511 512 float __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) wcstof( const wchar_t * __restrict__, wchar_t ** __restrict__); 513 long double __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) wcstold (const wchar_t * __restrict__, wchar_t ** __restrict__); 514 515 516 wchar_t* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wgetenv(const wchar_t*); 517 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wputenv(const wchar_t*); 518 void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wsearchenv(const wchar_t*, const wchar_t*, wchar_t*); 519 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wsystem(const wchar_t*); 520 void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wmakepath(wchar_t*, const wchar_t*, const wchar_t*, const wchar_t*, const wchar_t*); 521 void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wsplitpath (const wchar_t*, wchar_t*, wchar_t*, wchar_t*, wchar_t*); 522 wchar_t* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wfullpath (wchar_t*, const wchar_t*, size_t); 523 524 525 526 527 size_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) wcstombs (char*, const wchar_t*, size_t); 528 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) wctomb (char*, wchar_t); 529 530 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) mblen (const char*, size_t); 531 size_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) mbstowcs (wchar_t*, const char*, size_t); 532 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) mbtowc (wchar_t*, const char*, size_t); 533 534 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) rand (void); 535 void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) srand (unsigned int); 536 537 void* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) calloc (size_t, size_t) __attribute__ ((__malloc__)); 538 void* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) malloc (size_t) __attribute__ ((__malloc__)); 539 void* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) realloc (void*, size_t); 540 void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) free (void*); 541 void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) abort (void) __attribute__ ((__noreturn__)); 542 void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) exit (int) __attribute__ ((__noreturn__)); 543 544 545 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) atexit (void (*)(void)); 546 547 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) system (const char*); 548 char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) getenv (const char*); 549 550 551 void* __attribute__((__cdecl__)) bsearch (const void*, const void*, size_t, size_t, 552 int (*)(const void*, const void*)); 553 void __attribute__((__cdecl__)) qsort(void*, size_t, size_t, 554 int (*)(const void*, const void*)); 555 556 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) abs (int) __attribute__ ((__const__)); 557 long __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) labs (long) __attribute__ ((__const__)); 558 # 385 "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdlib.h" 3 559 typedef struct { int quot, rem; } div_t; 560 typedef struct { long quot, rem; } ldiv_t; 561 562 div_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) div (int, int) __attribute__ ((__const__)); 563 ldiv_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) ldiv (long, long) __attribute__ ((__const__)); 564 565 566 567 568 569 570 571 void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _beep (unsigned int, unsigned int) __attribute__ ((__deprecated__)); 572 573 void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _seterrormode (int) __attribute__ ((__deprecated__)); 574 void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _sleep (unsigned long) __attribute__ ((__deprecated__)); 575 576 void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _exit (int) __attribute__ ((__noreturn__)); 577 578 579 580 typedef int (* _onexit_t)(void); 581 _onexit_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _onexit( _onexit_t ); 582 583 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _putenv (const char*); 584 void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _searchenv (const char*, const char*, char*); 585 586 char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _ecvt (double, int, int*, int*); 587 char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _fcvt (double, int, int*, int*); 588 char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _gcvt (double, int, char*); 589 590 void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _makepath (char*, const char*, const char*, const char*, const char*); 591 void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _splitpath (const char*, char*, char*, char*, char*); 592 char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _fullpath (char*, const char*, size_t); 593 594 char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _itoa (int, char*, int); 595 char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _ltoa (long, char*, int); 596 char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _ultoa(unsigned long, char*, int); 597 wchar_t* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _itow (int, wchar_t*, int); 598 wchar_t* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _ltow (long, wchar_t*, int); 599 wchar_t* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _ultow (unsigned long, wchar_t*, int); 600 601 602 long long __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _atoi64(const char *); 603 char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _i64toa(long long, char *, int); 604 char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _ui64toa(unsigned long long, char *, int); 605 long long __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _wtoi64(const wchar_t *); 606 wchar_t* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _i64tow(long long, wchar_t *, int); 607 wchar_t* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _ui64tow(unsigned long long, wchar_t *, int); 608 609 unsigned int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) (_rotl)(unsigned int, int) __attribute__ ((__const__)); 610 unsigned int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) (_rotr)(unsigned int, int) __attribute__ ((__const__)); 611 unsigned long __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) (_lrotl)(unsigned long, int) __attribute__ ((__const__)); 612 unsigned long __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) (_lrotr)(unsigned long, int) __attribute__ ((__const__)); 613 614 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _set_error_mode (int); 615 # 477 "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdlib.h" 3 616 int __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) putenv (const char*); 617 void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) searchenv (const char*, const char*, char*); 618 619 char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) itoa (int, char*, int); 620 char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) ltoa (long, char*, int); 621 622 623 char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) ecvt (double, int, int*, int*); 624 char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) fcvt (double, int, int*, int*); 625 char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) gcvt (double, int, char*); 626 # 497 "C:/Program Files (x86)/CodeBlocks/MinGW/include/stdlib.h" 3 627 void __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) _Exit(int) __attribute__ ((__noreturn__)); 628 629 630 631 632 633 typedef struct { long long quot, rem; } lldiv_t; 634 635 lldiv_t __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) lldiv (long long, long long) __attribute__ ((__const__)); 636 637 long long __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) llabs(long long); 638 639 640 641 642 643 long long __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) strtoll (const char* __restrict__, char** __restrict, int); 644 unsigned long long __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) strtoull (const char* __restrict__, char** __restrict__, int); 645 646 647 long long __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) atoll (const char *); 648 649 650 long long __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) wtoll (const wchar_t *); 651 char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) lltoa (long long, char *, int); 652 char* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) ulltoa (unsigned long long , char *, int); 653 wchar_t* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) lltow (long long, wchar_t *, int); 654 wchar_t* __attribute__((__cdecl__)) __attribute__ ((__nothrow__)) ulltow (unsigned long long, wchar_t *, int); 655 # 3 "test.c" 2 656 657 658 659 int main() 660 { 661 662 663 664 665 printf("Hello World\n"); 666 return 0; 667 }
注意:
①.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 $-16, %esp subl $16, %esp call ___main movl $LC0, (%esp) call _puts movl $0, %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 1 anaconda-ks.cfg Desktop Downloads hello.c Music p2.c Pictures Python_project test test.o 2 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.6355 0000000000601028 D __data_start 0000000000601028 W data_start 0000000000400460 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 0000000000601030 B _end 00000000004005b4 T _fini 00000000004004f0 t frame_dummy 0000000000600e10 t __frame_dummy_init_array_entry 0000000000400700 r __FRAME_END__ 0000000000601000 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 0000000000400540 T __libc_csu_init U __libc_start_main@@GLIBC_2.2.5 000000000040051d T main U puts@@GLIBC_2.2.5 0000000000400490 t register_tm_clones 0000000000400430 T _start 0000000000601030 D __TMC_END__ [root@localhost ~]# nm test.o 0000000000000000 T main U puts
strip:
對可執行文件進行瘦身
給gcc指定-s選項時,gcc就是調用strip來瘦身的。我們也可以gcc時先不指定-s,然后自己主動使用strip來瘦身。

[root@localhost ~]# ll test -rwxr-xr-x. 1 root root 8440 Aug 2 22:37 test [root@localhost ~]# strip test [root@localhost ~]# ll test -rwxr-xr-x. 1 root root 6296 Aug 2 22:41 test
objdump:
反匯編,將機器指令反翻譯為可以被人識別的匯編指令,這就反匯編。反匯編結果默認輸出到屏幕,可以重定向到文件
對.o文件進行反匯編

[root@localhost ~]# objdump test.o -D test.o: file format elf64-x86-64 Disassembly of section .text: 0000000000000000 <main>: 0: 55 push %rbp 1: 48 89 e5 mov %rsp,%rbp 4: bf 00 00 00 00 mov $0x0,%edi 9: e8 00 00 00 00 callq e <main+0xe> e: b8 00 00 00 00 mov $0x0,%eax 13: 5d pop %rbp 14: c3 retq Disassembly of section .rodata: 0000000000000000 <.rodata>: 0: 48 rex.W 1: 65 6c gs insb (%dx),%es:(%rdi) 3: 6c insb (%dx),%es:(%rdi) 4: 6f outsl %ds:(%rsi),(%dx) 5: 20 57 6f and %dl,0x6f(%rdi) 8: 72 6c jb 76 <main+0x76> a: 64 fs ... Disassembly of section .comment: 0000000000000000 <.comment>: 0: 00 47 43 add %al,0x43(%rdi) 3: 43 3a 20 rex.XB cmp (%r8),%spl 6: 28 47 4e sub %al,0x4e(%rdi) 9: 55 push %rbp a: 29 20 sub %esp,(%rax) c: 34 2e xor $0x2e,%al e: 38 2e cmp %ch,(%rsi) 10: 35 20 32 30 31 xor $0x31303220,%eax 15: 35 30 36 32 33 xor $0x33323630,%eax 1a: 20 28 and %ch,(%rax) 1c: 52 push %rdx 1d: 65 64 20 48 61 gs and %cl,%fs:0x61(%rax) 22: 74 20 je 44 <main+0x44> 24: 34 2e xor $0x2e,%al 26: 38 2e cmp %ch,(%rsi) 28: 35 2d 32 38 29 xor $0x2938322d,%eax ... Disassembly of section .eh_frame: 0000000000000000 <.eh_frame>: 0: 14 00 adc $0x0,%al 2: 00 00 add %al,(%rax) 4: 00 00 add %al,(%rax) 6: 00 00 add %al,(%rax) 8: 01 7a 52 add %edi,0x52(%rdx) b: 00 01 add %al,(%rcx) d: 78 10 js 1f <.eh_frame+0x1f> f: 01 1b add %ebx,(%rbx) 11: 0c 07 or $0x7,%al 13: 08 90 01 00 00 1c or %dl,0x1c000001(%rax) 19: 00 00 add %al,(%rax) 1b: 00 1c 00 add %bl,(%rax,%rax,1) 1e: 00 00 add %al,(%rax) 20: 00 00 add %al,(%rax) 22: 00 00 add %al,(%rax) 24: 15 00 00 00 00 adc $0x0,%eax 29: 41 0e rex.B (bad) 2b: 10 86 02 43 0d 06 adc %al,0x60d4302(%rsi) 31: 50 push %rax 32: 0c 07 or $0x7,%al 34: 08 00 or %al,(%rax) ... [root@localhost ~]#
對可執行文件進行反匯編

[root@localhost ~]# objdump test -D test: file format elf64-x86-64 Disassembly of section .interp: 0000000000400238 <.interp>: 400238: 2f (bad) 400239: 6c insb (%dx),%es:(%rdi) 40023a: 69 62 36 34 2f 6c 64 imul $0x646c2f34,0x36(%rdx),%esp 400241: 2d 6c 69 6e 75 sub $0x756e696c,%eax 400246: 78 2d js 400275 <puts@plt-0x18b> 400248: 78 38 js 400282 <puts@plt-0x17e> 40024a: 36 2d 36 34 2e 73 ss sub $0x732e3436,%eax 400250: 6f outsl %ds:(%rsi),(%dx) 400251: 2e 32 00 xor %cs:(%rax),%al Disassembly of section .note.ABI-tag: 0000000000400254 <.note.ABI-tag>: 400254: 04 00 add $0x0,%al 400256: 00 00 add %al,(%rax) 400258: 10 00 adc %al,(%rax) 40025a: 00 00 add %al,(%rax) 40025c: 01 00 add %eax,(%rax) 40025e: 00 00 add %al,(%rax) 400260: 47 rex.RXB 400261: 4e 55 rex.WRX push %rbp 400263: 00 00 add %al,(%rax) 400265: 00 00 add %al,(%rax) 400267: 00 02 add %al,(%rdx) 400269: 00 00 add %al,(%rax) 40026b: 00 06 add %al,(%rsi) 40026d: 00 00 add %al,(%rax) 40026f: 00 20 add %ah,(%rax) 400271: 00 00 add %al,(%rax) ... Disassembly of section .note.gnu.build-id: 0000000000400274 <.note.gnu.build-id>: 400274: 04 00 add $0x0,%al 400276: 00 00 add %al,(%rax) 400278: 14 00 adc $0x0,%al 40027a: 00 00 add %al,(%rax) 40027c: 03 00 add (%rax),%eax 40027e: 00 00 add %al,(%rax) 400280: 47 rex.RXB 400281: 4e 55 rex.WRX push %rbp 400283: 00 aa 49 34 c6 e5 add %ch,-0x1a39cbb7(%rdx) 400289: 6a 73 pushq $0x73 40028b: a9 2a ae 51 f5 test $0xf551ae2a,%eax 400290: c3 retq 400291: 9e sahf 400292: dc 41 74 faddl 0x74(%rcx) 400295: 5f pop %rdi 400296: 8c f3 mov %?,%ebx Disassembly of section .gnu.hash: 0000000000400298 <.gnu.hash>: 400298: 01 00 add %eax,(%rax) 40029a: 00 00 add %al,(%rax) 40029c: 01 00 add %eax,(%rax) 40029e: 00 00 add %al,(%rax) 4002a0: 01 00 add %eax,(%rax) ... Disassembly of section .dynsym: 00000000004002b8 <.dynsym>: ... 4002d0: 0b 00 or (%rax),%eax 4002d2: 00 00 add %al,(%rax) 4002d4: 12 00 adc (%rax),%al ... 4002e6: 00 00 add %al,(%rax) 4002e8: 10 00 adc %al,(%rax) 4002ea: 00 00 add %al,(%rax) 4002ec: 12 00 adc (%rax),%al ... 4002fe: 00 00 add %al,(%rax) 400300: 22 00 and (%rax),%al 400302: 00 00 add %al,(%rax) 400304: 20 00 and %al,(%rax) ... Disassembly of section .dynstr: 0000000000400318 <.dynstr>: 400318: 00 6c 69 62 add %ch,0x62(%rcx,%rbp,2) 40031c: 63 2e movslq (%rsi),%ebp 40031e: 73 6f jae 40038f <puts@plt-0x71> 400320: 2e 36 00 70 75 cs add %dh,%ss:0x75(%rax) 400325: 74 73 je 40039a <puts@plt-0x66> 400327: 00 5f 5f add %bl,0x5f(%rdi) 40032a: 6c insb (%dx),%es:(%rdi) 40032b: 69 62 63 5f 73 74 61 imul $0x6174735f,0x63(%rdx),%esp 400332: 72 74 jb 4003a8 <puts@plt-0x58> 400334: 5f pop %rdi 400335: 6d insl (%dx),%es:(%rdi) 400336: 61 (bad) 400337: 69 6e 00 5f 5f 67 6d imul $0x6d675f5f,0x0(%rsi),%ebp 40033e: 6f outsl %ds:(%rsi),(%dx) 40033f: 6e outsb %ds:(%rsi),(%dx) 400340: 5f pop %rdi 400341: 73 74 jae 4003b7 <puts@plt-0x49> 400343: 61 (bad) 400344: 72 74 jb 4003ba <puts@plt-0x46> 400346: 5f pop %rdi 400347: 5f pop %rdi 400348: 00 47 4c add %al,0x4c(%rdi) 40034b: 49 rex.WB 40034c: 42 rex.X 40034d: 43 5f rex.XB pop %r15 40034f: 32 2e xor (%rsi),%ch 400351: 32 2e xor (%rsi),%ch 400353: 35 .byte 0x35 ... Disassembly of section .gnu.version: 0000000000400356 <.gnu.version>: 400356: 00 00 add %al,(%rax) 400358: 02 00 add (%rax),%al 40035a: 02 00 add (%rax),%al ... Disassembly of section .gnu.version_r: 0000000000400360 <.gnu.version_r>: 400360: 01 00 add %eax,(%rax) 400362: 01 00 add %eax,(%rax) 400364: 01 00 add %eax,(%rax) 400366: 00 00 add %al,(%rax) 400368: 10 00 adc %al,(%rax) 40036a: 00 00 add %al,(%rax) 40036c: 00 00 add %al,(%rax) 40036e: 00 00 add %al,(%rax) 400370: 75 1a jne 40038c <puts@plt-0x74> 400372: 69 09 00 00 02 00 imul $0x20000,(%rcx),%ecx 400378: 31 00 xor %eax,(%rax) 40037a: 00 00 add %al,(%rax) 40037c: 00 00 add %al,(%rax) ... Disassembly of section .rela.dyn: 0000000000400380 <.rela.dyn>: 400380: f8 clc 400381: 0f 60 00 punpcklbw (%rax),%mm0 400384: 00 00 add %al,(%rax) 400386: 00 00 add %al,(%rax) 400388: 06 (bad) 400389: 00 00 add %al,(%rax) 40038b: 00 03 add %al,(%rbx) ... Disassembly of section .rela.plt: 0000000000400398 <.rela.plt>: 400398: 18 10 sbb %dl,(%rax) 40039a: 60 (bad) 40039b: 00 00 add %al,(%rax) 40039d: 00 00 add %al,(%rax) 40039f: 00 07 add %al,(%rdi) 4003a1: 00 00 add %al,(%rax) 4003a3: 00 01 add %al,(%rcx) ... 4003ad: 00 00 add %al,(%rax) 4003af: 00 20 add %ah,(%rax) 4003b1: 10 60 00 adc %ah,0x0(%rax) 4003b4: 00 00 add %al,(%rax) 4003b6: 00 00 add %al,(%rax) 4003b8: 07 (bad) 4003b9: 00 00 add %al,(%rax) 4003bb: 00 02 add %al,(%rdx) ... Disassembly of section .init: 00000000004003c8 <.init>: 4003c8: 48 83 ec 08 sub $0x8,%rsp 4003cc: 48 8b 05 25 0c 20 00 mov 0x200c25(%rip),%rax # 600ff8 <__libc_start_main@plt+0x200be8> 4003d3: 48 85 c0 test %rax,%rax 4003d6: 74 05 je 4003dd <puts@plt-0x23> 4003d8: e8 43 00 00 00 callq 400420 <__libc_start_main@plt+0x10> 4003dd: 48 83 c4 08 add $0x8,%rsp 4003e1: c3 retq Disassembly of section .plt: 00000000004003f0 <puts@plt-0x10>: 4003f0: ff 35 12 0c 20 00 pushq 0x200c12(%rip) # 601008 <__libc_start_main@plt+0x200bf8> 4003f6: ff 25 14 0c 20 00 jmpq *0x200c14(%rip) # 601010 <__libc_start_main@plt+0x200c00> 4003fc: 0f 1f 40 00 nopl 0x0(%rax) 0000000000400400 <puts@plt>: 400400: ff 25 12 0c 20 00 jmpq *0x200c12(%rip) # 601018 <__libc_start_main@plt+0x200c08> 400406: 68 00 00 00 00 pushq $0x0 40040b: e9 e0 ff ff ff jmpq 4003f0 <puts@plt-0x10> 0000000000400410 <__libc_start_main@plt>: 400410: ff 25 0a 0c 20 00 jmpq *0x200c0a(%rip) # 601020 <__libc_start_main@plt+0x200c10> 400416: 68 01 00 00 00 pushq $0x1 40041b: e9 d0 ff ff ff jmpq 4003f0 <puts@plt-0x10> Disassembly of section .plt.got: 0000000000400420 <.plt.got>: 400420: ff 25 d2 0b 20 00 jmpq *0x200bd2(%rip) # 600ff8 <__libc_start_main@plt+0x200be8> 400426: 66 90 xchg %ax,%ax Disassembly of section .text: 0000000000400430 <.text>: 400430: 31 ed xor %ebp,%ebp 400432: 49 89 d1 mov %rdx,%r9 400435: 5e pop %rsi 400436: 48 89 e2 mov %rsp,%rdx 400439: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp 40043d: 50 push %rax 40043e: 54 push %rsp 40043f: 49 c7 c0 b0 05 40 00 mov $0x4005b0,%r8 400446: 48 c7 c1 40 05 40 00 mov $0x400540,%rcx 40044d: 48 c7 c7 1d 05 40 00 mov $0x40051d,%rdi 400454: e8 b7 ff ff ff callq 400410 <__libc_start_main@plt> 400459: f4 hlt 40045a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) 400460: b8 37 10 60 00 mov $0x601037,%eax 400465: 55 push %rbp 400466: 48 2d 30 10 60 00 sub $0x601030,%rax 40046c: 48 83 f8 0e cmp $0xe,%rax 400470: 48 89 e5 mov %rsp,%rbp 400473: 77 02 ja 400477 <__libc_start_main@plt+0x67> 400475: 5d pop %rbp 400476: c3 retq 400477: b8 00 00 00 00 mov $0x0,%eax 40047c: 48 85 c0 test %rax,%rax 40047f: 74 f4 je 400475 <__libc_start_main@plt+0x65> 400481: 5d pop %rbp 400482: bf 30 10 60 00 mov $0x601030,%edi 400487: ff e0 jmpq *%rax 400489: 0f 1f 80 00 00 00 00 nopl 0x0(%rax) 400490: b8 30 10 60 00 mov $0x601030,%eax 400495: 55 push %rbp 400496: 48 2d 30 10 60 00 sub $0x601030,%rax 40049c: 48 c1 f8 03 sar $0x3,%rax 4004a0: 48 89 e5 mov %rsp,%rbp 4004a3: 48 89 c2 mov %rax,%rdx 4004a6: 48 c1 ea 3f shr $0x3f,%rdx 4004aa: 48 01 d0 add %rdx,%rax 4004ad: 48 d1 f8 sar %rax 4004b0: 75 02 jne 4004b4 <__libc_start_main@plt+0xa4> 4004b2: 5d pop %rbp 4004b3: c3 retq 4004b4: ba 00 00 00 00 mov $0x0,%edx 4004b9: 48 85 d2 test %rdx,%rdx 4004bc: 74 f4 je 4004b2 <__libc_start_main@plt+0xa2> 4004be: 5d pop %rbp 4004bf: 48 89 c6 mov %rax,%rsi 4004c2: bf 30 10 60 00 mov $0x601030,%edi 4004c7: ff e2 jmpq *%rdx 4004c9: 0f 1f 80 00 00 00 00 nopl 0x0(%rax) 4004d0: 80 3d 55 0b 20 00 00 cmpb $0x0,0x200b55(%rip) # 60102c <__libc_start_main@plt+0x200c1c> 4004d7: 75 11 jne 4004ea <__libc_start_main@plt+0xda> 4004d9: 55 push %rbp 4004da: 48 89 e5 mov %rsp,%rbp 4004dd: e8 7e ff ff ff callq 400460 <__libc_start_main@plt+0x50> 4004e2: 5d pop %rbp 4004e3: c6 05 42 0b 20 00 01 movb $0x1,0x200b42(%rip) # 60102c <__libc_start_main@plt+0x200c1c> 4004ea: f3 c3 repz retq 4004ec: 0f 1f 40 00 nopl 0x0(%rax) 4004f0: 48 83 3d 28 09 20 00 cmpq $0x0,0x200928(%rip) # 600e20 <__libc_start_main@plt+0x200a10> 4004f7: 00 4004f8: 74 1e je 400518 <__libc_start_main@plt+0x108> 4004fa: b8 00 00 00 00 mov $0x0,%eax 4004ff: 48 85 c0 test %rax,%rax 400502: 74 14 je 400518 <__libc_start_main@plt+0x108> 400504: 55 push %rbp 400505: bf 20 0e 60 00 mov $0x600e20,%edi 40050a: 48 89 e5 mov %rsp,%rbp 40050d: ff d0 callq *%rax 40050f: 5d pop %rbp 400510: e9 7b ff ff ff jmpq 400490 <__libc_start_main@plt+0x80> 400515: 0f 1f 00 nopl (%rax) 400518: e9 73 ff ff ff jmpq 400490 <__libc_start_main@plt+0x80> 40051d: 55 push %rbp 40051e: 48 89 e5 mov %rsp,%rbp 400521: bf d0 05 40 00 mov $0x4005d0,%edi 400526: e8 d5 fe ff ff callq 400400 <puts@plt> 40052b: b8 00 00 00 00 mov $0x0,%eax 400530: 5d pop %rbp 400531: c3 retq 400532: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1) 400539: 00 00 00 40053c: 0f 1f 40 00 nopl 0x0(%rax) 400540: 41 57 push %r15 400542: 41 89 ff mov %edi,%r15d 400545: 41 56 push %r14 400547: 49 89 f6 mov %rsi,%r14 40054a: 41 55 push %r13 40054c: 49 89 d5 mov %rdx,%r13 40054f: 41 54 push %r12 400551: 4c 8d 25 b8 08 20 00 lea 0x2008b8(%rip),%r12 # 600e10 <__libc_start_main@plt+0x200a00> 400558: 55 push %rbp 400559: 48 8d 2d b8 08 20 00 lea 0x2008b8(%rip),%rbp # 600e18 <__libc_start_main@plt+0x200a08> 400560: 53 push %rbx 400561: 4c 29 e5 sub %r12,%rbp 400564: 31 db xor %ebx,%ebx 400566: 48 c1 fd 03 sar $0x3,%rbp 40056a: 48 83 ec 08 sub $0x8,%rsp 40056e: e8 55 fe ff ff callq 4003c8 <puts@plt-0x38> 400573: 48 85 ed test %rbp,%rbp 400576: 74 1e je 400596 <__libc_start_main@plt+0x186> 400578: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1) 40057f: 00 400580: 4c 89 ea mov %r13,%rdx 400583: 4c 89 f6 mov %r14,%rsi 400586: 44 89 ff mov %r15d,%edi 400589: 41 ff 14 dc callq *(%r12,%rbx,8) 40058d: 48 83 c3 01 add $0x1,%rbx 400591: 48 39 eb cmp %rbp,%rbx 400594: 75 ea jne 400580 <__libc_start_main@plt+0x170> 400596: 48 83 c4 08 add $0x8,%rsp 40059a: 5b pop %rbx 40059b: 5d pop %rbp 40059c: 41 5c pop %r12 40059e: 41 5d pop %r13 4005a0: 41 5e pop %r14 4005a2: 41 5f pop %r15 4005a4: c3 retq 4005a5: 90 nop 4005a6: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1) 4005ad: 00 00 00 4005b0: f3 c3 repz retq Disassembly of section .fini: 00000000004005b4 <.fini>: 4005b4: 48 83 ec 08 sub $0x8,%rsp 4005b8: 48 83 c4 08 add $0x8,%rsp 4005bc: c3 retq Disassembly of section .rodata: 00000000004005c0 <.rodata>: 4005c0: 01 00 add %eax,(%rax) 4005c2: 02 00 add (%rax),%al ... 4005d0: 48 rex.W 4005d1: 65 6c gs insb (%dx),%es:(%rdi) 4005d3: 6c insb (%dx),%es:(%rdi) 4005d4: 6f outsl %ds:(%rsi),(%dx) 4005d5: 20 57 6f and %dl,0x6f(%rdi) 4005d8: 72 6c jb 400646 <__libc_start_main@plt+0x236> 4005da: 64 fs ... Disassembly of section .eh_frame_hdr: 00000000004005dc <.eh_frame_hdr>: 4005dc: 01 1b add %ebx,(%rbx) 4005de: 03 3b add (%rbx),%edi 4005e0: 30 00 xor %al,(%rax) 4005e2: 00 00 add %al,(%rax) 4005e4: 05 00 00 00 14 add $0x14000000,%eax 4005e9: fe (bad) 4005ea: ff (bad) 4005eb: ff (bad) 4005ec: 7c 00 jl 4005ee <__libc_start_main@plt+0x1de> 4005ee: 00 00 add %al,(%rax) 4005f0: 54 push %rsp 4005f1: fe (bad) 4005f2: ff (bad) 4005f3: ff 4c 00 00 decl 0x0(%rax,%rax,1) 4005f7: 00 41 ff add %al,-0x1(%rcx) 4005fa: ff (bad) 4005fb: ff a4 00 00 00 64 ff jmpq *-0x9c0000(%rax,%rax,1) 400602: ff (bad) 400603: ff c4 inc %esp 400605: 00 00 add %al,(%rax) 400607: 00 d4 add %dl,%ah 400609: ff (bad) 40060a: ff (bad) 40060b: ff 0c 01 decl (%rcx,%rax,1) ... Disassembly of section .eh_frame: 0000000000400610 <.eh_frame>: 400610: 14 00 adc $0x0,%al 400612: 00 00 add %al,(%rax) 400614: 00 00 add %al,(%rax) 400616: 00 00 add %al,(%rax) 400618: 01 7a 52 add %edi,0x52(%rdx) 40061b: 00 01 add %al,(%rcx) 40061d: 78 10 js 40062f <__libc_start_main@plt+0x21f> 40061f: 01 1b add %ebx,(%rbx) 400621: 0c 07 or $0x7,%al 400623: 08 90 01 07 10 14 or %dl,0x14100701(%rax) 400629: 00 00 add %al,(%rax) 40062b: 00 1c 00 add %bl,(%rax,%rax,1) 40062e: 00 00 add %al,(%rax) 400630: 00 fe add %bh,%dh 400632: ff (bad) 400633: ff 2a ljmp *(%rdx) ... 40063d: 00 00 add %al,(%rax) 40063f: 00 14 00 add %dl,(%rax,%rax,1) 400642: 00 00 add %al,(%rax) 400644: 00 00 add %al,(%rax) 400646: 00 00 add %al,(%rax) 400648: 01 7a 52 add %edi,0x52(%rdx) 40064b: 00 01 add %al,(%rcx) 40064d: 78 10 js 40065f <__libc_start_main@plt+0x24f> 40064f: 01 1b add %ebx,(%rbx) 400651: 0c 07 or $0x7,%al 400653: 08 90 01 00 00 24 or %dl,0x24000001(%rax) 400659: 00 00 add %al,(%rax) 40065b: 00 1c 00 add %bl,(%rax,%rax,1) 40065e: 00 00 add %al,(%rax) 400660: 90 nop 400661: fd std 400662: ff (bad) 400663: ff 30 pushq (%rax) 400665: 00 00 add %al,(%rax) 400667: 00 00 add %al,(%rax) 400669: 0e (bad) 40066a: 10 46 0e adc %al,0xe(%rsi) 40066d: 18 4a 0f sbb %cl,0xf(%rdx) 400670: 0b 77 08 or 0x8(%rdi),%esi 400673: 80 00 3f addb $0x3f,(%rax) 400676: 1a 3b sbb (%rbx),%bh 400678: 2a 33 sub (%rbx),%dh 40067a: 24 22 and $0x22,%al 40067c: 00 00 add %al,(%rax) 40067e: 00 00 add %al,(%rax) 400680: 1c 00 sbb $0x0,%al 400682: 00 00 add %al,(%rax) 400684: 44 00 00 add %r8b,(%rax) 400687: 00 95 fe ff ff 15 add %dl,0x15fffffe(%rbp) 40068d: 00 00 add %al,(%rax) 40068f: 00 00 add %al,(%rax) 400691: 41 0e rex.B (bad) 400693: 10 86 02 43 0d 06 adc %al,0x60d4302(%rsi) 400699: 50 push %rax 40069a: 0c 07 or $0x7,%al 40069c: 08 00 or %al,(%rax) 40069e: 00 00 add %al,(%rax) 4006a0: 44 00 00 add %r8b,(%rax) 4006a3: 00 64 00 00 add %ah,0x0(%rax,%rax,1) 4006a7: 00 98 fe ff ff 65 add %bl,0x65fffffe(%rax) 4006ad: 00 00 add %al,(%rax) 4006af: 00 00 add %al,(%rax) 4006b1: 42 0e rex.X (bad) 4006b3: 10 8f 02 45 0e 18 adc %cl,0x180e4502(%rdi) 4006b9: 8e 03 mov (%rbx),%es 4006bb: 45 0e rex.RB (bad) 4006bd: 20 8d 04 45 0e 28 and %cl,0x280e4504(%rbp) 4006c3: 8c 05 48 0e 30 86 mov %es,-0x79cff1b8(%rip) # ffffffff86701511 <__libc_start_main@plt+0xffffffff86301101> 4006c9: 06 (bad) 4006ca: 48 0e rex.W (bad) 4006cc: 38 83 07 4d 0e 40 cmp %al,0x400e4d07(%rbx) 4006d2: 6c insb (%dx),%es:(%rdi) 4006d3: 0e (bad) 4006d4: 38 41 0e cmp %al,0xe(%rcx) 4006d7: 30 41 0e xor %al,0xe(%rcx) 4006da: 28 42 0e sub %al,0xe(%rdx) 4006dd: 20 42 0e and %al,0xe(%rdx) 4006e0: 18 42 0e sbb %al,0xe(%rdx) 4006e3: 10 42 0e adc %al,0xe(%rdx) 4006e6: 08 00 or %al,(%rax) 4006e8: 14 00 adc $0x0,%al 4006ea: 00 00 add %al,(%rax) 4006ec: ac lods %ds:(%rsi),%al 4006ed: 00 00 add %al,(%rax) 4006ef: 00 c0 add %al,%al 4006f1: fe (bad) 4006f2: ff (bad) 4006f3: ff 02 incl (%rdx) ... Disassembly of section .init_array: 0000000000600e10 <.init_array>: 600e10: f0 04 40 lock add $0x40,%al 600e13: 00 00 add %al,(%rax) 600e15: 00 00 add %al,(%rax) ... Disassembly of section .fini_array: 0000000000600e18 <.fini_array>: 600e18: d0 04 40 rolb (%rax,%rax,2) 600e1b: 00 00 add %al,(%rax) 600e1d: 00 00 add %al,(%rax) ... Disassembly of section .jcr: 0000000000600e20 <.jcr>: ... Disassembly of section .dynamic: 0000000000600e28 <.dynamic>: 600e28: 01 00 add %eax,(%rax) 600e2a: 00 00 add %al,(%rax) 600e2c: 00 00 add %al,(%rax) 600e2e: 00 00 add %al,(%rax) 600e30: 01 00 add %eax,(%rax) 600e32: 00 00 add %al,(%rax) 600e34: 00 00 add %al,(%rax) 600e36: 00 00 add %al,(%rax) 600e38: 0c 00 or $0x0,%al 600e3a: 00 00 add %al,(%rax) 600e3c: 00 00 add %al,(%rax) 600e3e: 00 00 add %al,(%rax) 600e40: c8 03 40 00 enterq $0x4003,$0x0 600e44: 00 00 add %al,(%rax) 600e46: 00 00 add %al,(%rax) 600e48: 0d 00 00 00 00 or $0x0,%eax 600e4d: 00 00 add %al,(%rax) 600e4f: 00 b4 05 40 00 00 00 add %dh,0x40(%rbp,%rax,1) 600e56: 00 00 add %al,(%rax) 600e58: 19 00 sbb %eax,(%rax) 600e5a: 00 00 add %al,(%rax) 600e5c: 00 00 add %al,(%rax) 600e5e: 00 00 add %al,(%rax) 600e60: 10 0e adc %cl,(%rsi) 600e62: 60 (bad) 600e63: 00 00 add %al,(%rax) 600e65: 00 00 add %al,(%rax) 600e67: 00 1b add %bl,(%rbx) 600e69: 00 00 add %al,(%rax) 600e6b: 00 00 add %al,(%rax) 600e6d: 00 00 add %al,(%rax) 600e6f: 00 08 add %cl,(%rax) 600e71: 00 00 add %al,(%rax) 600e73: 00 00 add %al,(%rax) 600e75: 00 00 add %al,(%rax) 600e77: 00 1a add %bl,(%rdx) 600e79: 00 00 add %al,(%rax) 600e7b: 00 00 add %al,(%rax) 600e7d: 00 00 add %al,(%rax) 600e7f: 00 18 add %bl,(%rax) 600e81: 0e (bad) 600e82: 60 (bad) 600e83: 00 00 add %al,(%rax) 600e85: 00 00 add %al,(%rax) 600e87: 00 1c 00 add %bl,(%rax,%rax,1) 600e8a: 00 00 add %al,(%rax) 600e8c: 00 00 add %al,(%rax) 600e8e: 00 00 add %al,(%rax) 600e90: 08 00 or %al,(%rax) 600e92: 00 00 add %al,(%rax) 600e94: 00 00 add %al,(%rax) 600e96: 00 00 add %al,(%rax) 600e98: f5 cmc 600e99: fe (bad) 600e9a: ff 6f 00 ljmp *0x0(%rdi) 600e9d: 00 00 add %al,(%rax) 600e9f: 00 98 02 40 00 00 add %bl,0x4002(%rax) 600ea5: 00 00 add %al,(%rax) 600ea7: 00 05 00 00 00 00 add %al,0x0(%rip) # 600ead <__libc_start_main@plt+0x200a9d> 600ead: 00 00 add %al,(%rax) 600eaf: 00 18 add %bl,(%rax) 600eb1: 03 40 00 add 0x0(%rax),%eax 600eb4: 00 00 add %al,(%rax) 600eb6: 00 00 add %al,(%rax) 600eb8: 06 (bad) 600eb9: 00 00 add %al,(%rax) 600ebb: 00 00 add %al,(%rax) 600ebd: 00 00 add %al,(%rax) 600ebf: 00 b8 02 40 00 00 add %bh,0x4002(%rax) 600ec5: 00 00 add %al,(%rax) 600ec7: 00 0a add %cl,(%rdx) 600ec9: 00 00 add %al,(%rax) 600ecb: 00 00 add %al,(%rax) 600ecd: 00 00 add %al,(%rax) 600ecf: 00 3d 00 00 00 00 add %bh,0x0(%rip) # 600ed5 <__libc_start_main@plt+0x200ac5> 600ed5: 00 00 add %al,(%rax) 600ed7: 00 0b add %cl,(%rbx) 600ed9: 00 00 add %al,(%rax) 600edb: 00 00 add %al,(%rax) 600edd: 00 00 add %al,(%rax) 600edf: 00 18 add %bl,(%rax) 600ee1: 00 00 add %al,(%rax) 600ee3: 00 00 add %al,(%rax) 600ee5: 00 00 add %al,(%rax) 600ee7: 00 15 00 00 00 00 add %dl,0x0(%rip) # 600eed <__libc_start_main@plt+0x200add> ... 600ef5: 00 00 add %al,(%rax) 600ef7: 00 03 add %al,(%rbx) ... 600f01: 10 60 00 adc %ah,0x0(%rax) 600f04: 00 00 add %al,(%rax) 600f06: 00 00 add %al,(%rax) 600f08: 02 00 add (%rax),%al 600f0a: 00 00 add %al,(%rax) 600f0c: 00 00 add %al,(%rax) 600f0e: 00 00 add %al,(%rax) 600f10: 30 00 xor %al,(%rax) 600f12: 00 00 add %al,(%rax) 600f14: 00 00 add %al,(%rax) 600f16: 00 00 add %al,(%rax) 600f18: 14 00 adc $0x0,%al 600f1a: 00 00 add %al,(%rax) 600f1c: 00 00 add %al,(%rax) 600f1e: 00 00 add %al,(%rax) 600f20: 07 (bad) 600f21: 00 00 add %al,(%rax) 600f23: 00 00 add %al,(%rax) 600f25: 00 00 add %al,(%rax) 600f27: 00 17 add %dl,(%rdi) 600f29: 00 00 add %al,(%rax) 600f2b: 00 00 add %al,(%rax) 600f2d: 00 00 add %al,(%rax) 600f2f: 00 98 03 40 00 00 add %bl,0x4003(%rax) 600f35: 00 00 add %al,(%rax) 600f37: 00 07 add %al,(%rdi) 600f39: 00 00 add %al,(%rax) 600f3b: 00 00 add %al,(%rax) 600f3d: 00 00 add %al,(%rax) 600f3f: 00 80 03 40 00 00 add %al,0x4003(%rax) 600f45: 00 00 add %al,(%rax) 600f47: 00 08 add %cl,(%rax) 600f49: 00 00 add %al,(%rax) 600f4b: 00 00 add %al,(%rax) 600f4d: 00 00 add %al,(%rax) 600f4f: 00 18 add %bl,(%rax) 600f51: 00 00 add %al,(%rax) 600f53: 00 00 add %al,(%rax) 600f55: 00 00 add %al,(%rax) 600f57: 00 09 add %cl,(%rcx) 600f59: 00 00 add %al,(%rax) 600f5b: 00 00 add %al,(%rax) 600f5d: 00 00 add %al,(%rax) 600f5f: 00 18 add %bl,(%rax) 600f61: 00 00 add %al,(%rax) 600f63: 00 00 add %al,(%rax) 600f65: 00 00 add %al,(%rax) 600f67: 00 fe add %bh,%dh 600f69: ff (bad) 600f6a: ff 6f 00 ljmp *0x0(%rdi) 600f6d: 00 00 add %al,(%rax) 600f6f: 00 60 03 add %ah,0x3(%rax) 600f72: 40 00 00 add %al,(%rax) 600f75: 00 00 add %al,(%rax) 600f77: 00 ff add %bh,%bh 600f79: ff (bad) 600f7a: ff 6f 00 ljmp *0x0(%rdi) 600f7d: 00 00 add %al,(%rax) 600f7f: 00 01 add %al,(%rcx) 600f81: 00 00 add %al,(%rax) 600f83: 00 00 add %al,(%rax) 600f85: 00 00 add %al,(%rax) 600f87: 00 f0 add %dh,%al 600f89: ff (bad) 600f8a: ff 6f 00 ljmp *0x0(%rdi) 600f8d: 00 00 add %al,(%rax) 600f8f: 00 56 03 add %dl,0x3(%rsi) 600f92: 40 00 00 add %al,(%rax) ... Disassembly of section .got: 0000000000600ff8 <.got>: ... Disassembly of section .got.plt: 0000000000601000 <.got.plt>: 601000: 28 0e sub %cl,(%rsi) 601002: 60 (bad) ... 601017: 00 06 add %al,(%rsi) 601019: 04 40 add $0x40,%al 60101b: 00 00 add %al,(%rax) 60101d: 00 00 add %al,(%rax) 60101f: 00 16 add %dl,(%rsi) 601021: 04 40 add $0x40,%al 601023: 00 00 add %al,(%rax) 601025: 00 00 add %al,(%rax) ... Disassembly of section .data: 0000000000601028 <.data>: 601028: 00 00 add %al,(%rax) ... Disassembly of section .bss: 000000000060102c <.bss>: 60102c: 00 00 add %al,(%rax) ... Disassembly of section .comment: 0000000000000000 <.comment>: 0: 47 rex.RXB 1: 43 rex.XB 2: 43 3a 20 rex.XB cmp (%r8),%spl 5: 28 47 4e sub %al,0x4e(%rdi) 8: 55 push %rbp 9: 29 20 sub %esp,(%rax) b: 34 2e xor $0x2e,%al d: 38 2e cmp %ch,(%rsi) f: 35 20 32 30 31 xor $0x31303220,%eax 14: 35 30 36 32 33 xor $0x33323630,%eax 19: 20 28 and %ch,(%rax) 1b: 52 push %rdx 1c: 65 64 20 48 61 gs and %cl,%fs:0x61(%rax) 21: 74 20 je 43 <puts@plt-0x4003bd> 23: 34 2e xor $0x2e,%al 25: 38 2e cmp %ch,(%rsi) 27: 35 2d 32 38 29 xor $0x2938322d,%eax ... [root@localhost ~]#
反匯編的意義
其實對於做應用程序開發的我們來說,反匯編的意義不大,但是對於做逆向開發的人來說,這就很有意義,因為做逆向開發的人,需要分析二進制的機器指令,但是純二進制的機器指令很難閱讀,所以必須將二進制機器指令反翻譯為ascii的匯編指令,才能閱讀。
ar:
用來制作靜態庫文件
參考:靜態庫 VS 動態庫
readelf:
讀取elf格式信息
參考: 剖析可執行文件ELF組成
debug
調試程序用