Linux下的C编程(一)你好 世界

第一个程序

hello world“出自祖师爷那本K&R、它是所有程序员的必敲代码,我的第一个程序是用vc++6.0敲得hello world,当时什么也不懂,胡乱照着敲,error比行数都多,真是嘤嘤嘤了;

hello world包含的意义也绝不仅仅是这短短6行这么简单;

#include <stdio.h>
int main(void)
{
printf("Hello world!\n");
return 0;
}
return 0

这六行存在争议的就是第五行了,为什么要返回0?为什么不是一二三四五六七八九?

这里就不得不提到一个shell命令了

#echo $?

查看上一步执行任务是否成功
如果为0则代表成功、如果不为0表示失败。
比如执行一个不存在的命令

#haha

在这里插入图片描述
返回的是127;
执行hello
在这里插入图片描述
返回的是0,当然,这个0是我自己在hello.c源程序中写的
如果把源程第五行序改为return 127呢?

在这里插入图片描述
编译执行:
在这里插入图片描述
可以看到程序明明运行成功了,但是返回的却不是0,这就可以理解了,返回值是程序员自己设定的、而Linux的程序都是约定认为返回0代表程序运行成功的。

在/usr/include/stdlib.h可以看到这样的宏
在这里插入图片描述
定义了0 为成功的退出状态。
主函数也可以不用返回值,网上说会由垃圾值,所以我删掉返回重新编译了,执行了十次左右,未见垃圾值:
在这里插入图片描述
所以,即使写了int main(),主函数也可以不返回值。

一个程序从无到有再到运行它过程往往需要如下几步:编辑编译(预处理、翻译、汇编、链接。最终生成二进制目标文件)、运行

windows下都习惯了靠编译器为我们除了编码意外做所有的事情,到了Linux环境如何更好的了解程序编辑、编译、运行的机制呢?

let‘s go

编辑

使用vim新建hello.c文件

#vim hello.c

插入hello world代码
在这里插入图片描述

编译之 预处理

预处理器是编译过程中单独执行的第一个步骤。使用#include的行在编译的第一个阶段被替换成了所包含的文件,其中”“和<>的区别:”“在源文件所在位置找,如果找不到就去系统目录中查找,而<>直接到系统目录下查找头文件。

由于hello 程序过于短小精悍,所以往往手动使用gcc编译即可了,但是,对于平时编程来说,一个工程往往有很多的源文件、头文件,手动敲就变得耗时耗力且出错率低,所以,编写makefile文件变得十分必要了。

在当前文件夹中新建makefile文件

#vim makefile

由于需要得到预处理文件,所以插入一个规则,并重定向到一个.i文件中去

inc:
	gcc -E hello.c>hello.i

在这里插入图片描述

make
#make inc
查看下当前目录文件
#ls

在这里插入图片描述

查看.i文件
#cat hello.i

在这里插入图片描述
文件中果然包含了其他内容,这就是include的内容,所以,第一个步骤预处理完成。

编译之 翻译

这个阶段编译器将预处理过的文本翻译成汇编程序hello.s

将这个步骤添加到makefile

exc:
	gcc -S hello.i -o hello.s
执行
#make exc
查看下这个翻译出来的文件
	.file	"hello.c"
	.text
	.section	.rodata
.LC0:
	.string	"Hello world!"
	.text
	.globl	main
	.type	main, @function
main:
.LFB0:
	.cfi_startproc
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register 6
	leaq	.LC0(%rip), %rdi
	call	puts@PLT
	movl	$0, %eax
	popq	%rbp
	.cfi_def_cfa 7, 8
	ret
	.cfi_endproc
.LFE0:
	.size	main, .-main
	.ident	"GCC: (Debian 8.3.0-6) 8.3.0"
	.section	.note.GNU-stack,"",@progbits
编译之 汇编

makefile中加入

asm:
	gcc -c hello.s -o hello.o

执行make

#make asm

如果想要查看这个编译出来的.o文件,也很方便,Linux提供了readelf程序来查看二进制文件,因为此时这个.o文件是汇编编译出来的,距离可执行文件只差一步链接啦,所以使用readelf也可以打开;

#readelf -a hello.o

其内容为:

ELF 头:
  Magic:  7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  类别:                              ELF64
  数据:                              2 补码,小端序 (little endian)
  版本:                              1 (current)
  OS/ABI:                            UNIX - System V
  ABI 版本:                          0
  类型:                              REL (可重定位文件)
  系统架构:                          Advanced Micro Devices X86-64
  版本:                              0x1
  入口点地址:              0x0
  程序头起点:              0 (bytes into file)
  Start of section headers:          704 (bytes into file)
  标志:             0x0
  本头的大小:       64 (字节)
  程序头大小:       0 (字节)
  Number of program headers:         0
  节头大小:         64 (字节)
  节头数量:         13
  字符串表索引节头: 12

节头:
  [号] 名称              类型             地址              偏移量
       大小              全体大小          旗标   链接   信息   对齐
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .text             PROGBITS         0000000000000000  00000040
       0000000000000017  0000000000000000  AX       0     0     1
  [ 2] .rela.text        RELA             0000000000000000  00000210
       0000000000000030  0000000000000018   I      10     1     8
  [ 3] .data             PROGBITS         0000000000000000  00000057
       0000000000000000  0000000000000000  WA       0     0     1
  [ 4] .bss              NOBITS           0000000000000000  00000057
       0000000000000000  0000000000000000  WA       0     0     1
  [ 5] .rodata           PROGBITS         0000000000000000  00000057
       000000000000000d  0000000000000000   A       0     0     1
  [ 6] .comment          PROGBITS         0000000000000000  00000064
       000000000000001d  0000000000000001  MS       0     0     1
  [ 7] .note.GNU-stack   PROGBITS         0000000000000000  00000081
       0000000000000000  0000000000000000           0     0     1
  [ 8] .eh_frame         PROGBITS         0000000000000000  00000088
       0000000000000038  0000000000000000   A       0     0     8
  [ 9] .rela.eh_frame    RELA             0000000000000000  00000240
       0000000000000018  0000000000000018   I      10     8     8
  [10] .symtab           SYMTAB           0000000000000000  000000c0
       0000000000000120  0000000000000018          11     9     8
  [11] .strtab           STRTAB           0000000000000000  000001e0
       0000000000000029  0000000000000000           0     0     1
  [12] .shstrtab         STRTAB           0000000000000000  00000258
       0000000000000061  0000000000000000           0     0     1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  l (large), p (processor specific)

There are no section groups in this file.

本文件中没有程序头。

There is no dynamic section in this file.

重定位节 '.rela.text' at offset 0x210 contains 2 entries:
  偏移量          信息           类型           符号值        符号名称 + 加数
000000000007  000500000002 R_X86_64_PC32     0000000000000000 .rodata - 4
00000000000c  000b00000004 R_X86_64_PLT32    0000000000000000 puts - 4

重定位节 '.rela.eh_frame' at offset 0x240 contains 1 entry:
  偏移量          信息           类型           符号值        符号名称 + 加数
000000000020  000200000002 R_X86_64_PC32     0000000000000000 .text + 0

The decoding of unwind sections for machine type Advanced Micro Devices X86-64 is not currently supported.

Symbol table '.symtab' contains 12 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS hello.c
     2: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 
     3: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 
     4: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 
     5: 0000000000000000     0 SECTION LOCAL  DEFAULT    5 
     6: 0000000000000000     0 SECTION LOCAL  DEFAULT    7 
     7: 0000000000000000     0 SECTION LOCAL  DEFAULT    8 
     8: 0000000000000000     0 SECTION LOCAL  DEFAULT    6 
     9: 0000000000000000    23 FUNC    GLOBAL DEFAULT    1 main
    10: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND _GLOBAL_OFFSET_TABLE_
    11: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND puts
编译之 链接

最后一步 链接 ,在makefile中加入

link:
	gcc hell.o -o hello

执行!

#make link
查看目录文件
#ls

在这里插入图片描述

绿色的hello就是由hello.c一步一步编译出来的可执行程序啦,

#./hello

在这里插入图片描述
让这一串出现在屏幕上实属不易。

查看ELF

Linux下可执行的二进制文件一般为ELF格式,查看下hello:

#readelf -a hello

内容

ELF 头:
  Magic:  7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  类别:                              ELF64
  数据:                              2 补码,小端序 (little endian)
  版本:                              1 (current)
  OS/ABI:                            UNIX - System V
  ABI 版本:                          0
  类型:                              DYN (共享目标文件)
  系统架构:                          Advanced Micro Devices X86-64
  版本:                              0x1
  入口点地址:              0x1050
  程序头起点:              64 (bytes into file)
  Start of section headers:          14688 (bytes into file)
  标志:             0x0
  本头的大小:       64 (字节)
  程序头大小:       56 (字节)
  Number of program headers:         11
  节头大小:         64 (字节)
  节头数量:         30
  字符串表索引节头: 29

节头:
  [号] 名称              类型             地址              偏移量
       大小              全体大小          旗标   链接   信息   对齐
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .interp           PROGBITS         00000000000002a8  000002a8
       000000000000001c  0000000000000000   A       0     0     1
  [ 2] .note.ABI-tag     NOTE             00000000000002c4  000002c4
       0000000000000020  0000000000000000   A       0     0     4
  [ 3] .note.gnu.build-i NOTE             00000000000002e4  000002e4
       0000000000000024  0000000000000000   A       0     0     4
  [ 4] .gnu.hash         GNU_HASH         0000000000000308  00000308
       0000000000000024  0000000000000000   A       5     0     8
  [ 5] .dynsym           DYNSYM           0000000000000330  00000330
       00000000000000a8  0000000000000018   A       6     1     8
  [ 6] .dynstr           STRTAB           00000000000003d8  000003d8
       0000000000000082  0000000000000000   A       0     0     1
  [ 7] .gnu.version      VERSYM           000000000000045a  0000045a
       000000000000000e  0000000000000002   A       5     0     2
  [ 8] .gnu.version_r    VERNEED          0000000000000468  00000468
       0000000000000020  0000000000000000   A       6     1     8
  [ 9] .rela.dyn         RELA             0000000000000488  00000488
       00000000000000c0  0000000000000018   A       5     0     8
  [10] .rela.plt         RELA             0000000000000548  00000548
       0000000000000018  0000000000000018  AI       5    23     8
  [11] .init             PROGBITS         0000000000001000  00001000
       0000000000000017  0000000000000000  AX       0     0     4
  [12] .plt              PROGBITS         0000000000001020  00001020
       0000000000000020  0000000000000010  AX       0     0     16
  [13] .plt.got          PROGBITS         0000000000001040  00001040
       0000000000000008  0000000000000008  AX       0     0     8
  [14] .text             PROGBITS         0000000000001050  00001050
       0000000000000161  0000000000000000  AX       0     0     16
  [15] .fini             PROGBITS         00000000000011b4  000011b4
       0000000000000009  0000000000000000  AX       0     0     4
  [16] .rodata           PROGBITS         0000000000002000  00002000
       0000000000000011  0000000000000000   A       0     0     4
  [17] .eh_frame_hdr     PROGBITS         0000000000002014  00002014
       000000000000003c  0000000000000000   A       0     0     4
  [18] .eh_frame         PROGBITS         0000000000002050  00002050
       0000000000000108  0000000000000000   A       0     0     8
  [19] .init_array       INIT_ARRAY       0000000000003de8  00002de8
       0000000000000008  0000000000000008  WA       0     0     8
  [20] .fini_array       FINI_ARRAY       0000000000003df0  00002df0
       0000000000000008  0000000000000008  WA       0     0     8
  [21] .dynamic          DYNAMIC          0000000000003df8  00002df8
       00000000000001e0  0000000000000010  WA       6     0     8
  [22] .got              PROGBITS         0000000000003fd8  00002fd8
       0000000000000028  0000000000000008  WA       0     0     8
  [23] .got.plt          PROGBITS         0000000000004000  00003000
       0000000000000020  0000000000000008  WA       0     0     8
  [24] .data             PROGBITS         0000000000004020  00003020
       0000000000000010  0000000000000000  WA       0     0     8
  [25] .bss              NOBITS           0000000000004030  00003030
       0000000000000008  0000000000000000  WA       0     0     1
  [26] .comment          PROGBITS         0000000000000000  00003030
       000000000000001c  0000000000000001  MS       0     0     1
  [27] .symtab           SYMTAB           0000000000000000  00003050
       0000000000000600  0000000000000018          28    45     8
  [28] .strtab           STRTAB           0000000000000000  00003650
       0000000000000203  0000000000000000           0     0     1
  [29] .shstrtab         STRTAB           0000000000000000  00003853
       0000000000000107  0000000000000000           0     0     1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  l (large), p (processor specific)

There are no section groups in this file.

程序头:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  PHDR           0x0000000000000040 0x0000000000000040 0x0000000000000040
                 0x0000000000000268 0x0000000000000268  R      0x8
  INTERP         0x00000000000002a8 0x00000000000002a8 0x00000000000002a8
                 0x000000000000001c 0x000000000000001c  R      0x1
      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
  LOAD           0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000560 0x0000000000000560  R      0x1000
  LOAD           0x0000000000001000 0x0000000000001000 0x0000000000001000
                 0x00000000000001bd 0x00000000000001bd  R E    0x1000
  LOAD           0x0000000000002000 0x0000000000002000 0x0000000000002000
                 0x0000000000000158 0x0000000000000158  R      0x1000
  LOAD           0x0000000000002de8 0x0000000000003de8 0x0000000000003de8
                 0x0000000000000248 0x0000000000000250  RW     0x1000
  DYNAMIC        0x0000000000002df8 0x0000000000003df8 0x0000000000003df8
                 0x00000000000001e0 0x00000000000001e0  RW     0x8
  NOTE           0x00000000000002c4 0x00000000000002c4 0x00000000000002c4
                 0x0000000000000044 0x0000000000000044  R      0x4
  GNU_EH_FRAME   0x0000000000002014 0x0000000000002014 0x0000000000002014
                 0x000000000000003c 0x000000000000003c  R      0x4
  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000  RW     0x10
  GNU_RELRO      0x0000000000002de8 0x0000000000003de8 0x0000000000003de8
                 0x0000000000000218 0x0000000000000218  R      0x1

 Section to Segment mapping:
  段节...
   00     
   01     .interp 
   02     .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt 
   03     .init .plt .plt.got .text .fini 
   04     .rodata .eh_frame_hdr .eh_frame 
   05     .init_array .fini_array .dynamic .got .got.plt .data .bss 
   06     .dynamic 
   07     .note.ABI-tag .note.gnu.build-id 
   08     .eh_frame_hdr 
   09     
   10     .init_array .fini_array .dynamic .got 

Dynamic section at offset 0x2df8 contains 26 entries:
  标记        类型                         名称/值
 0x0000000000000001 (NEEDED)             共享库:[libc.so.6]
 0x000000000000000c (INIT)               0x1000
 0x000000000000000d (FINI)               0x11b4
 0x0000000000000019 (INIT_ARRAY)         0x3de8
 0x000000000000001b (INIT_ARRAYSZ)       8 (bytes)
 0x000000000000001a (FINI_ARRAY)         0x3df0
 0x000000000000001c (FINI_ARRAYSZ)       8 (bytes)
 0x000000006ffffef5 (GNU_HASH)           0x308
 0x0000000000000005 (STRTAB)             0x3d8
 0x0000000000000006 (SYMTAB)             0x330
 0x000000000000000a (STRSZ)              130 (bytes)
 0x000000000000000b (SYMENT)             24 (bytes)
 0x0000000000000015 (DEBUG)              0x0
 0x0000000000000003 (PLTGOT)             0x4000
 0x0000000000000002 (PLTRELSZ)           24 (bytes)
 0x0000000000000014 (PLTREL)             RELA
 0x0000000000000017 (JMPREL)             0x548
 0x0000000000000007 (RELA)               0x488
 0x0000000000000008 (RELASZ)             192 (bytes)
 0x0000000000000009 (RELAENT)            24 (bytes)
 0x000000006ffffffb (FLAGS_1)            标志: PIE
 0x000000006ffffffe (VERNEED)            0x468
 0x000000006fffffff (VERNEEDNUM)         1
 0x000000006ffffff0 (VERSYM)             0x45a
 0x000000006ffffff9 (RELACOUNT)          3
 0x0000000000000000 (NULL)               0x0

重定位节 '.rela.dyn' at offset 0x488 contains 8 entries:
  偏移量          信息           类型           符号值        符号名称 + 加数
000000003de8  000000000008 R_X86_64_RELATIVE                    1130
000000003df0  000000000008 R_X86_64_RELATIVE                    10f0
000000004028  000000000008 R_X86_64_RELATIVE                    4028
000000003fd8  000100000006 R_X86_64_GLOB_DAT 0000000000000000 _ITM_deregisterTMClone + 0
000000003fe0  000300000006 R_X86_64_GLOB_DAT 0000000000000000 __libc_start_main@GLIBC_2.2.5 + 0
000000003fe8  000400000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start__ + 0
000000003ff0  000500000006 R_X86_64_GLOB_DAT 0000000000000000 _ITM_registerTMCloneTa + 0
000000003ff8  000600000006 R_X86_64_GLOB_DAT 0000000000000000 __cxa_finalize@GLIBC_2.2.5 + 0

重定位节 '.rela.plt' at offset 0x548 contains 1 entry:
  偏移量          信息           类型           符号值        符号名称 + 加数
000000004018  000200000007 R_X86_64_JUMP_SLO 0000000000000000 puts@GLIBC_2.2.5 + 0

The decoding of unwind sections for machine type Advanced Micro Devices X86-64 is not currently supported.

Symbol table '.dynsym' contains 7 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_deregisterTMCloneTab
     2: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND puts@GLIBC_2.2.5 (2)
     3: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.2.5 (2)
     4: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
     5: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_registerTMCloneTable
     6: 0000000000000000     0 FUNC    WEAK   DEFAULT  UND __cxa_finalize@GLIBC_2.2.5 (2)

Symbol table '.symtab' contains 64 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 00000000000002a8     0 SECTION LOCAL  DEFAULT    1 
     2: 00000000000002c4     0 SECTION LOCAL  DEFAULT    2 
     3: 00000000000002e4     0 SECTION LOCAL  DEFAULT    3 
     4: 0000000000000308     0 SECTION LOCAL  DEFAULT    4 
     5: 0000000000000330     0 SECTION LOCAL  DEFAULT    5 
     6: 00000000000003d8     0 SECTION LOCAL  DEFAULT    6 
     7: 000000000000045a     0 SECTION LOCAL  DEFAULT    7 
     8: 0000000000000468     0 SECTION LOCAL  DEFAULT    8 
     9: 0000000000000488     0 SECTION LOCAL  DEFAULT    9 
    10: 0000000000000548     0 SECTION LOCAL  DEFAULT   10 
    11: 0000000000001000     0 SECTION LOCAL  DEFAULT   11 
    12: 0000000000001020     0 SECTION LOCAL  DEFAULT   12 
    13: 0000000000001040     0 SECTION LOCAL  DEFAULT   13 
    14: 0000000000001050     0 SECTION LOCAL  DEFAULT   14 
    15: 00000000000011b4     0 SECTION LOCAL  DEFAULT   15 
    16: 0000000000002000     0 SECTION LOCAL  DEFAULT   16 
    17: 0000000000002014     0 SECTION LOCAL  DEFAULT   17 
    18: 0000000000002050     0 SECTION LOCAL  DEFAULT   18 
    19: 0000000000003de8     0 SECTION LOCAL  DEFAULT   19 
    20: 0000000000003df0     0 SECTION LOCAL  DEFAULT   20 
    21: 0000000000003df8     0 SECTION LOCAL  DEFAULT   21 
    22: 0000000000003fd8     0 SECTION LOCAL  DEFAULT   22 
    23: 0000000000004000     0 SECTION LOCAL  DEFAULT   23 
    24: 0000000000004020     0 SECTION LOCAL  DEFAULT   24 
    25: 0000000000004030     0 SECTION LOCAL  DEFAULT   25 
    26: 0000000000000000     0 SECTION LOCAL  DEFAULT   26 
    27: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
    28: 0000000000001080     0 FUNC    LOCAL  DEFAULT   14 deregister_tm_clones
    29: 00000000000010b0     0 FUNC    LOCAL  DEFAULT   14 register_tm_clones
    30: 00000000000010f0     0 FUNC    LOCAL  DEFAULT   14 __do_global_dtors_aux
    31: 0000000000004030     1 OBJECT  LOCAL  DEFAULT   25 completed.7325
    32: 0000000000003df0     0 OBJECT  LOCAL  DEFAULT   20 __do_global_dtors_aux_fin
    33: 0000000000001130     0 FUNC    LOCAL  DEFAULT   14 frame_dummy
    34: 0000000000003de8     0 OBJECT  LOCAL  DEFAULT   19 __frame_dummy_init_array_
    35: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS hello.c
    36: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
    37: 0000000000002154     0 OBJECT  LOCAL  DEFAULT   18 __FRAME_END__
    38: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS 
    39: 0000000000003df0     0 NOTYPE  LOCAL  DEFAULT   19 __init_array_end
    40: 0000000000003df8     0 OBJECT  LOCAL  DEFAULT   21 _DYNAMIC
    41: 0000000000003de8     0 NOTYPE  LOCAL  DEFAULT   19 __init_array_start
    42: 0000000000002014     0 NOTYPE  LOCAL  DEFAULT   17 __GNU_EH_FRAME_HDR
    43: 0000000000004000     0 OBJECT  LOCAL  DEFAULT   23 _GLOBAL_OFFSET_TABLE_
    44: 0000000000001000     0 FUNC    LOCAL  DEFAULT   11 _init
    45: 00000000000011b0     1 FUNC    GLOBAL DEFAULT   14 __libc_csu_fini
    46: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_deregisterTMCloneTab
    47: 0000000000004020     0 NOTYPE  WEAK   DEFAULT   24 data_start
    48: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND puts@@GLIBC_2.2.5
    49: 0000000000004030     0 NOTYPE  GLOBAL DEFAULT   24 _edata
    50: 00000000000011b4     0 FUNC    GLOBAL HIDDEN    15 _fini
    51: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@@GLIBC_
    52: 0000000000004020     0 NOTYPE  GLOBAL DEFAULT   24 __data_start
    53: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
    54: 0000000000004028     0 OBJECT  GLOBAL HIDDEN    24 __dso_handle
    55: 0000000000002000     4 OBJECT  GLOBAL DEFAULT   16 _IO_stdin_used
    56: 0000000000001150    93 FUNC    GLOBAL DEFAULT   14 __libc_csu_init
    57: 0000000000004038     0 NOTYPE  GLOBAL DEFAULT   25 _end
    58: 0000000000001050    43 FUNC    GLOBAL DEFAULT   14 _start
    59: 0000000000004030     0 NOTYPE  GLOBAL DEFAULT   25 __bss_start
    60: 0000000000001135    23 FUNC    GLOBAL DEFAULT   14 main
    61: 0000000000004030     0 OBJECT  GLOBAL HIDDEN    24 __TMC_END__
    62: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_registerTMCloneTable
    63: 0000000000000000     0 FUNC    WEAK   DEFAULT  UND __cxa_finalize@@GLIBC_2.2

Histogram for `.gnu.hash' bucket list length (total of 2 buckets):
 Length  Number     % of total  Coverage
      0  1          ( 50.0%)
      1  1          ( 50.0%)    100.0%

Version symbols section '.gnu.version' contains 7 entries:
 地址:000000000000045a  Offset: 0x00045a  Link: 5 (.dynsym)
  000:   0 (*本地*)       0 (*本地*)       2 (GLIBC_2.2.5)   2 (GLIBC_2.2.5)
  004:   0 (*本地*)       0 (*本地*)       2 (GLIBC_2.2.5)

Version needs section '.gnu.version_r' contains 1 entry:
 地址:0x0000000000000468  Offset: 0x000468  Link: 6 (.dynstr)
  000000: Version: 1  文件:libc.so.6  计数:1
  0x0010:   Name: GLIBC_2.2.5  标志:无  版本:2

Displaying notes found in: .note.ABI-tag
  所有者             Data size	Description
  GNU                  0x00000010	NT_GNU_ABI_TAG (ABI version tag)
    OS: Linux, ABI: 3.2.0

Displaying notes found in: .note.gnu.build-id
  所有者             Data size	Description
  GNU                  0x00000014	NT_GNU_BUILD_ID (unique build ID bitstring)
    Build ID: eca94c2c32a2d5ccdd6097ee889e3470df276c47

显然比链接之前长了许多,增加了程序头等内容。

GDB

程序写完如果输入不符合预期的话就需要用到调试,断点。单步跟踪等可以快速定位到问题,当然,如果靠往程序中加入printf()也能达到调试的目的,这里就需要用到GDB(当然,图形化的高级编译器要方便的多)

GDB调试的是可执行文件,使用gcc编译的话要为可执行程序包含调试信息

#gcc -g hello.c -o hello

GDB调试hello

#gdb hello

在这里插入图片描述
表示读取完成。
gdb中常用的命令

break 设置断点 可以使行号、函数名称等
kill 终止当前调试的程序
print 显示变量或者表达式的值
delete 删除断点
run 运行
make 编译程序
continue 从断点继续执行
set args 设置运行参数
next 单步执行程序
step 进入函数内部

以上只是一部分常用命令、如果需要更多的操作、则查看gdb的帮助文件。

help all

反编译

至此好像对于hello程序所有的内容都看了一遍,但是如果只拿到一个可执行文件,想研究下该程序,就需要用到反汇编了,Linux提供了反汇编程序objdump
反汇编hello并重定向到txt文件中

objdump -s -d hello > hello.txt

得到:

hello:     文件格式 elf64-x86-64

Contents of section .interp:
 02a8 2f6c6962 36342f6c 642d6c69 6e75782d  /lib64/ld-linux-
 02b8 7838362d 36342e73 6f2e3200           x86-64.so.2.    
Contents of section .note.ABI-tag:
 02c4 04000000 10000000 01000000 474e5500  ............GNU.
 02d4 00000000 03000000 02000000 00000000  ................
Contents of section .note.gnu.build-id:
 02e4 04000000 14000000 03000000 474e5500  ............GNU.
 02f4 eca94c2c 32a2d5cc dd6097ee 889e3470  ..L,2....`....4p
 0304 df276c47                             .'lG            
Contents of section .gnu.hash:
 0308 02000000 06000000 01000000 06000000  ................
 0318 00008100 00000000 06000000 00000000  ................
 0328 d165ce6d                             .e.m            
Contents of section .dynsym:
 0330 00000000 00000000 00000000 00000000  ................
 0340 00000000 00000000 3d000000 20000000  ........=... ...
 0350 00000000 00000000 00000000 00000000  ................
 0360 0b000000 12000000 00000000 00000000  ................
 0370 00000000 00000000 1f000000 12000000  ................
 0380 00000000 00000000 00000000 00000000  ................
 0390 59000000 20000000 00000000 00000000  Y... ...........
 03a0 00000000 00000000 68000000 20000000  ........h... ...
 03b0 00000000 00000000 00000000 00000000  ................
 03c0 10000000 22000000 00000000 00000000  ...."...........
 03d0 00000000 00000000                    ........        
Contents of section .dynstr:
 03d8 006c6962 632e736f 2e360070 75747300  .libc.so.6.puts.
 03e8 5f5f6378 615f6669 6e616c69 7a65005f  __cxa_finalize._
 03f8 5f6c6962 635f7374 6172745f 6d61696e  _libc_start_main
 0408 00474c49 42435f32 2e322e35 005f4954  .GLIBC_2.2.5._IT
 0418 4d5f6465 72656769 73746572 544d436c  M_deregisterTMCl
 0428 6f6e6554 61626c65 005f5f67 6d6f6e5f  oneTable.__gmon_
 0438 73746172 745f5f00 5f49544d 5f726567  start__._ITM_reg
 0448 69737465 72544d43 6c6f6e65 5461626c  isterTMCloneTabl
 0458 6500                                 e.              
Contents of section .gnu.version:
 045a 00000000 02000200 00000000 0200      ..............  
Contents of section .gnu.version_r:
 0468 01000100 01000000 10000000 00000000  ................
 0478 751a6909 00000200 31000000 00000000  u.i.....1.......
Contents of section .rela.dyn:
 0488 e83d0000 00000000 08000000 00000000  .=..............
 0498 30110000 00000000 f03d0000 00000000  0........=......
 04a8 08000000 00000000 f0100000 00000000  ................
 04b8 28400000 00000000 08000000 00000000  (@..............
 04c8 28400000 00000000 d83f0000 00000000  (@.......?......
 04d8 06000000 01000000 00000000 00000000  ................
 04e8 e03f0000 00000000 06000000 03000000  .?..............
 04f8 00000000 00000000 e83f0000 00000000  .........?......
 0508 06000000 04000000 00000000 00000000  ................
 0518 f03f0000 00000000 06000000 05000000  .?..............
 0528 00000000 00000000 f83f0000 00000000  .........?......
 0538 06000000 06000000 00000000 00000000  ................
Contents of section .rela.plt:
 0548 18400000 00000000 07000000 02000000  .@..............
 0558 00000000 00000000                    ........        
Contents of section .init:
 1000 4883ec08 488b05dd 2f000048 85c07402  H...H.../..H..t.
 1010 ffd04883 c408c3                      ..H....         
Contents of section .plt:
 1020 ff35e22f 0000ff25 e42f0000 0f1f4000  .5./...%./....@.
 1030 ff25e22f 00006800 000000e9 e0ffffff  .%./..h.........
Contents of section .plt.got:
 1040 ff25b22f 00006690                    .%./..f.        
Contents of section .text:
 1050 31ed4989 d15e4889 e24883e4 f050544c  1.I..^H..H...PTL
 1060 8d054a01 0000488d 0de30000 00488d3d  ..J...H......H.=
 1070 c1000000 ff15662f 0000f40f 1f440000  ......f/.....D..
 1080 488d3da9 2f000048 8d05a22f 00004839  H.=./..H.../..H9
 1090 f8741548 8b053e2f 00004885 c07409ff  .t.H..>/..H..t..
 10a0 e00f1f80 00000000 c30f1f80 00000000  ................
 10b0 488d3d79 2f000048 8d35722f 00004829  H.=y/..H.5r/..H)
 10c0 fe48c1fe 034889f0 48c1e83f 4801c648  .H...H..H..?H..H
 10d0 d1fe7414 488b0515 2f000048 85c07408  ..t.H.../..H..t.
 10e0 ffe0660f 1f440000 c30f1f80 00000000  ..f..D..........
 10f0 803d392f 00000075 2f554883 3df62e00  .=9/...u/UH.=...
 1100 00004889 e5740c48 8b3d1a2f 0000e82d  ..H..t.H.=./...-
 1110 ffffffe8 68ffffff c605112f 0000015d  ....h....../...]
 1120 c30f1f80 00000000 c30f1f80 00000000  ................
 1130 e97bffff ff554889 e5488d3d c40e0000  .{...UH..H.=....
 1140 e8ebfeff ffb80000 00005dc3 0f1f4000  ..........]...@.
 1150 41574c8d 3d8f2c00 00415649 89d64155  AWL.=.,..AVI..AU
 1160 4989f541 544189fc 55488d2d 802c0000  I..ATA..UH.-.,..
 1170 534c29fd 4883ec08 e883feff ff48c1fd  SL).H........H..
 1180 03741b31 db0f1f00 4c89f24c 89ee4489  .t.1....L..L..D.
 1190 e741ff14 df4883c3 014839dd 75ea4883  .A...H...H9.u.H.
 11a0 c4085b5d 415c415d 415e415f c30f1f00  ..[]A\A]A^A_....
 11b0 c3                                   .               
Contents of section .fini:
 11b4 4883ec08 4883c408 c3                 H...H....       
Contents of section .rodata:
 2000 01000200 48656c6c 6f20776f 726c6421  ....Hello world!
 2010 00                                   .               
Contents of section .eh_frame_hdr:
 2014 011b033b 38000000 06000000 0cf0ffff  ...;8...........
 2024 84000000 2cf0ffff ac000000 3cf0ffff  ....,.......<...
 2034 54000000 21f1ffff c4000000 3cf1ffff  T...!.......<...
 2044 e4000000 9cf1ffff 2c010000           ........,...    
Contents of section .eh_frame:
 2050 14000000 00000000 017a5200 01781001  .........zR..x..
 2060 1b0c0708 90010710 14000000 1c000000  ................
 2070 e0efffff 2b000000 00000000 00000000  ....+...........
 2080 14000000 00000000 017a5200 01781001  .........zR..x..
 2090 1b0c0708 90010000 24000000 1c000000  ........$.......
 20a0 80efffff 20000000 000e1046 0e184a0f  .... ......F..J.
 20b0 0b770880 003f1a3b 2a332422 00000000  .w...?.;*3$"....
 20c0 14000000 44000000 78efffff 08000000  ....D...x.......
 20d0 00000000 00000000 1c000000 5c000000  ............\...
 20e0 55f0ffff 17000000 00410e10 8602430d  U........A....C.
 20f0 06520c07 08000000 44000000 7c000000  .R......D...|...
 2100 50f0ffff 5d000000 00420e10 8f02490e  P...]....B....I.
 2110 188e0345 0e208d04 450e288c 05440e30  ...E. ..E.(..D.0
 2120 8606480e 38830747 0e406a0e 38410e30  ..H.8..G.@j.8A.0
 2130 410e2842 0e20420e 18420e10 420e0800  A.(B. B..B..B...
 2140 10000000 c4000000 68f0ffff 01000000  ........h.......
 2150 00000000 00000000                    ........        
Contents of section .init_array:
 3de8 30110000 00000000                    0.......        
Contents of section .fini_array:
 3df0 f0100000 00000000                    ........        
Contents of section .dynamic:
 3df8 01000000 00000000 01000000 00000000  ................
 3e08 0c000000 00000000 00100000 00000000  ................
 3e18 0d000000 00000000 b4110000 00000000  ................
 3e28 19000000 00000000 e83d0000 00000000  .........=......
 3e38 1b000000 00000000 08000000 00000000  ................
 3e48 1a000000 00000000 f03d0000 00000000  .........=......
 3e58 1c000000 00000000 08000000 00000000  ................
 3e68 f5feff6f 00000000 08030000 00000000  ...o............
 3e78 05000000 00000000 d8030000 00000000  ................
 3e88 06000000 00000000 30030000 00000000  ........0.......
 3e98 0a000000 00000000 82000000 00000000  ................
 3ea8 0b000000 00000000 18000000 00000000  ................
 3eb8 15000000 00000000 00000000 00000000  ................
 3ec8 03000000 00000000 00400000 00000000  .........@......
 3ed8 02000000 00000000 18000000 00000000  ................
 3ee8 14000000 00000000 07000000 00000000  ................
 3ef8 17000000 00000000 48050000 00000000  ........H.......
 3f08 07000000 00000000 88040000 00000000  ................
 3f18 08000000 00000000 c0000000 00000000  ................
 3f28 09000000 00000000 18000000 00000000  ................
 3f38 fbffff6f 00000000 00000008 00000000  ...o............
 3f48 feffff6f 00000000 68040000 00000000  ...o....h.......
 3f58 ffffff6f 00000000 01000000 00000000  ...o............
 3f68 f0ffff6f 00000000 5a040000 00000000  ...o....Z.......
 3f78 f9ffff6f 00000000 03000000 00000000  ...o............
 3f88 00000000 00000000 00000000 00000000  ................
 3f98 00000000 00000000 00000000 00000000  ................
 3fa8 00000000 00000000 00000000 00000000  ................
 3fb8 00000000 00000000 00000000 00000000  ................
 3fc8 00000000 00000000 00000000 00000000  ................
Contents of section .got:
 3fd8 00000000 00000000 00000000 00000000  ................
 3fe8 00000000 00000000 00000000 00000000  ................
 3ff8 00000000 00000000                    ........        
Contents of section .got.plt:
 4000 f83d0000 00000000 00000000 00000000  .=..............
 4010 00000000 00000000 36100000 00000000  ........6.......
Contents of section .data:
 4020 00000000 00000000 28400000 00000000  ........(@......
Contents of section .comment:
 0000 4743433a 20284465 6269616e 20382e33  GCC: (Debian 8.3
 0010 2e302d36 2920382e 332e3000           .0-6) 8.3.0.    

Disassembly of section .init:

0000000000001000 <_init>:
    1000:	48 83 ec 08          	sub    $0x8,%rsp
    1004:	48 8b 05 dd 2f 00 00 	mov    0x2fdd(%rip),%rax        # 3fe8 <__gmon_start__>
    100b:	48 85 c0             	test   %rax,%rax
    100e:	74 02                	je     1012 <_init+0x12>
    1010:	ff d0                	callq  *%rax
    1012:	48 83 c4 08          	add    $0x8,%rsp
    1016:	c3                   	retq   

Disassembly of section .plt:

0000000000001020 <.plt>:
    1020:	ff 35 e2 2f 00 00    	pushq  0x2fe2(%rip)        # 4008 <_GLOBAL_OFFSET_TABLE_+0x8>
    1026:	ff 25 e4 2f 00 00    	jmpq   *0x2fe4(%rip)        # 4010 <_GLOBAL_OFFSET_TABLE_+0x10>
    102c:	0f 1f 40 00          	nopl   0x0(%rax)

0000000000001030 <puts@plt>:
    1030:	ff 25 e2 2f 00 00    	jmpq   *0x2fe2(%rip)        # 4018 <puts@GLIBC_2.2.5>
    1036:	68 00 00 00 00       	pushq  $0x0
    103b:	e9 e0 ff ff ff       	jmpq   1020 <.plt>

Disassembly of section .plt.got:

0000000000001040 <__cxa_finalize@plt>:
    1040:	ff 25 b2 2f 00 00    	jmpq   *0x2fb2(%rip)        # 3ff8 <__cxa_finalize@GLIBC_2.2.5>
    1046:	66 90                	xchg   %ax,%ax

Disassembly of section .text:

0000000000001050 <_start>:
    1050:	31 ed                	xor    %ebp,%ebp
    1052:	49 89 d1             	mov    %rdx,%r9
    1055:	5e                   	pop    %rsi
    1056:	48 89 e2             	mov    %rsp,%rdx
    1059:	48 83 e4 f0          	and    $0xfffffffffffffff0,%rsp
    105d:	50                   	push   %rax
    105e:	54                   	push   %rsp
    105f:	4c 8d 05 4a 01 00 00 	lea    0x14a(%rip),%r8        # 11b0 <__libc_csu_fini>
    1066:	48 8d 0d e3 00 00 00 	lea    0xe3(%rip),%rcx        # 1150 <__libc_csu_init>
    106d:	48 8d 3d c1 00 00 00 	lea    0xc1(%rip),%rdi        # 1135 <main>
    1074:	ff 15 66 2f 00 00    	callq  *0x2f66(%rip)        # 3fe0 <__libc_start_main@GLIBC_2.2.5>
    107a:	f4                   	hlt    
    107b:	0f 1f 44 00 00       	nopl   0x0(%rax,%rax,1)

0000000000001080 <deregister_tm_clones>:
    1080:	48 8d 3d a9 2f 00 00 	lea    0x2fa9(%rip),%rdi        # 4030 <__TMC_END__>
    1087:	48 8d 05 a2 2f 00 00 	lea    0x2fa2(%rip),%rax        # 4030 <__TMC_END__>
    108e:	48 39 f8             	cmp    %rdi,%rax
    1091:	74 15                	je     10a8 <deregister_tm_clones+0x28>
    1093:	48 8b 05 3e 2f 00 00 	mov    0x2f3e(%rip),%rax        # 3fd8 <_ITM_deregisterTMCloneTable>
    109a:	48 85 c0             	test   %rax,%rax
    109d:	74 09                	je     10a8 <deregister_tm_clones+0x28>
    109f:	ff e0                	jmpq   *%rax
    10a1:	0f 1f 80 00 00 00 00 	nopl   0x0(%rax)
    10a8:	c3                   	retq   
    10a9:	0f 1f 80 00 00 00 00 	nopl   0x0(%rax)

00000000000010b0 <register_tm_clones>:
    10b0:	48 8d 3d 79 2f 00 00 	lea    0x2f79(%rip),%rdi        # 4030 <__TMC_END__>
    10b7:	48 8d 35 72 2f 00 00 	lea    0x2f72(%rip),%rsi        # 4030 <__TMC_END__>
    10be:	48 29 fe             	sub    %rdi,%rsi
    10c1:	48 c1 fe 03          	sar    $0x3,%rsi
    10c5:	48 89 f0             	mov    %rsi,%rax
    10c8:	48 c1 e8 3f          	shr    $0x3f,%rax
    10cc:	48 01 c6             	add    %rax,%rsi
    10cf:	48 d1 fe             	sar    %rsi
    10d2:	74 14                	je     10e8 <register_tm_clones+0x38>
    10d4:	48 8b 05 15 2f 00 00 	mov    0x2f15(%rip),%rax        # 3ff0 <_ITM_registerTMCloneTable>
    10db:	48 85 c0             	test   %rax,%rax
    10de:	74 08                	je     10e8 <register_tm_clones+0x38>
    10e0:	ff e0                	jmpq   *%rax
    10e2:	66 0f 1f 44 00 00    	nopw   0x0(%rax,%rax,1)
    10e8:	c3                   	retq   
    10e9:	0f 1f 80 00 00 00 00 	nopl   0x0(%rax)

00000000000010f0 <__do_global_dtors_aux>:
    10f0:	80 3d 39 2f 00 00 00 	cmpb   $0x0,0x2f39(%rip)        # 4030 <__TMC_END__>
    10f7:	75 2f                	jne    1128 <__do_global_dtors_aux+0x38>
    10f9:	55                   	push   %rbp
    10fa:	48 83 3d f6 2e 00 00 	cmpq   $0x0,0x2ef6(%rip)        # 3ff8 <__cxa_finalize@GLIBC_2.2.5>
    1101:	00 
    1102:	48 89 e5             	mov    %rsp,%rbp
    1105:	74 0c                	je     1113 <__do_global_dtors_aux+0x23>
    1107:	48 8b 3d 1a 2f 00 00 	mov    0x2f1a(%rip),%rdi        # 4028 <__dso_handle>
    110e:	e8 2d ff ff ff       	callq  1040 <__cxa_finalize@plt>
    1113:	e8 68 ff ff ff       	callq  1080 <deregister_tm_clones>
    1118:	c6 05 11 2f 00 00 01 	movb   $0x1,0x2f11(%rip)        # 4030 <__TMC_END__>
    111f:	5d                   	pop    %rbp
    1120:	c3                   	retq   
    1121:	0f 1f 80 00 00 00 00 	nopl   0x0(%rax)
    1128:	c3                   	retq   
    1129:	0f 1f 80 00 00 00 00 	nopl   0x0(%rax)

0000000000001130 <frame_dummy>:
    1130:	e9 7b ff ff ff       	jmpq   10b0 <register_tm_clones>

0000000000001135 <main>:
    1135:	55                   	push   %rbp
    1136:	48 89 e5             	mov    %rsp,%rbp
    1139:	48 8d 3d c4 0e 00 00 	lea    0xec4(%rip),%rdi        # 2004 <_IO_stdin_used+0x4>
    1140:	e8 eb fe ff ff       	callq  1030 <puts@plt>
    1145:	b8 00 00 00 00       	mov    $0x0,%eax
    114a:	5d                   	pop    %rbp
    114b:	c3                   	retq   
    114c:	0f 1f 40 00          	nopl   0x0(%rax)

0000000000001150 <__libc_csu_init>:
    1150:	41 57                	push   %r15
    1152:	4c 8d 3d 8f 2c 00 00 	lea    0x2c8f(%rip),%r15        # 3de8 <__frame_dummy_init_array_entry>
    1159:	41 56                	push   %r14
    115b:	49 89 d6             	mov    %rdx,%r14
    115e:	41 55                	push   %r13
    1160:	49 89 f5             	mov    %rsi,%r13
    1163:	41 54                	push   %r12
    1165:	41 89 fc             	mov    %edi,%r12d
    1168:	55                   	push   %rbp
    1169:	48 8d 2d 80 2c 00 00 	lea    0x2c80(%rip),%rbp        # 3df0 <__init_array_end>
    1170:	53                   	push   %rbx
    1171:	4c 29 fd             	sub    %r15,%rbp
    1174:	48 83 ec 08          	sub    $0x8,%rsp
    1178:	e8 83 fe ff ff       	callq  1000 <_init>
    117d:	48 c1 fd 03          	sar    $0x3,%rbp
    1181:	74 1b                	je     119e <__libc_csu_init+0x4e>
    1183:	31 db                	xor    %ebx,%ebx
    1185:	0f 1f 00             	nopl   (%rax)
    1188:	4c 89 f2             	mov    %r14,%rdx
    118b:	4c 89 ee             	mov    %r13,%rsi
    118e:	44 89 e7             	mov    %r12d,%edi
    1191:	41 ff 14 df          	callq  *(%r15,%rbx,8)
    1195:	48 83 c3 01          	add    $0x1,%rbx
    1199:	48 39 dd             	cmp    %rbx,%rbp
    119c:	75 ea                	jne    1188 <__libc_csu_init+0x38>
    119e:	48 83 c4 08          	add    $0x8,%rsp
    11a2:	5b                   	pop    %rbx
    11a3:	5d                   	pop    %rbp
    11a4:	41 5c                	pop    %r12
    11a6:	41 5d                	pop    %r13
    11a8:	41 5e                	pop    %r14
    11aa:	41 5f                	pop    %r15
    11ac:	c3                   	retq   
    11ad:	0f 1f 00             	nopl   (%rax)

00000000000011b0 <__libc_csu_fini>:
    11b0:	c3                   	retq   

Disassembly of section .fini:

00000000000011b4 <_fini>:
    11b4:	48 83 ec 08          	sub    $0x8,%rsp
    11b8:	48 83 c4 08          	add    $0x8,%rsp
    11bc:	c3                   	retq 
总结

hello world这短短的六行代码不能说明c所有机制,确让人从本质上理解了程序的基本构成,不禁感叹前辈们的智慧;
如果有一天因为自己的程序得不到满意的输出,回来看看hello world。

山僧不解数甲子, 一叶落知天下秋。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值