当前位置: 首页 > news >正文

制作一个RISC-V的操作系统三-编译与链接

文章目录

  • GCC
    • GCC简介
    • GCC的命令格式
    • gcc -E
    • gcc -c
    • gcc -S
    • gcc -g
    • gcc -v
    • GCC的主要执行步骤
    • GCC涉及的文件类型
    • 针对多个源文件的处理
  • ELF
    • ELF介绍
    • ELF文件格式
    • ELF文件处理相关工具:Binutils(binary utility)
      • readlelf -h
      • readelf -S或readelf -SW(加W显示变宽)
      • objdump -S
  • 练习 3-1
  • 练习 3-2

GCC

GCC简介

在这里插入图片描述

GCC的命令格式

预处理: 把#define #include 这些#开头的宏语言转为标准的C语言
编译:C语言变成机器指令
链接:把编译后的指令文件与其他库链接到一块
调试需要加入调试信息

建议实战一下,观察区别
在这里插入图片描述
如该程序
在这里插入图片描述

gcc -E

当预处理该文件时并且将输出结果输出到E文件
在这里插入图片描述
打开E文件
在这里插入图片描述
可以看到代码非常多,但最后的main函数没有变化。上面的代码就是#include<stdio.h>转换为C语言的结果

gcc -c

生成的可执行文件,但还没有链接
在这里插入图片描述
在这里插入图片描述

gcc -S

在这里插入图片描述
打开S文件查看,为汇编语言
在这里插入图片描述

gcc -g

在这里插入图片描述

gcc -v

可以看到一大串相关信息
在这里插入图片描述

GCC的主要执行步骤

Linux mv(英文全拼:move file)命令用来为文件或目录改名、或将文件或目录移入其它位置。

在这里插入图片描述
在这里插入图片描述

cc1:预处理和编译
在这里插入图片描述
as:生成O文件 机器指令

在这里插入图片描述
collect中有ld 链接
将各种标准库和O文件链接在一起
在这里插入图片描述

GCC涉及的文件类型

小写s:不包含#开头的代码
大写S:还包含#开头的代码
可执行文件默认为a.out
在这里插入图片描述

针对多个源文件的处理

在这里插入图片描述

ELF

ELF介绍

可重定位文件:链接才能把位置定下来
核心转储文件:程序崩溃时相关信息
在这里插入图片描述

ELF文件格式

二进制
ELF Header: ELF文件的基本信息 (如运行在哪种体系架构 版本号)
.text: 程序的指令
.init:程序初始化的指令
4K字节对齐
Programe Header Table:运行时用到,将哪些节放到一起合成段,段放哪里
Section Header Table:节的一些信息,定位之类的
在这里插入图片描述

ELF文件处理相关工具:Binutils(binary utility)

ar=tar:生成静态库要用到

在这里插入图片描述

readlelf -h

查看文件头 ELF-header
在这里插入图片描述

  • Magic:魔术 没啥大用,就是给ELF做一个特殊的标志,和别的东西区分开来

  • Class:文件类型 64位还是32位

readelf -S或readelf -SW(加W显示变宽)

查看Section Header Table
PROGBITS:可执行执行的意思
RELA:可重定位的
在这里插入图片描述

objdump -S

-S是将汇编显示源代码部分

此时反汇编结果中没有源码部分显示
在这里插入图片描述
当编译时加上-g后 (生成调试信息)再反汇编发现源码和汇编指令
在这里插入图片描述

练习 3-1

  • 使⽤ gcc 编译代码并使⽤ binutils ⼯具对⽣成的⽬标文件和可执⾏文件(ELF 格式)进⾏分析。具体要求如下:
  • 编写⼀个简单的打印 “hello world!” 的程序源文件:hello.c
    对源文件进⾏本地编译,⽣成针对⽀持 x86_64 指令集架构处理器的⽬标文件 hello.o。
  • 查看 hello.o 的文件的文件头信息。
  • 查看 hello.o 的 Section header table。
  • 对 hello.o 反汇编,并查看 hello.c 的 C 程序源码和机器指令的对应关系。

练习 3-2

如下例⼦ C 语⾔代码

#include <stdio.h>
int global_init = 0x11111111;
const int global_const = 0x22222222;
void main()
{
static int static_var = 0x33333333;
static int static_var_uninit;
int auto_var = 0x44444444;
printf("hello world!\n");
return;
}
  • 请问编译为可执行文件后,global_init, global_const, static_var, static_var_uninit, auto_var 这些变量分别存放在那些 section ⾥
  • “hello world!\n” 这个字符串⼜在哪⾥?并尝试⽤⼯具查看并验证你的猜想
    在这里插入图片描述
    在这里插入图片描述
    auto_var变量 和"hello world!\n" 这个字符串在栈中,需要程序运行时才会有
    可以根据地址来判断从属于哪个节
    在这里插入图片描述
    在这里插入图片描述
http://www.lryc.cn/news/255535.html

相关文章:

  • tmux工具--程序部署在服务器上持久化执行
  • C语言精选——选择题Day39
  • React 笔记 jsx
  • QMenu风格设计qss+阴影
  • temu防窒息警示语贴哪里
  • Maven——坐标和依赖
  • Python中事务的常见用法
  • 蛮力法最大值连续子序问题
  • 多功能智能遥测终端机 5G/4G+北斗多信道 视频采集传输
  • 1.查看表的基本结构,表的详细结构和修改表名
  • Mybatis实用教程之XML实现动态sql
  • 混合App开发实现页面跳转(更新中)
  • 【FPGA】Verilog:BCD 加法器的实现
  • 机器学习第15天:GBDT模型
  • STM32F407-14.3.9-01输出比较模式
  • LeetCode题:174. 地下城游戏
  • CSS、JS文件无法正确加载至页面问题与解决
  • ftp的服务安装配置
  • 原码,补码,反码(极简版)
  • uniapp监听wifi连接状态
  • 2023年总结和2024年展望(以ue为主攻)
  • 南京大学计算机学院面试准备
  • API成批分配漏洞介绍与解决方案
  • 跨网文件摆渡系统:安全、可控的数字传输桥梁
  • 线程池的原理和基本使用~
  • PyTorch2.0环境搭建
  • figma 基础使用 —— 常用方法
  • linux rsync 和scp区别
  • mac如何永久设置环境变量
  • 小程序一键生成工具哪个好?