为什么汇编程序仅在与 crt1.o crti.o 和 crtn.o 链接时才起作用? [英] Why does an assembly program only work when linked with crt1.o crti.o and crtn.o?
问题描述
我想知道程序是如何工作的,所以为了让程序尽可能简单,我会在汇编中四处游荡.
I like to know how programs work so to make it as bare bones as possible I fool around with assembly.
我刚刚发现了如何使用 wprintf 函数为 x86_64 汇编代码(发现宽字符是 32 位).我所要做的就是链接到 libc (-lc).
I just found out how to assemble code for x86_64 using wprintf function (found out wide chars are 32 bit). all I had to do was link to libc (-lc).
我正在尝试为 32 位汇编代码做同样的事情,但我绊倒了很多.最终我使用 gcc 进行链接(并将 _start: 更改为 main:).然后我自己使用 ld 进行了链接,并包含了 crt1.o crti.o 和 crtn.o.然后我的程序工作了(它之前不会打印出任何东西)所以我的问题是,我可以在我的代码中做一些事情来消除对其他 3 个目标文件的需要(当然还可以恢复到 _start: 而不是 main:)?
I'm trying to assemble code for 32-bit doing about the same thing but I stumbled quite a bit. Eventually I used gcc to do the linking ( and changed the _start: to main:). So then I did the linking myself using ld and included crt1.o crti.o and crtn.o. Then my program worked ( it wouldn't print out anything before ) So my question is, can I do something within my code to eliminate the need for these other 3 object files (and of course revert back to _start: instead of 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)ま(注意没有换行,所以它在提示之前打印)
oh and the output is simply a japanese hiragana (ma)ま (notice there is no line break so it prints before the prompt)
推荐答案
以下是这些文件的作用.它们是链接到操作系统的 c 运行时环境和设置.
Here are what the files do for you. They are the c-runtime environment and setup that link to the OS.
crt1.o
初始运行时代码的较新风格.包含 _start 符号,它在跳转到 libc main 之前使用 argc/argv/libc _init/libc _fini 设置环境.glibc 将此文件称为start.S".
crt1.o
Newer style of the initial runtime code. Contains the _start symbol which sets up the env with argc/argv/libc _init/libc _fini before jumping to the libc main. glibc calls this file 'start.S'.
crti.o
定义函数prolog;.init 部分中的 _init 和 .fini 部分中的 _fini.glibc 称之为initfini.c".
crti.o
Defines the function prolog; _init in the .init section and _fini in the .fini section. glibc calls this 'initfini.c'.
crtn.o
定义函数结语.glibc 称之为initfini.c".
crtn.o
Defines the function epilog. glibc calls this 'initfini.c'.
在以下网站 http://wiki.osdev 上可以找到出色的文章和示例代码.org/Creating_a_C_Library 用于上述每个库.
There is an excellent write up and example code to be found at the following website http://wiki.osdev.org/Creating_a_C_Library for each of the libraries above.
这篇关于为什么汇编程序仅在与 crt1.o crti.o 和 crtn.o 链接时才起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!