assembly - 为什么汇编程序仅在与 crt1.o crti.o 和 crtn.o 链接时才起作用?

标签 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)ま(注意没有换行符,所以它在提示之前打印)

最佳答案

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

  • crt1.o初始运行时代码的较新样式。包含 _start 符号,它在跳转到 libc main 之前使用 argc/argv/libc _init/libc _fini 设置环境。 glibc 将此文件称为“start.S”。
  • crti.o定义函数序言; .init 部分中的 _init 和 .fini 部分中的 _fini。 glibc 称之为“initfini.c”。
  • crtn.o定义函数结语。 glibc 称之为“initfini.c”。

  • 在以下网站 http://wiki.osdev.org/Creating_a_C_Library 上可以找到出色的编写和示例代码。对于上面的每个库。

    关于assembly - 为什么汇编程序仅在与 crt1.o crti.o 和 crtn.o 链接时才起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18091463/

    相关文章:

    c - get_sp() 函数如何工作?

    c++ - 静态或动态链接 CRT、MFC、ATL 等

    c - 了解现有 C 程序的编译和链接

    c - 为什么 mod 2^n 对有符号数使用 CLTD 指令

    linux - 将 16 位 DOS x86 程序集移植到 32 位 Linux x86 程序集

    c++ - 如何不优化 - 愚蠢函数的机制

    c - 链接器如何解析 C 中多重定义的全局符号

    c - _builtin_prefetch()中第二个参数的作用是什么?

    assembly - NASM 中的 .bss 部分中声明的变量是否会加载到进程的数据部分而不是进程的 bss 部分?

    c - x86 过程调用内存分配