8

C単一のライブラリ呼び出しを使用していなくても、たとえばexit()を使用していなくても、実行可能なプログラミング言語でプログラムを作成できるかどうか疑問に思います。

もしそうなら、それは明らかにライブラリ(libc、ld-linux)にまったく依存しません。

4

6 に答える 6

8

そのようなことを書くことができると思いますが、オペレーティングシステムにプロセスを終了するように要求できないため、最後に無限ループが必要になります。そして、あなたは何も役に立たなかった。

ELF プログラムのコンパイルから始めて、ELF 仕様を調べ、ヘッダー、プログラム セグメント、およびプログラムに必要なその他の部分を一緒に作成します。カーネルはコードをロードし、最初のアドレスにジャンプします。そこに無限ループを配置できます。しかし、アセンブラの知識がなければ、最初から絶望的です。

glibc で使用されるstart.Sファイルは、開始点として役立つ場合があります。スタンドアロンの実行可能ファイルをアセンブルできるように変更してみてください。その start.S ファイルは、すべての ELF アプリケーションのエントリ ポイントで__libc_start_mainあり、次に を呼び出すものmainです。必要に応じて変更するだけです。

わかりました、それは理論的でした。しかし今、それはどのような実用的な用途があるのでしょうか?

更新された質問への回答

良い。libgloss組み込みシステムで実行するためのプログラムに最小限のインターフェイスを提供するライブラリがあります。newlibC ライブラリは、それをシステム コール インターフェイスとして使用します。一般的な考え方は、libgloss が C ライブラリとオペレーティング システムの間の層であるということです。そのため、オペレーティング システムがジャンプするスタートアップ ファイルも含まれています。これらのライブラリは両方とも GNU binutils プロジェクトの一部です。私はそれらを使用して別のOSと別のプロセッサのインターフェースを実行しましたが、Linux用のlibglossポートはないようです。そのため、システムコールを呼び出す場合は、他の人がすでに述べたように、自分でそれを行う必要があります. .

Cプログラミング言語でプログラムを書くことは絶対に可能です。Linux カーネルは、そのようなプログラムの良い例です。しかし、ユーザープログラムも可能です。しかし、最低限必要なものはランタイム ライブラリです (何か重大なことをしたい場合)。そのようなものには、memcpy、基本的なマクロなどの本当に基本的な機能が含まれます。C 標準には、フリースタンディングと呼ばれる特別な準拠モードがあり、カーネルにも適した非常に限られた機能セットのみを必要とします。実際、私はx86 アセンブラーについて何も知りませんが、非常に単純な C プログラムで運試しをしました。

/* gcc -nostdlib start.c */
int main(int, char**, char**);

void _start(int args)
{
    /* we do not care about arguments for main. start.S in 
     * glibc documents how the kernel passes them though.
     */
    int c = main(0,0,0);

    /* do the system-call for exit. */
    asm("movl   %0,%%ebx\n" /* first argument */
        "movl   $1,%%eax\n" /* syscall 1 */
        "int    $0x80"      /* fire interrupt */
        : : "r"(c) :"%eax", "%ebx");
}

int main(int argc, char** argv, char** env) {
    /* yeah here we can do some stuff */
    return 42;
}

満足しています。実際にコンパイルして実行します:)

于 2009-02-08T00:42:38.647 に答える
5

はい、可能ですが、システム コールを作成し、エントリ ポイントを手動で設定する必要があります。

エントリ ポイントを持つ最小限のプログラムの例:

.globl _start
.text
_start:
    xorl %eax,%eax
    incl %eax
    movb $42, %bl
    int $0x80

または、プレーン C (出口なし) の場合:

void __attribute__((noreturn)) _start() {
    while(1);
}

以下でコンパイル:

gcc -nostdlib -o example example.s
gcc -nostdlib -o example example.c
于 2009-02-08T00:25:41.600 に答える
2

C コンパイラが libc に依存するコードを生成しないようにする方法が必要gccです-fno-hosted。また、実装するアセンブリ言語ルーチンが 1 つ必要ですsyscall(2)。適当なOS docoを入手できれば書くのは難しくありません。その後、あなたはレースに出ます。

于 2009-02-08T02:53:04.360 に答える
2

純粋なCで?他の人が言っているように、システムコールを作成する方法がまだ必要なので、そのためにインライン asm にドロップダウンする必要があるかもしれません。そうは言っても、gcc を使用している場合は -ffreestanding をチェックしてください。

于 2009-02-08T01:13:08.680 に答える
0

そうですね、すべての情報をメモリにロードするには、いくつかのシステムコールを使用する必要があるので、私はそれを疑っています。

そして、Linuxの動作方法のために、ほとんどexit()を使用する必要があります。

于 2009-02-08T00:16:54.690 に答える
0

はい、できますが、かなりトリッキーです。

本質的にはまったく意味がありません。

プログラムを静的にリンクできますが、その場合、C ライブラリの適切な部分がそのバイナリに含まれます (したがって、依存関係はありません)。

C ライブラリがなくても完全に実行できます。その場合、適切な低レベル インターフェイスを使用してシステム コールを行う必要があります。これはアーキテクチャに依存し、int 0x80 である必要はありません。

あなたの目標が非常に小さな自己完結型のバイナリを作成することである場合は、uclibc などに対して静的リンクを作成する方がよい場合があります。

于 2009-02-08T09:43:52.767 に答える