預處理

/* test.c */
#include <stdio.h>
 
int main() {
    printf("%s", "Hello World");
    return 0;
}

進行預處理:gcc -E test.c -o test.i 預處理即是將各種 macro、define 等等給展開,所以可以看到 test.i 當中直到最下面才出現原本 test.c 的內容,上面全部都是展開的結果。

/* test.i*/
 
# 1 "test.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 31 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 32 "<command-line>" 2
# 1 "test.c"
# 1 "/usr/include/stdio.h" 1 3 4
# 27 "/usr/include/stdio.h" 3 4
# 1 "/usr/include/aarch64-linux-gnu/bits/libc-header-start.h" 1 3 4
# 33 "/usr/include/aarch64-linux-gnu/bits/libc-header-start.h" 3 4
# 1 "/usr/include/features.h" 1 3 4
 
...
...
...
 
extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
# 858 "/usr/include/stdio.h" 3 4
extern int __uflow (FILE *);
extern int __overflow (FILE *, int);
# 873 "/usr/include/stdio.h" 3 4
 
# 2 "test.c" 2
 
 
# 3 "test.c"
int main() {
    printf("%s", "Hello World");
    return 0;
}
 

編譯

進行編譯得到 assembly file:gcc -S test.i -o test.s

	.arch armv8-a
	.file	"test.c"
	.text
	.section	.rodata
	.align	3
.LC0:
	.string	"Hello World"
	.align	3
.LC1:
	.string	"%s"
	.text
	.align	2
	.global	main
	.type	main, %function
main:
.LFB0:
	.cfi_startproc
	stp	x29, x30, [sp, -16]!
	.cfi_def_cfa_offset 16
	.cfi_offset 29, -16
	.cfi_offset 30, -8
	mov	x29, sp
	adrp	x0, .LC0
	add	x1, x0, :lo12:.LC0
	adrp	x0, .LC1
	add	x0, x0, :lo12:.LC1
	bl	printf
	mov	w0, 0
	ldp	x29, x30, [sp], 16
	.cfi_restore 30
	.cfi_restore 29
	.cfi_def_cfa_offset 0
	ret
	.cfi_endproc
.LFE0:
	.size	main, .-main
	.ident	"GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0"
	.section	.note.GNU-stack,"",@progbits
 

彙編

將組合語言彙編成機器語言,得到 object file:gcc -c test.s -o test.o

parallels@ubuntu-linux-20-04-desktop:~/C_playground$ objdump -h test.o
 
test.o:     file format elf64-littleaarch64
 
Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .text         00000028  0000000000000000  0000000000000000  00000040  2**2
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
  1 .data         00000000  0000000000000000  0000000000000000  00000068  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000000  0000000000000000  0000000000000000  00000068  2**0
                  ALLOC
  3 .rodata       00000013  0000000000000000  0000000000000000  00000068  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .comment      0000002c  0000000000000000  0000000000000000  0000007b  2**0
                  CONTENTS, READONLY
  5 .note.GNU-stack 00000000  0000000000000000  0000000000000000  000000a7  2**0
                  CONTENTS, READONLY
  6 .eh_frame     00000038  0000000000000000  0000000000000000  000000a8  2**3
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
parallels@ubuntu-linux-20-04-desktop:~/C_playground$ hexdump test.o
0000000 457f 464c 0102 0001 0000 0000 0000 0000
0000010 0001 00b7 0001 0000 0000 0000 0000 0000
0000020 0000 0000 0000 0000 0348 0000 0000 0000
0000030 0000 0000 0040 0000 0000 0040 000d 000c
0000040 7bfd a9bf 03fd 9100 0000 9000 0001 9100
0000050 0000 9000 0000 9100 0000 9400 0000 5280
0000060 7bfd a8c1 03c0 d65f 6548 6c6c 206f 6f57
0000070 6c72 0064 0000 0000 7325 0000 4347 3a43
0000080 2820 6255 6e75 7574 3920 342e 302e 312d
0000090 6275 6e75 7574 7e31 3032 302e 2e34 2931
00000a0 3920 342e 302e 0000 0010 0000 0000 0000
00000b0 7a01 0052 7804 011e 0c1b 001f 0020 0000
00000c0 0018 0000 0000 0000 0028 0000 4100 100e
00000d0 029d 019e de48 0edd 0000 0000 0000 0000
00000e0 0000 0000 0000 0000 0000 0000 0000 0000
00000f0 0000 0000 0000 0000 0001 0000 0004 fff1
0000100 0000 0000 0000 0000 0000 0000 0000 0000
0000110 0000 0000 0003 0001 0000 0000 0000 0000
0000120 0000 0000 0000 0000 0000 0000 0003 0003
0000130 0000 0000 0000 0000 0000 0000 0000 0000
0000140 0000 0000 0003 0004 0000 0000 0000 0000
0000150 0000 0000 0000 0000 0000 0000 0003 0005
0000160 0000 0000 0000 0000 0000 0000 0000 0000
0000170 0008 0000 0000 0005 0000 0000 0000 0000
0000180 0000 0000 0000 0000 000b 0000 0000 0001
0000190 0000 0000 0000 0000 0000 0000 0000 0000
00001a0 0000 0000 0003 0007 0000 0000 0000 0000
00001b0 0000 0000 0000 0000 0008 0000 0000 0008
00001c0 0014 0000 0000 0000 0000 0000 0000 0000
00001d0 0000 0000 0003 0008 0000 0000 0000 0000
00001e0 0000 0000 0000 0000 0000 0000 0003 0006
00001f0 0000 0000 0000 0000 0000 0000 0000 0000
0000200 000e 0000 0012 0001 0000 0000 0000 0000
0000210 0028 0000 0000 0000 0013 0000 0010 0000
0000220 0000 0000 0000 0000 0000 0000 0000 0000
0000230 7400 7365 2e74 0063 6424 2400 0078 616d
0000240 6e69 7000 6972 746e 0066 0000 0000 0000
0000250 0008 0000 0000 0000 0113 0000 0005 0000
0000260 0000 0000 0000 0000 000c 0000 0000 0000
0000270 0115 0000 0005 0000 0000 0000 0000 0000
0000280 0010 0000 0000 0000 0113 0000 0005 0000
0000290 0010 0000 0000 0000 0014 0000 0000 0000
00002a0 0115 0000 0005 0000 0010 0000 0000 0000
00002b0 0018 0000 0000 0000 011b 0000 000d 0000
00002c0 0000 0000 0000 0000 001c 0000 0000 0000
00002d0 0105 0000 0002 0000 0000 0000 0000 0000
00002e0 2e00 7973 746d 6261 2e00 7473 7472 6261
00002f0 2e00 6873 7473 7472 6261 2e00 6572 616c
0000300 742e 7865 0074 642e 7461 0061 622e 7373
0000310 2e00 6f72 6164 6174 2e00 6f63 6d6d 6e65
0000320 0074 6e2e 746f 2e65 4e47 2d55 7473 6361
0000330 006b 722e 6c65 2e61 6865 665f 6172 656d
0000340 0000 0000 0000 0000 0000 0000 0000 0000
*
0000380 0000 0000 0000 0000 0020 0000 0001 0000
0000390 0006 0000 0000 0000 0000 0000 0000 0000
00003a0 0040 0000 0000 0000 0028 0000 0000 0000
00003b0 0000 0000 0000 0000 0004 0000 0000 0000
00003c0 0000 0000 0000 0000 001b 0000 0004 0000
00003d0 0040 0000 0000 0000 0000 0000 0000 0000
00003e0 0250 0000 0000 0000 0078 0000 0000 0000
00003f0 000a 0000 0001 0000 0008 0000 0000 0000
0000400 0018 0000 0000 0000 0026 0000 0001 0000
0000410 0003 0000 0000 0000 0000 0000 0000 0000
0000420 0068 0000 0000 0000 0000 0000 0000 0000
0000430 0000 0000 0000 0000 0001 0000 0000 0000
0000440 0000 0000 0000 0000 002c 0000 0008 0000
0000450 0003 0000 0000 0000 0000 0000 0000 0000
0000460 0068 0000 0000 0000 0000 0000 0000 0000
0000470 0000 0000 0000 0000 0001 0000 0000 0000
0000480 0000 0000 0000 0000 0031 0000 0001 0000
0000490 0002 0000 0000 0000 0000 0000 0000 0000
00004a0 0068 0000 0000 0000 0013 0000 0000 0000
00004b0 0000 0000 0000 0000 0008 0000 0000 0000
00004c0 0000 0000 0000 0000 0039 0000 0001 0000
00004d0 0030 0000 0000 0000 0000 0000 0000 0000
00004e0 007b 0000 0000 0000 002c 0000 0000 0000
00004f0 0000 0000 0000 0000 0001 0000 0000 0000
0000500 0001 0000 0000 0000 0042 0000 0001 0000
0000510 0000 0000 0000 0000 0000 0000 0000 0000
0000520 00a7 0000 0000 0000 0000 0000 0000 0000
0000530 0000 0000 0000 0000 0001 0000 0000 0000
0000540 0000 0000 0000 0000 0057 0000 0001 0000
0000550 0002 0000 0000 0000 0000 0000 0000 0000
0000560 00a8 0000 0000 0000 0038 0000 0000 0000
0000570 0000 0000 0000 0000 0008 0000 0000 0000
0000580 0000 0000 0000 0000 0052 0000 0004 0000
0000590 0040 0000 0000 0000 0000 0000 0000 0000
00005a0 02c8 0000 0000 0000 0018 0000 0000 0000
00005b0 000a 0000 0008 0000 0008 0000 0000 0000
00005c0 0018 0000 0000 0000 0001 0000 0002 0000
00005d0 0000 0000 0000 0000 0000 0000 0000 0000
00005e0 00e0 0000 0000 0000 0150 0000 0000 0000
00005f0 000b 0000 000c 0000 0008 0000 0000 0000
0000600 0018 0000 0000 0000 0009 0000 0003 0000
0000610 0000 0000 0000 0000 0000 0000 0000 0000
0000620 0230 0000 0000 0000 001a 0000 0000 0000
0000630 0000 0000 0000 0000 0001 0000 0000 0000
0000640 0000 0000 0000 0000 0011 0000 0003 0000
0000650 0000 0000 0000 0000 0000 0000 0000 0000
0000660 02e0 0000 0000 0000 0061 0000 0000 0000
0000670 0000 0000 0000 0000 0001 0000 0000 0000
*
0000688

連接(linking)

Linking 要解決什麼問題?考慮一個 jump 指令,如果 jump 到的 address 是寫死的,因為程式碼會變動,如果在 destination 和 source 之間又有指令被插進來,那 jump 指令中 destination 的 address 就要重新計算並更新(Relocation),如果要人工來做這件事會很麻煩。

Address and Storage Allocation Symbol Resolution Relocation

// simpleSection.c
int printf( const char* format, ...);
 
int global_init_var = 84;
int global_unit_init_var;
 
void func1(int i)
{
    printf( "%d\n", i );
}
 
 
int main(void)
{
    static int static_var = 85;
    static int static_var2 = 82;
 
    int a = 1;
    int b;
 
    func1(static_var + static_var2 + a + b);
    return a;
}
gcc -c simpleSection.c
objdump -h simpleSection.o
simpleSection.o:	file format mach-o arm64
 
Sections:
Idx Name             Size     VMA              Type
  0 __text           00000088 0000000000000000 TEXT
  1 __data           0000000c 0000000000000088 DATA
  2 __cstring        00000004 0000000000000094 DATA
  3 __compact_unwind 00000040 0000000000000098 DATA
jjlin@linjiajiadeMacBook-Air ~> objdump -h simpleSection.o

simpleSection.o:	file format mach-o arm64

Sections:
Idx Name             Size     VMA              Type
  0 __text           00000088 0000000000000000 TEXT
  1 __data           0000000c 0000000000000088 DATA
  2 __cstring        00000004 0000000000000094 DATA
  3 __compact_unwind 00000040 0000000000000098 DATA

jjlin@linjiajiadeMacBook-Air ~> objdump -s -d  simpleSection.o
simpleSection.o:	file format mach-o arm64
Contents of section __TEXT,__text:
 0000 ff8300d1 fd7b01a9 fd430091 a0c31fb8  .....{...C......
 0010 a9c35fb8 e80309aa e9030091 280100f9  .._.........(...
 0020 00000090 00000091 00000094 fd7b41a9  .............{A.
 0030 ff830091 c0035fd6 ff8300d1 fd7b01a9  ......_......{..
 0040 fd430091 bfc31fb8 28008052 e80b00b9  .C......(..R....
 0050 08000090 080140b9 09000090 290140b9  ......@.....).@.
 0060 0801090b e90b40b9 0801090b e90740b9  ......@.......@.
 0070 0001090b 00000094 e00b40b9 fd7b41a9  ..........@..{A.
 0080 ff830091 c0035fd6                    ......_.
Contents of section __DATA,__data:
 0088 54000000 55000000 52000000           T...U...R...
Contents of section __TEXT,__cstring:
 0094 25640a00                             %d..
Contents of section __LD,__compact_unwind:
 0098 00000000 00000000 38000000 00000004  ........8.......
 00a8 00000000 00000000 00000000 00000000  ................
 00b8 38000000 00000000 50000000 00000004  8.......P.......
 00c8 00000000 00000000 00000000 00000000  ................

Disassembly of section __TEXT,__text:

0000000000000000 <ltmp0>:
       0: d10083ff     	sub	sp, sp, #32
       4: a9017bfd     	stp	x29, x30, [sp, #16]
       8: 910043fd     	add	x29, sp, #16
       c: b81fc3a0     	stur	w0, [x29, #-4]
      10: b85fc3a9     	ldur	w9, [x29, #-4]
      14: aa0903e8     	mov	x8, x9
      18: 910003e9     	mov	x9, sp
      1c: f9000128     	str	x8, [x9]
      20: 90000000     	adrp	x0, 0x0 <ltmp0+0x20>
      24: 91000000     	add	x0, x0, #0
      28: 94000000     	bl	0x28 <ltmp0+0x28>
      2c: a9417bfd     	ldp	x29, x30, [sp, #16]
      30: 910083ff     	add	sp, sp, #32
      34: d65f03c0     	ret

0000000000000038 <_main>:
      38: d10083ff     	sub	sp, sp, #32
      3c: a9017bfd     	stp	x29, x30, [sp, #16]
      40: 910043fd     	add	x29, sp, #16
      44: b81fc3bf     	stur	wzr, [x29, #-4]
      48: 52800028     	mov	w8, #1
      4c: b9000be8     	str	w8, [sp, #8]
      50: 90000008     	adrp	x8, 0x0 <_main+0x18>
      54: b9400108     	ldr	w8, [x8]
      58: 90000009     	adrp	x9, 0x0 <_main+0x20>
      5c: b9400129     	ldr	w9, [x9]
      60: 0b090108     	add	w8, w8, w9
      64: b9400be9     	ldr	w9, [sp, #8]
      68: 0b090108     	add	w8, w8, w9
      6c: b94007e9     	ldr	w9, [sp, #4]
      70: 0b090100     	add	w0, w8, w9
      74: 94000000     	bl	0x74 <_main+0x3c>
      78: b9400be0     	ldr	w0, [sp, #8]
      7c: a9417bfd     	ldp	x29, x30, [sp, #16]
      80: 910083ff     	add	sp, sp, #32
      84: d65f03c0     	ret
jjlin@linjiajiadeMacBook-Air ~> objdump --syms simpleSection.o

simpleSection.o:	file format mach-o arm64

SYMBOL TABLE:
0000000000000000 l     F __TEXT,__text ltmp0
0000000000000094 l     O __TEXT,__cstring l_.str
000000000000008c l     O __DATA,__data _main.static_var
0000000000000090 l     O __DATA,__data _main.static_var2
0000000000000088 l     O __DATA,__data ltmp1
0000000000000094 l     O __TEXT,__cstring ltmp2
0000000000000098 l     O __LD,__compact_unwind ltmp3
0000000000000000 g     F __TEXT,__text _func1
0000000000000088 g     O __DATA,__data _global_init_var
0000000000000038 g     F __TEXT,__text _main
0000000000000004         *COM*	0000000000000004 _global_unit_init_var
0000000000000000         *UND* _printf