预处理、编译、汇编、链接、启动代码、相关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 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
调试程序用