• Linux程序编译的过程


    编译过程

    c,c++代表的高层语言编写的程序在转化成为处理器可以识别并且执行的二级制代码的过程
    在这里插入图片描述

    预处理Preprocessing

    编译Compilation

    汇编Assembly

    链接Linking

    GCC 工具链介绍

    GCC 编译工具

    Binutils 二进制程序处理器

    C运行库 语法 + 标准库

    编写 hello 程序

    #include
    
    int main(void){
    	printf("Hello World\n");
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    gcc 将源文件进行预处理,将生成预处理文件

    -E 源程序预处理之后停止

    [root@localhost test]# gcc -E hello.c -o hello.i
    [root@localhost test]# ls
    demo01.sh  hello.c  hello.i
    [root@localhost test]# cat hello.i
    
    • 1
    • 2
    • 3
    • 4

    查看hello.i文件

    在这里插入图片描述

    编译,将预处理生成的我呢间编译成汇编文件hello.s

    -S gcc执行编译后停止,生成汇编程序

    [root@localhost test]# gcc -S hello.i -o hello.s
    [root@localhost test]# ls
    demo01.sh  hello.c  hello.i  hello.s
    [root@localhost test]# cat hello.s
    	.file	"hello.c"
    	.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
    	movl	$.LC0, %edi
    	call	puts
    	movl	$0, %eax
    	popq	%rbp
    	.cfi_def_cfa 7, 8
    	ret
    	.cfi_endproc
    .LFE0:
    	.size	main, .-main
    	.ident	"GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-44)"
    	.section	.note.GNU-stack,"",@progbits
    [root@localhost test]# 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    汇编,将生成的汇编程序hello.s生成hello.o目标文件

    -c,汇编之后停止,生成目标文件

    或者直接使用 as 代替 gcc 命令进行汇编,asBinutils中的命令

    [root@localhost test]# gcc -c hello.s -o hello.o
    [root@localhost test]# ls
    demo01.sh  hello.c  hello.i  hello.o  hello.s
    [root@localhost test]# cat hello.o                                                                                                                 ELF>@@
    UH怨¸]ello WorldGCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-44)zRx 
    P                                                             C
    򽁁       hello.cmainputs
    
     
    񁀿ÿÿ .symtab.strtab.shstrtab.rela.text.data.bss.rodata.comment.note.GNU-stack.rela.eh_frame @忰                                                     &UU1U
        90a.BWR@                                                                                                                                       
                                                                                                                                                       ΁0a[root@localhost test]# XshellXshellXshell
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    此时生成的hello.o文件是ELF文件,就是执行连接格式的可重定向文件

    链接

    静态连接,在编译阶段直接将静态库直接添加到可执行文件中去

    [root@localhost test]# gcc -static hello.c -o staticHello
    [root@localhost test]# size staticHello 
       text	   data	    bss	    dec	    hex	filename
     771320	   6196	   8640	 786156	  bfeec	staticHello
    [root@localhost test]# ldd staticHello 
    	不是动态可执行文件
    [root@localhost test]# 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    动态链接,在链接阶段,把需要的动态库加入到内存中去

    使用了动态链接,使用 size 命令可以看到可执行文件的大小,ldd可以看到链接的其他glibc的动态库

    [root@localhost test]# gcc hello.c -o hello
    [root@localhost test]# size hello
       text	   data	    bss	    dec	    hex	filename
       1226	    548	      4	   1778	    6f2	hello
    [root@localhost test]# ldd hello
    	linux-vdso.so.1 =>  (0x00007ffdae1aa000)
    	libc.so.6 => /lib64/libc.so.6 (0x00007f92b215a000)
    	/lib64/ld-linux-x86-64.so.2 (0x00007f92b2528000)
    [root@localhost test]# 
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    分析ELF文件

    ELF 文件的段

    text,已编译程序的指令代码段

    rodata,只读数据

    data,初始化后的C程序全局变量和静态局部变量

    debug,调试符号表

    在这里插入图片描述

    使用readelf -S查看每个段的信息
    在这里插入图片描述

    反编译ELF文件,可以查看ELF文件的指令和数据

    objdump -D hello
    
    • 1

    在这里插入图片描述
    反编译并且和C源码混合显示

    [root@localhost test]# gcc -o hello -g hello.c
    [root@localhost test]# objdump -S hello
    
    
    • 1
    • 2
    • 3

    在这里插入图片描述

    Linux 基本命令

    安装和登录的命令

    login,shutdown,halt,reboot,install,mount,unmount,chsh,exit,last,init 0,init 6

    cat 查看文件的内容

    mv 移动文件和重命名

    chmod 修改权限

    rm 删除文件

    rmdir 删除目录

    man 帮助文档

    –help 帮助手册

    tar 解压缩

    su ,sudo 切换用户,sudo 命令需要输入当前用户的密码,su 命令需要输入 root 用户的密码

    • su root 输入root密码后切换之root用户但是pwd目录不变

    • su - root 输入root密码后切换之root用户但是pwd目录/root

    • sudo 命令只允许使用提升的权限运行单个命令,而 su 命令会启动一个新的 shell,同时允许使用 root 权限运行尽可能多的命令,直到明确退出登录。

    df 磁盘剩余

    grep,find,awk 文本查找三剑客

    umask 掩码

    ln 创建链接

    who 查看当前系统使用者

    ping 查看所给的URL是否正常通信

    mkdir 创建文件夹

    touch 创建文件

    vim,vi 文本编辑器

  • 相关阅读:
    Flink / Scala - 使用 CountWindow 实现按条数触发窗口
    【吴恩达机器学习笔记】八、应用机器学习的建议
    Kafka 3.3.1 Kraft 多端口协议搭建
    手术机器人工程师面试题目
    WX小程序的常用知识点总结
    C++类和对象(上)
    【动手学深度学习-Pytorch版】Transformer代码总结
    变化数据捕获(CDC)技术分类优劣与适用场景
    list
    VUE系列 ---- 网络模块axios(一 )
  • 原文地址:https://blog.csdn.net/qq_46724069/article/details/127848626