Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 手动创建和运行可执行文件_C_Assembly_Compiler Construction - Fatal编程技术网

C 手动创建和运行可执行文件

C 手动创建和运行可执行文件,c,assembly,compiler-construction,C,Assembly,Compiler Construction,出于兴趣,我想手工编译和运行最简单的C程序 //t.c int main() { return 0; } 所以我想做: $cpp t.c:在这种情况下不应执行任何操作,因为不需要进行预处理 $cc1 t.c:应编译t.c->t.s $as-o t.o t.c:应安装t.s->t.o $ld t.o:应生成可执行的a.out(无需执行任何操作) 我遇到的问题是as,因为运行最后一个命令会产生: ld: warning: cannot find entry symbol _st

出于兴趣,我想手工编译和运行最简单的C程序

//t.c

int main() {
       return 0;
}
所以我想做:

  • $cpp t.c
    :在这种情况下不应执行任何操作,因为不需要进行预处理
  • $cc1 t.c
    :应编译
    t.c
    ->
    t.s
  • $as-o t.o t.c
    :应安装
    t.s
    ->
    t.o
  • $ld t.o
    :应生成可执行的
    a.out
    (无需执行任何操作)
我遇到的问题是
as
,因为运行最后一个命令会产生:

ld: warning: cannot find entry symbol _start; defaulting to 00000000000400b0

发生什么事了?我故意省略了
libc
,以尽可能地简化它,但我不明白发生了什么。我缺少什么标志?

加载和执行程序还有更多的内容。从链接器输出可以猜到,执行不是从
main
开始,而是从
\u start
开始,这是由CRT(C运行时)库提供的,该库与编译器捆绑在一起,并在后台与代码链接

下面是一些关于Linux上程序启动的概述


在虚拟源代码上执行
cc-v-Wall
,查看所有需要的详细步骤。

既然你说的是最简单的程序,下面是一个真正的黑客程序

这是针对运行x86_64的Ubuntu 12.04的。如果你还有别的事情,那么这可能会给你一个提示

mkdir hack_code
cd hack_code
cp /usr/lib/ldscripts/elf_x86_64.x ldsimple.x
现在将
ldsimple.x
修改为
ENTRY(main)
而不是开头的
ENTRY(\u start)

创建这个
mymain.c

int main(void)
{
    __asm__ __volatile__ (
        "movq $60, %rax\n"  /* call sys_exit */
        "movq $2,  %rdi\n"  /* return code   */
        "syscall"           /* call kernel to exit program */
    );
    return 0;
}
然后:

gcc -c mymain.c
ld -o mymain -T./ldsimple.x mymain.o

瞧:你现在有了一个不使用任何库等的程序。

哦,我需要链接到
crt1.o
?是的,crt1.o将提供_start,你真的应该在预处理后有一个中间文件,因为它是预处理程序,将删除顶部的注释(虽然传递它可能不会影响下一次传递)。@LeeDanielCrocker的确,编译器接受仍然包含注释的“预处理”文件。如果出于某种原因需要,GCC的预处理器甚至可以将它们保留在其中。非常好的链接。非常感谢。这正是我想要的。