C语言的hello world 下面这个是人可以阅读的。
源代码文件 a.c其实内容就是文本
#include
void main()
{
//我的第一个C语言程序
printf("helloworldn");
}
预处理这个
gcc -E a.c -o a.i处理关于
“#” 的指令 例如这个include
#include
【1】删除#define,展开所有宏定义。例#define portnumber 3333
【2】处理条件预编译 #if, #ifdef, #if, #elif,#endif
【3】处理“#include”预编译指令,将包含的“.h”文件插入对应位置。这可是递归进行的,文件内可能包含其他“.h”文件。
【4】删除所有注释。/**/,//。
【5】添加行号和文件标识符。用于显示调试信息:错误或警告的位置。
【6】保留#pragma编译器指令。(1)设定编译器状态,(2)指示编译器完成一些特定的动作。
那么预处理后的内容是什么呢? 有个 a.l 文件会生成,内容如下。已经删除了很多内容。
如果仔细分析 a.i文件中包含了 stdio.h中的内容,其实这也就是include指令的一个简单理解
# 1 "a.c"
# 1 ""
# 1 ""
# 31 ""
# 448 "/usr/include/features.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/gnu/stubs.h" 1 3 4
# 10 "/usr/include/x86_64-linux-gnu/gnu/stubs.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/gnu/stubs-64.h" 1 3 4
# 11 "/usr/include/x86_64-linux-gnu/gnu/stubs.h" 2 3 4
# 449 "/usr/include/features.h" 2 3 4
# 34 "/usr/include/x86_64-linux-gnu/bits/libc-header-start.h" 2 3 4
# 28 "/usr/include/stdio.h" 2 3 4
typedef unsigned long int __rlim64_t;
typedef unsigned int __id_t;
typedef long int __time_t;
typedef unsigned int __useconds_t;
typedef long int __suseconds_t;
typedef int __daddr_t;
typedef int __key_t;
typedef _G_fpos_t fpos_t;
# 131 "/usr/include/stdio.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/stdio_lim.h" 1 3 4
# 132 "/usr/include/stdio.h" 2 3 4
extern struct _IO_FILE *stdin;
extern struct _IO_FILE *stdout;
extern struct _IO_FILE *stderr;
extern int remove (const char *__filename) __attribute__ ((__nothrow__ , __leaf__));
extern int rename (const char *__old, const char *__new) __attribute__ ((__nothrow__ , __leaf__));
extern int renameat (int __oldfd, const char *__old, int __newfd,
const char *__new) __attribute__ ((__nothrow__ , __leaf__));
extern int ftrylockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;
extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
# 868 "/usr/include/stdio.h" 3 4
# 6 "a.c" 2
# 6 "a.c"
void main()
{
printf("helloworldn");
}
如何生成汇编代码呢>
gcc -S a.c 合集执行后会有一个 a.s文件生成,打开这个文件的内容我们年一下汇编代码
.file "a.c"
.text
.section .rodata
.LC0:
.string "helloworld"
.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
nop
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0"
.section .note.GNU-stack,"",@progbits
这篇文章写了一个简单的c语言生成汇编的指令介绍。
生成二进制文件 o但是是不能执行的
gcc -c hello.c 生成一个新文件 a.o 的obj文件..i注意obj文件是不能在操作系统上执行的。
root@-817953:~/c_pro# ./a.o
-bash: ./a.o: cannot execute binary file: Exec format error
root@hwsrv-817953:~/c_pro#
在Linux系统中,“o”指的是目标文件,即存放目标代码的计算机文件;“a”指的是静态库文件,是指要调用的函数或者过程链接到可执行文件中,成为可执行文件的一部分。
问题来了在Window或者Linux上能执行的程序是什么样的?
目标文件的格式
Linux:ELF(Executable Linkable Format)
Windows:PE(Portable Executable)
COFF格式:PE和ELF都是源自COFF格式,Unix最早是a.out文件格式,为了解决共享库问题,引入了COFF格式。
如何生成目标文件
命令 gcc a.c 会生成一个a.out的文件,这个文件才能执行。
执行程序 ./a.out 这个已经是二进制文件了。
root@hwsrv-817953:~/c_pro# ./a.out
helloworld
一堆看不懂得的内容
总结:
./ a.out'执行即可
window
s上生成exe就可以直接执行了
限时特惠:本站每日持续更新海量各大内部网赚创业教程,会员可以下载全站资源点击查看详情
站长微信:11082411