首页 > 其他分享 >Compilation Steps and Memory Layout of the C program

Compilation Steps and Memory Layout of the C program

时间:2024-04-26 16:33:20浏览次数:24  
标签:__ Layout cfi Compilation program file world hello stage

Table of Contents

What are the four stages of the compilation process?

Normally compiling a C program is a multi-stage process and utilizes different 'tools'.

1. Preprocessing

2. Compilation

3. Assembly

4. Linking

In this post, I'll walk through each one of the four stages of compiling stages using the following C program:

/**
 *  "Hello, World!": A classic.
 * /

#include <stdio.h>

int main(void)
{
  puts("Hello, \
  World!"); // A comment
  return 0;
}

Preprocessing

The first stage of compilation is called preprocessing. In this stage, lines starting with a # character are interrupted by the preprocessor as preprocessor commands. Before interrupting the commands, the preprocessor does some initial processing. This includes joining continued lines(lines ending with a \)and stripping comments.

To print the result of the preprocessing stage, pass the -E option to cc:

cc -E hello_world.c

Given the "Hello, World!" example above, the preprocessor will produce the contents of the stdio.h header file joined with the contents of the hello_world.c file, stripped free from its leading comment.

Unlike what the author did, actually I use the command

gcc -E hello_world.c > hello_world.i

here, which means to save the result of the preprocessing stage to a file named hello_world.i

with the processed file hello_world.i, we can see the result as below:

... // lines omitted for brevity
# 501 "d:\\mingw\\include\\stdio.h" 3
__attribute__((__cdecl__)) __attribute__((__nothrow__)) __attribute__((__format__(__mingw_printf__,3,4)))
int snprintf (char *, size_t, const char *, ...);
... // lines omitted for brevity
 # 3 "hello_world.c"
int main(void)
{
  puts("Hello,   World!");
  return 0;
}

Comparing to the content from the original file hello_world.c, in the processed file hello_world.i, we can see that the continued lines are joined into one line, and the comments are removed.

Compilation

The second stage of compilation is confusingly enough called compilation. In this stage, the preprocessed code is translated to assembly instructions specific to the target processor architecture. These form an intermediate human-readable language.

The existence of this step allows for C code to contain inline assembly instructions and for different assemblers to be used.

Some compilers also support the use of an integrated assembler, in which the compilation stage generates
machine code directly, avoiding the overhead of generating the intermediate assembly instructions and invoking the assembler.

To save the result of the compilation stage, pass the -c option to cc:

cc -S hello_world.c

This will create a file named hello_world.s, containing the generated assembly instructions. On Mac OS 10.10.4, where cc is an alias for clang, the following output is generated:

.section    __TEXT,__text,regular,pure_instructions
   .macosx_version_min 10, 10
   .globl  _main
   .align  4, 0x90
_main:                                  ## @main
   .cfi_startproc
## BB#0:
   pushq   %rbp
Ltmp0:
   .cfi_def_cfa_offset 16
Ltmp1:
   .cfi_offset %rbp, -16
   movq    %rsp, %rbp
Ltmp2:
   .cfi_def_cfa_register %rbp
   subq    $16, %rsp
   leaq    L_.str(%rip), %rdi
   movl    $0, -4(%rbp)
   callq   _puts
   xorl    %ecx, %ecx
   movl    %eax, -8(%rbp)          ## 4-byte Spill
   movl    %ecx, %eax
   addq    $16, %rsp
   popq    %rbp
   retq
   .cfi_endproc
   .section    __TEXT,__cstring,cstring_literals
L_.str:                                 ## @.str
   .asciz  "Hello, World!"
.subsections_via_symbols

I use gcc instead of clang on my pc. So I use command with the option -S to generate the assembly code like this

gcc -S hello_world.c
After that, I can see the assembly code in the file hello_world.s. Lets take a look the content of the file as below.

.file	"hello_world.c"
  .def	___main;	.scl	2;	.type	32;	.endef
  .section .rdata,"dr"
LC0:
  .ascii "Hello,   World!\0"
  .text
  .globl	_main
  .def	_main;	.scl	2;	.type	32;	.endef
_main:
LFB10:
  .cfi_startproc
  pushl	%ebp
  .cfi_def_cfa_offset 8
  .cfi_offset 5, -8
  movl	%esp, %ebp
  .cfi_def_cfa_register 5
  andl	$-16, %esp
  subl	$16, %esp
  call	___main
  movl	$LC0, (%esp)
  call	_puts
  movl	$0, %eax
  leave
  .cfi_restore 5
  .cfi_def_cfa 4, 4
  ret
  .cfi_endproc
LFE10:
  .ident	"GCC: (MinGW.org GCC-6.3.0-1) 6.3.0"
  .def	_puts;	.scl	2;	.type	32;	.endef

Assembly

During the assembly stage, an assembler is used translate the assembly instructions to machine code, or or object code.. The output consists of actual instructiosn to be run by the target processor.

To save the result the of the assembly stage, pass the -c option to cc:

cc -c hello_world.c

Running the above command will create a file named hello_world.o, containing the object code of the program. The contents of this file are in a binary format and can be inspected using a hexdump or od by running either one of the following commands:

hexdump hello_world.o
od -c hello_world.o

Linking

The object code generated in the assembly stage is composed of machine instructions that the processor understands but some pieces of the program are out of order or missing. To produce an executable program, the existing pieces have to be rearranged and the missing ones filled in. This process is called linking.

Let's assume your project contains two(hello.c and world.c)source files. So, when you complie the project, the assembler will give you hello.o and world.o object files. In the end, we need only one binary file that has to be loaded into the target processor or controller. So, the linker will arrange those hello.o and world.o, gives a single binary file.

That's why you will get an error from the linker when you are calling the function which is not defined anywhere. Linker tries to find that function in ohter source files and throws an error if it couldn't find that.

The linker will arrange the pieces of object code so that functions in some pieces can successfully call functions in other pieces. It will also add pieces containing the instructions for library functions used by the program. In the case of the “Hello, World!” program, the linker will add the object code for the puts function.

The result of this stage is the final executable program. When run without options, cc will name this file a.out. To name the file something else, pass the -o option to cc:

cc -o hello_world hello_world.c

For your quick reference:

compilation steps of c program

标签:__,Layout,cfi,Compilation,program,file,world,hello,stage
From: https://www.cnblogs.com/archerqvq/p/18160008

相关文章

  • 【翻译】RISC-V裸机编程指南(Bare metal programming with RISC-V guide)
    RISC-V裸机编程指南(BaremetalprogrammingwithRISC-Vguide)作者:Follow@popovicu94原文链接:https://popovicu.com/posts/bare-metal-programming-risc-v/今天,我们将探讨如何为RISC-V架构的机器编写一个裸机程序。为了确保可复现,目标平台选择为QEMUriscv64virt虚拟机......
  • 2022 China Collegiate Programming Contest (CCPC) Mianyang | 2022 CCPC 绵阳(MAED
    搬运自本人知乎文章。https://zhuanlan.zhihu.com/p/588646549M.Rock-Paper-ScissorsPyramid题目链接Problem-M-Codeforces题意有一个长度为\(n\)的石头剪刀布序列,每个元素是RPS(石头、布、剪刀)中的一个,我们需要用这个序列构造一个三角,三角的底层为这个序列,第\(i(......
  • Cadence Virtuoso 打开 Layout 显示 undefined packet
    软件版本:IC617操作系统:CentOS解决办法:临时方法打开layout后。按住shift,点选左边layers窗口中的任一层次,弹出displayResourceEditor窗口。file->load。选择需要的drf文件加载即可。永久方法把display.drf文件复制到你的virtuoso启动目录即可参考链接......
  • The 18-th Beihang University Collegiate Programming Contest (BCPC 2023) - Final
    https://codeforces.com/gym/104883A#include<bits/stdc++.h>usingnamespacestd;usingi32=int32_t;usingi64=longlong;usingvi=vector<int>;i32main(){ios::sync_with_stdio(false),cin.tie(nullptr);i64n,sum=0;c......
  • Bulk端不接到地的NMOS,怎么画Layout?(搬运自LayoutArt)
    在上图中,红圈中的NMOS,它们的Bulk端没有接到地,而是接到各自的Source端,这种情况下,Layout应该怎么画呢?首先,大致了解NMOS的Bulk端为什么不接地,而是接到Source?在有些电路设计中,NMOS的Vth太大,NMOS管不能正常工作,为了减少Vth(阈值电压),可能会使用低Vth的NMOS,在工艺允许时,也可能使用减少体......
  • POI2011PRO-Programming Contest
    POI#Year2011#Dinic#网络流#贪心容易想到拆点的费用流做法,但是二分再拆点的时间复杂度是不可接受的考虑因为每个的时间\(r\)是定值,所以不可能出现做题个数差超过\(1\)的情况所以每一轮每个分配一个,用\(Dinic\)在推进一次,知道满流//Author:xiaruizeconstintN=......
  • The 18th Zhejiang Provincial Collegiate Programming Contest
    目录写在前面AMLCIJFGD写在最后写在前面比赛地址:https://codeforces.com/gym/103055。以下按个人难度向排序。唐唐唐唐唐,又是死在数学手上的一次。妈的为什么上个大学这么累好相似A签到。///*By:Luckyblock*/#include<bits/stdc++.h>#defineLLlonglong//=======......
  • useEffect useLayoutEffect
    useEffectuseEffect接收两个参数:一个函数和一个依赖数组。2.useEffect(callback):fontcolor=red>这个参数表示只要组件发生更新,就会执行回调函数callback,包括组件挂载时的初始化和后续状态或属性的更新。如果不需要依赖任何状态或属性,相当于类组件中的componentDidMount和......
  • JSNice:Predicting Program Properties from “Big Code”
    发表:ACMSIGPLANNotices,2015,苏黎世联邦理工学院计算机科学系SoftwareReliabilityLab,AndreasKrause团队(https://scholar.google.com/citations?user=eDHv58AAAAAJ)(https://www.sri.inf.ethz.ch/research/plml)工具:http://jsnice.org内容概括  文章通过“大代码”......
  • The 2023 ICPC Asia Hong Kong Regional Programming Contest (The 1st Universal Cup
    Preface不知道VP什么就继续找往年的区域赛真题来打了这场题挺合我们队口味的,开场2h就开出了5题(徐神110min的时候就过相对最难的C题),而且手上还有3个会写的题最后中间虽然因为F题卡常(CF评测机太慢导致的)浪费了快1h时间,但索性时间剩余很多还是4h下班了后面的题感觉都不太可做,遂光......