7

我想知道程序是如何工作的,所以为了尽可能地让它变得简单,我在组装上到处乱逛。

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

4

2 回答 2

8

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

  • crt1.o初始运行时代码的较新样式。包含 _start 符号,它在跳转到 libc main 之前使用 argc/argv/libc _init/libc _fini 设置 env。glibc 将此文件称为“start.S”。

  • crti.o定义函数序言;.init 部分中的 _init 和 .fini 部分中的 _fini。glibc 将此称为“initfini.c”。

  • crtn.o定义函数 Epilog。glibc 将此称为“initfini.c”。

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

于 2013-08-06T22:34:01.640 回答
-1

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

夏尔塔

于 2016-05-16T18:13:23.233 回答