【问题标题】:Why does an assembly program only work when linked with crt1.o crti.o and crtn.o?为什么汇编程序只有在与 crt1.o crti.o 和 crtn.o 链接时才能工作?
【发布时间】:2013-08-08 03:01:09
【问题描述】:

我想知道程序是如何工作的,所以我尽可能地把它变成了简单的框架。

我刚刚发现了如何使用 wprintf 函数为 x86_64 汇编代码(发现宽字符是 32 位的)。我所要做的就是链接到 libc (-lc)。

我正在尝试为 32 位汇编代码做同样的事情,但我绊倒了很多。最终我使用 gcc 进行链接(并将 _start: 更改为 main:)。因此,我使用 ld 自己进行了链接,并包括 crt1.o crti.o 和 crtn.o。然后我的程序工作了(之前它不会打印出任何东西)所以我的问题是,我可以在我的代码中做些什么来消除对其他 3 个目标文件的需要(当然恢复到 _start: 而不是 main:) ?

test_lib.S

.section .data
locale:
  .string ""
  .align 4
printformat:
  .long '%','l','c',0

.section .text
.global main
main:

pushl   $locale
pushl   $6
call    setlocale
pushl   $12414
pushl   $printformat
call    wprintf
pushl   $2
call    exit

并运行以下

as --32 test_lib.S -o test_lib.o
ld -m elf_i386 -L/lib/ -L/usr/lib/ -I/lib/ld-linux.so.2 /usr/lib/crt1.o /usr/lib/crti.o -lc /usr/lib/crtn.o test_lib.o -o test_lib
./test_lib

哦,输出只是一个日语平假名(ma)ま(注意没有换行符,所以它在提示符之前打印)

【问题讨论】:

标签: assembly linker x86 32-bit


【解决方案1】:

以下是这些文件为您做的事情。它们是链接到操作系统的 c 运行时环境和设置。

  • crt1.o 初始运行时代码的更新样式。包含 _start 符号,它在跳转到 libc main 之前使用 argc/argv/libc _init/libc _fini 设置 env。 glibc 将此文件称为“start.S”。

  • crti.o定义函数prolog; .init 部分中的 _init 和 .fini 部分中的 _fini。 glibc 将此称为“initfini.c”。

  • crtn.o 定义函数 Epilog。 glibc 将此称为“initfini.c”。

对于上述每个库,可以在以下网站http://wiki.osdev.org/Creating_a_C_Library 找到出色的文章和示例代码。

【讨论】:

  • 好吧,您的链接显示了我所缺少的很多内容。不幸的是,它基于 x86_64 的调用约定。我想知道 argc 和 argv 应该在 32 位程序中的什么位置。另外,为什么我的 64 位程序不需要这些文件,而我的 32 位程序却需要这些文件?
  • 我会假设 32 与 64 链接器使用不同的默认值,但我不确定。我遇到了工具链中链接器之间的差异。
  • 在没有 libc 的情况下编译 (stackoverflow.com/questions/2548486/compiling-without-libc) 有更多有用的信息。
  • GNU Libc 库中的 libc-start.c 将是您为上述 CRT(c 运行时)代码寻找的 32 代码的良好起点。
  • 具体来说,crtn.o 完成了在 crti.o 中开始的 .init 和 .fini 部分。它对这两个部分所做的只是将堆栈指针弹出一次。
【解决方案2】:

在 3 位 Linux 中,它们位于堆栈中。启动时,0(%esp) 包含 argc。在 4(%esp) 处,您将找到指向程序名称的指针(包含在 argc 中)。之后是指向参数的指针数组,以 NULL 指针结束。之后是另一个以 NULL 结尾的指向系统变量的指针数组。听说可能有200多个!!

夏尔塔

【讨论】:

  • 问题不是询问 argc 或 argv,所以从代词“他们”开始是没有意义的。已经有问答展示了如何从 _start 获取 argc 和 argv 以及 envp。
猜你喜欢
  • 2014-01-15
  • 2014-03-10
  • 1970-01-01
  • 1970-01-01
  • 2011-02-12
  • 1970-01-01
  • 1970-01-01
  • 2020-07-24
  • 1970-01-01
相关资源
最近更新 更多