Heng30的博客
搜索 分类 关于 订阅

如何实现一个最小的C程序?

2024-09-08

最为一名无聊的程序员,总会在无聊的时候想深入了解程序启动的流程。大多数程序都是从main函数开始写代码的,就会给人一种错觉:程序执行的第一行代码应该是main函数。后面学习了链接相关的知识后发现,在执行main函数之前还有很多准备工作需要执行。加载动态库就是其中之一。

不禁会想,如何写一个最小的程序应该呢?首先是不能够使用第三方库,那就要编译成一个静态链接的程序。其次就是要让main函数成为第一个执行指令。

首先实现一个main函数作为入口函数

// bar.c

extern void foo(void);
int main(void) {
    foo();
    return 0;
}

因为不能使用第三方库,这里使用汇编来实现一个打印字符串到标准输出的函数。

# foo.s

.global foo
foo:
    movl $1, %eax       # write (
    movl $1, %edi       #   fd=1,
    movq $s, %rsi       #   buf=s,
    movl $(e-s), %edx   # count=e-s,
    syscall             # );

    movl $60, %eax      # exit (
    movl $1, %edi       #   status=1
    syscall             # );

s:
    .ascii "\033[01;31mHello, world\033[0m\n";
e:

最后是Makefile编译脚本。

#!/bin/sh

all: foobar

foobar: foo.o bar.o
    ld -e main -o $@ $^

%.o: %.c
    gcc -c -O3 $< -o $@

%.o: %.s
    as $< -o $@

clean:
    rm -f *.o foobar

ld -e main是定义程序的入口函数,可以替换成任意函数。最后出来的大小为1328个字节。