当前位置: 代码迷 >> 综合 >> 温故而知新--a.out
  详细解决方案

温故而知新--a.out

热度:36   发布时间:2024-01-29 20:39:11.0

1. 前世今生

    a.out  ---- assembler output  汇编程序输出(其实该叫链接器输出)

早起程序创建时还没有连接器,汇编后时直接保存到a.out里的,就算后来有了链接器,也就沿用了这个叫法

2. 怎么出生滴

    首先写个小程序 t1.c

#include <stdio.h>#define WORD "Hello World"#ifdef TEST
#define PRE_WORD "We Say"
#else
#define PRE_WORD "I Say"
#endifint main(void){//Do who need say Hello Worldprintf("%s: %s\n", PRE_WORD, WORD);return 0;
}

    2.1 其次用这个命令预处理一下

gcc -E t1.c -o t1.i //只进行预编译

    

    可以看出,预处理做了哪些事情

    ----处理#include指令,将被包含的头文件插入

    ----删除#define宏,并将定义展开

    ----处理条件编译

    ----删除注释

    这几个都是比较明显的处理,还有一些其他的处理,留作思考题吧

    2.2 再用这个命令编译

gcc -S t1.c -o t1.s //编译
	.file	"t1.c".text.section	.rodata
.LC0:.string	"Hello World"
.LC1:.string	"I Say"
.LC2:.string	"%s: %s\n".text.globl	main.type	main, @function
main:
.LFB0:.cfi_startprocpushq	%rbp.cfi_def_cfa_offset 16.cfi_offset 6, -16movq	%rsp, %rbp.cfi_def_cfa_register 6leaq	.LC0(%rip), %rdxleaq	.LC1(%rip), %rsileaq	.LC2(%rip), %rdimovl	$0, %eaxcall	printf@PLTmovl	$0, %eaxpopq	%rbp.cfi_def_cfa 7, 8ret.cfi_endproc
.LFE0:.size	main, .-main.ident	"GCC: (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0".section	.note.GNU-stack,"",@progbits

    此时,已经将代码由文本语言转换成机器语言了,主要做了这些事

    ----词法分析

    ----语法分析

    ----语义分析

    ----目标文件的优化和生成

    2.3 继续用命令处理

gcc -c t1.i -o t1.o

    此时汇编过程已经结束,生成了目标文件.o,但此时还不能正常运行.o文件,加了权限也不行

    

objdump -t t1.o //查看生成的符号表
t1.o:     file format elf64-x86-64SYMBOL TABLE:
0000000000000000 l    df *ABS*	0000000000000000 t1.c
0000000000000000 l    d  .text	0000000000000000 .text
0000000000000000 l    d  .data	0000000000000000 .data
0000000000000000 l    d  .bss	0000000000000000 .bss
0000000000000000 l    d  .rodata	0000000000000000 .rodata
0000000000000000 l    d  .note.GNU-stack	0000000000000000 .note.GNU-stack
0000000000000000 l    d  .eh_frame	0000000000000000 .eh_frame
0000000000000000 l    d  .comment	0000000000000000 .comment
0000000000000000 g     F .text	000000000000002a main
0000000000000000         *UND*	0000000000000000 _GLOBAL_OFFSET_TABLE_
0000000000000000         *UND*	0000000000000000 printf

    2.4 最后还得转换成二进制才能执行

gcc t1.o -o a.out

    

    当然,这个a.out是手动写的,但实际情况中是系统自动生成滴