我想知道程序是如何工作的,这样我就可以尽可能地把它弄得简单粗暴,我在组装时到处乱搞。
我刚刚发现了如何使用 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/