为什么汇编程序仅在与crt1.o crti.o和crtn.o链接时才有效?

时间:2013-08-06 22:14:10

标签: assembly linker x86 32-bit

我想知道程序是如何工作的,以便尽可能地让它成为一块骨头。我在组装时愚弄。

我刚刚发现了如何使用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)ま(注意没有换行符,所以它在提示之前打印)

2 个答案:

答案 0 :(得分:9)

以下是文件为您所做的事情。它们是链接到操作系统的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找到优秀的代码和示例代码。

答案 1 :(得分:-1)

在3位Linux中,它们位于堆栈中。启动时,0(%esp)包含argc。在4(%esp),你会找到一个指向程序名称的指针(包含在argc中)。之后是一个指向参数的指针数组,以NULL指针结束。之后是另一个NULL结束的系统变量指针数组。我被告知可能有超过200个!!

Shiarta