我想了解C编译
给出main.c中的简单C代码:
int main() {
int a;
a = 42;
return 0;
}
我执行了以下操作:
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
执行main.exe时出现分段错误。
在此示例中如何获得良好的内存寻址?
[当我在x86_64 Ubuntu 19.10系统上尝试从您的问题开始的命令序列时,我从ld
收到警告:
ld: warning: cannot find entry symbol _start; defaulting to 0000000000401000
这表明有问题。
错误意味着链接器未找到符号_start
,而是使用默认地址。运行程序时,它将尝试在此地址执行代码,这显然是无效的。
从C代码编译的可执行程序不只包含您的代码。编译器指示链接器添加C运行时库和启动代码。启动代码负责初始化和调用main
函数。
例如运行
gcc -v -o main.exe main.o
查看要添加到程序中的其他文件。在我的系统上,这显示了一些文件名,其名称以crt
开头,表示“ C运行时”。
如果您不使用gcc
链接程序,而是直接使用ld
,则必须以与编译器自动执行的类似方式手动添加所有必需的目标文件。