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

Cra*_*aig 7 x86 assembly linker 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
Run Code Online (Sandbox Code Playgroud)

并运行以下

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
Run Code Online (Sandbox Code Playgroud)

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

小智 9

以下是文件为您执行的操作.它们是链接到OS的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上找到优秀的编写和示例代码.