一步一步的C编译导致segfault

joh*_*nnn 4 c linux compilation ld

我正在尝试理解 C 编译

鉴于 main.c 中的这个简单的 C 代码:

int main() {
    int a;
    a = 42;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我执行了以下操作:

cpp main.c main.i
/usr/lib/gcc/x86_64-linux-gnu/9/cc1 main.i -o main.s
as -o main.o main.s
ld -o main.exe main.o
Run Code Online (Sandbox Code Playgroud)

执行 main.exe 时,出现分段错误。

在这个例子中我怎样才能得到一个好的内存寻址?

Bod*_*odo 7

当我在 x86_64 Ubuntu 19.10 系统上尝试您的问题中的命令序列时,我收到一条警告ld

ld: warning: cannot find entry symbol _start; defaulting to 0000000000401000
Run Code Online (Sandbox Code Playgroud)

这表明出现了问题。

该错误意味着链接器没有找到符号_start,而是使用了默认地址。当运行你的程序时,它会尝试在这个显然无效的地址执行代码。

从 C 代码编译的可执行程序不仅仅包含您的代码。编译器指示链接器添加 C 运行时库和启动代码。启动代码负责初始化和调用您的main函数。

运行例如

gcc -v -o main.exe main.o
Run Code Online (Sandbox Code Playgroud)

查看哪些其他文件被添加到您的程序中。在我的系统上,这显示了一些名称以crt“C 运行时”开头的文件。

如果您不使用gcc链接程序而是ld直接使用,则必须以类似于编译器自动执行的方式手动添加所有必需的目标文件。