7

私はプログラムがどのように機能するかを知りたいので、できるだけ骨の折れるようにするために、アセンブリをいじっています。

wprintf 関数を使用して x86_64 のコードをアセンブルする方法を見つけました (ワイド文字は 32 ビットであることがわかりました)。私がしなければならなかったのは、libc (-lc) にリンクすることだけでした。

私は 32 ビット用のコードをほぼ同じように組み立てようとしていますが、かなりつまずきました。最終的に、gcc を使用してリンクを作成しました (そして、_start: を main: に変更しました)。それで、ld を使用して自分でリンクを作成し、crt1.o crti.o と crtn.o を含めました。その後、私のプログラムは機能しました(以前は何も出力されませんでした)。私の質問は、これらの他の3つのオブジェクトファイルの必要性を排除するためにコード内で何かを行うことができるかということです(もちろん、メインの代わりに_start:に戻ります) ?

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

ファイルの機能は次のとおりです。それらは、OS にリンクする c-runtime 環境とセットアップです。

  • crt1.o初期ランタイム コードの新しいスタイル。libc メインにジャンプする前に、argc/argv/libc _init/libc _fini で環境をセットアップする _start シンボルが含まれています。glibc はこのファイルを「start.S」と呼びます。

  • crti.o関数のプロローグを定義します。.init セクションの _init と .fini セクションの _fini。glibc はこれを「initfini.c」と呼びます。

  • crtn.o関数のエピローグを定義します。glibc はこれを「initfini.c」と呼びます。

上記の各ライブラリについて、次の Web サイトhttp://wiki.osdev.org/Creating_a_C_Libraryに優れた記事とサンプル コードがあります。

于 2013-08-06T22:34:01.640 に答える