Autosar 系列教程:小柴带你学 AutoSar 总目录

# 小柴带你学 AutoSar 系列一、基础知识篇(4)编译

# GCC 编译

GCC 编译器是一个开源的编译器套件,用于编译多种编程语言,包括 C、C++、Objective-C、Fortran、Ada 等。它是一个功能强大且灵活的编译器,支持多种平台和架构。

# 1. 预处理阶段(Preprocessing)

在预处理阶段,GCC 将源代码中的预处理指令(以 # 开头的指令,如 #include#define )处理成纯 C 代码。预处理器会将头文件包含到源文件中,执行宏替换等操作。

生成的文件:通常,预处理后的文件会以 .i 扩展名保存,如 source.i

# 2. 编译阶段(Compilation)

编译阶段将预处理后的源文件翻译成汇编语言。GCC 使用的是内置的 C 编译器(称为 cc1 ),它将 C 代码转换成目标机器的汇编代码。

生成的文件:通常,编译后的文件会以 .s 扩展名保存,如 source.s

# 3. 汇编阶段(Assembly)

在汇编阶段,汇编器将汇编代码转换成机器码指令,生成目标文件。这些目标文件包含了二进制代码和相关的元数据。

生成的文件:通常,汇编后的文件会以 .o 扩展名保存,如 source.o

# 4. 链接阶段(Linking)

链接阶段将所有的目标文件(包括程序的主文件和所有的库文件)链接在一起,生成最终的可执行文件。链接器(ld)负责解析符号引用、符号重定位等任务,将各个目标文件中的代码和数据段组合成一个可执行文件。

生成的文件:最终生成的可执行文件通常没有扩展名,如 a.out

# 示例

假设有一个 C 源文件 hello.c

#include <stdio.h>
int main() {
    printf("Hello, world!\n");
    return 0;
}

通过 GCC 编译该文件时,可以执行以下命令:

gcc -o hello hello.c

这个命令会依次执行预处理、编译、汇编和链接四个阶段,并生成最终的可执行文件 hello

  • hello.i :预处理后的文件。
  • hello.s :编译后的汇编文件。
  • hello.o :汇编后的目标文件。
  • hello :最终的可执行文件。

这就是 GCC 编译器的工作过程以及每个阶段生成的文件。

# GHS 编译

RH850 是一种用于嵌入式系统的微控制器(MCU),通常用 Green Hills Software(GHS)编译工具进行编译和链接。GHS 工具链包含编译器、汇编器、链接器等,支持各种目标平台和架构。编译过程包括使用链接脚本,这是生成嵌入式系统二进制文件的关键步骤。下面是一个典型的 RH850 使用 GHS 编译器的编译过程,详细介绍了每个阶段及其生成的文件,特别是链接器脚本的作用。

# 1. 源代码准备

假设有一个简单的 C 源文件 main.c

#include <stdio.h>
void main(void) {
    printf("Hello, RH850!\n");
}

# 2. 预处理阶段

预处理器将处理所有的预处理指令,例如 #include#define ,生成一个预处理后的文件。

命令

ccrh850 -E main.c -o main.i

生成的文件

  • main.i :预处理后的文件。

# 3. 编译阶段

编译器将预处理后的 C 代码转换为汇编代码。

命令

ccrh850 -S main.i -o main.s

生成的文件

  • main.s :汇编代码文件。

# 4. 汇编阶段

汇编器将汇编代码转换为机器代码,生成目标文件。

命令

asrh850 main.s -o main.o

生成的文件

  • main.o :目标文件(对象文件)。

# 5. 链接阶段

链接器将多个目标文件和库文件链接在一起,生成可执行文件。链接器脚本在这个阶段非常重要,用于指定代码和数据段在内存中的布局。

链接器脚本(linker script)

一个典型的链接器脚本可能如下所示( linker.ld ):

SECTIONS
{
    .text : {
        *(.text)
    }
    .data : {
        *(.data)
    }
    .bss : {
        *(.bss)
    }
}

这个脚本指定了 .text 段(代码段)、 .data 段(数据段)和 .bss 段(未初始化数据段)的布局。

命令

librh850 main.o -T linker.ld -o main.elf

生成的文件

  • main.elf :最终的可执行文件(ELF 格式)。

# 总结

  • 预处理:

    ccrh850 -E main.c -o main.i
    
    • 生成预处理后的文件 main.i
  • 编译:

    ccrh850 -S main.i -o main.s
    
    • 生成汇编代码文件 main.s
  • 汇编:

    asrh850 main.s -o main.o
    
    • 生成目标文件 main.o
  • 链接:

    librh850 main.o -T linker.ld -o main.elf
    
    • 生成最终的可执行文件 main.elf ,使用链接器脚本 linker.ld 指定内存布局。

每个阶段都生成特定的中间文件和最终的可执行文件,链接器脚本在链接阶段至关重要,它定义了程序的内存布局,使得生成的二进制文件能够正确地运行在目标硬件上。

更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

flechazo 微信支付

微信支付

flechazo 支付宝

支付宝

flechazo 贝宝

贝宝