32バイト以下のx86マシンコードで最もビジーなビーバーを構築する


8

あなたの仕事は、最大32バイトのコードを使用し、ゼロ化されたレジスターから始めて、可能な限り多くの命令を実行して停止するx86マシン言語(任意のバージョン)でプログラムを書くことです。

x86マシンで使用可能な形式である限り、ランダムアクセスメモリについては何でも想定できます。


3
停止動作が不明な、かなり小さな忙しいビーバーチューリングマシンがあります(en.wikipedia.org/wiki/Busy_beaver#Known_values)。誰かがそれらの1つを実装するとどうなりますか?
asmeurer 2013

ここに記入できる詳細がいくつかあります。スタックがセットアップされていますか?それはどれくらい大きいですか?プログラムはメモリに自由にアクセスできますか?もしそうなら、それはいくらですか?4 GBすべてへの読み取り/書き込みアクセス権はありますか?もしそうなら、私たちはプログラムがどこにあるかを選ぶことができますか?
ブレッドボックス2013

実際のレジスターがコードの実行の開始時にすべてゼロに設定されている限り、必要なメモリについては何でも想定できます。(これにより問題が発生しますか?私は機械語をあまり経験していません。)
Joe Z.

プロセッサがリアルモードまたはプロテクトモードであると想定できますか?プロテクトモードを想定できる場合は、グローバル記述子テーブルやページングテーブルなどに関する他の多くの質問が開かれるためです。これらの問題を考えると、使用可能なメモリがはるかに少ないことを意味するリアルモードを強制する方がよい場合があります。 。非現実的なモードを想定できない限り、私は今私が暗黙的に自分が入っていると想定していました。しかし、いずれにせよ、これはおそらく問題の説明で明示的に呼び出されるべきです。
ブレッドボックス2013

回答:


8

2 524224命令

私のプログラム:

_start:
        mov     bl, _end
        stc
iloop:  adc     [bx], al
        inc     bx
        jnz     iloop
        jnc     _start
        a32
        loop    _start
        hlt
_end:

(テクニカルノート:これはNASMのために書かれている。a32代替アドレスサイズプレフィックスバイト用のnasmの構文ですMASMのために、あなたが代わる。a32defb 0x67。)

わかりやすくするために、リストの出力を次に示します。

 1                  _start:
 2 0000 B310                mov     bl, _end
 3 0002 F9                  stc
 4 0003 1007        iloop:  adc     [bx], al
 5 0005 43                  inc     bx
 6 0006 75F9                jnz     iloop
 7 0008 73F4                jnc     _start
 8 000A 67                  a32
 9 000B E2F1                loop    _start
10 000D F4                  hlt
11                  _end:

プログラムは、プロセッサがリアルモードであり、プログラムがメモリの64kセグメントの下部にあることを前提としています。メモリセグメントは、すべてのビットがゼロに初期化されます。その設計は単純です。メモリを単一の巨大な符号なし整数として扱い、すべてのゼロにロールバックされるまで、考えられるすべての値をインクリメントします。この2を32回繰り返します。その後、停止します。

最も内側のループ(4〜6行目)は、巨大な整数をインクリメントします。前のバイトのキャリーがあったかどうかに応じて、各反復で1バイトに0または1が追加されます。このループは、常に2反復するように巨大な整数ですべてのバイトは、それが変化したか否か、アクセスされることに注意してください16 14回- 。

ちなみに、ご参考までに、このコードは、x86 inc/ dec命令がキャリーフラグに影響を与えない理由を示しています。このようなマルチバイトのキャリーパターンを単純化するためです。(このパターンは、元の8080命令セットが定義された8ビットマイクロプロセッサの時代に、より頻繁に登場しました。)

行7では、最後のバイトから1が実行されるまでインクリメントプロセスが繰り返され、巨大な整数がすべてのビットがゼロにリセットされたことを示します。これには時間がかかります。

行8から9は、最も外側のループを示し、レジスターがゼロになるまで、このプロセスを2から32回繰り返しecxます。これは、巨大な整数に32ビットを追加することと実質的に同じです。

別の外側のループを追加して(言う)を使用して、もう一度この操作を行うことが可能であろうedxレジスタが、その後、多分使用esiし、ediさらに多くの繰り返しのために。ただし、実行する価値はありません。インクリメントおよびループする命令には4バイトが必要です。これらの4バイトは、巨大な整数から取り除かれます。したがって、レジスタを介して32ビットを追加するために、RAMカウンターで32ビットを失います。唯一の理由ecxは例外で、loop3バイトにしか収まらない特殊な命令があるためです。したがって、このプログラムは24ビットを32ビットと交換しますが、これはわずかですが8ビットの正のゲインです。

プログラムが停止する前に実行する命令の数を直接計算することはそれほど難しくありません。ただし、この数を見積もるはるかに簡単な方法があります。プログラムは、プログラムを含む14バイトを除くすべてのメモリと、bxおよびecxレジスタを変更します。これは、2加算16 524224ビットの合計、14 + 2 + 4 = 65528バイト- 。ショートカットには、実行中に、524224ビットのすべての可能なパターンが1回だけ現れることを認識することが含まれます。RAMとecxレジスタの場合、プログラムはすべての値をインクリメントするため、これは簡単に確認できます。ためにbxメモリ内の値が更新されると同時に変更されるため、これは少し明白ではありません。ただし、プログラムの構造を考えると、完全なビットパターンが実際に2回出現する場合、プログラムは無限ループにある必要があることを示すことができます。これはそうではないので、各ビットパターンは最終的に一度だけ訪問されなければなりません。(当然、完全な証明は演習として読者に残されます。)

すべての可能なビットパターンがプログラムの過程で現れるため、プログラムは少なくとも2つの524224命令を実行する必要があります。これは、およそ1.4×10 157807に等しいです。(ジャンプ命令のため、実際の数値はわずかに高くなりますが、この大きさの違いは無視できます。)

明らかに、これは64k以上のRAMを使用することで大幅に改善できます。アクセスできるRAMの量が正確にわかるまで、次のバージョンのコードを待ちます。


それは17命令(34バイト)じゃないですか?それとも何か不足していますか?
Joe Z.

@JoeZ。incは1バイト(16ビットモードでアセンブルしない場合)
コピー

ああ。したがって、このプログラムは実際には25バイトの長さでしょうか。
ジョーZ.

はい、25バイトです
コピー

申し訳ありませんが、私はもっと明確にすべきでした。あいまいさを避けるために、リスト出力を追加しました。
ブレッドボックス2013

4

〜2 ^(2 ^ 67)の説明

(at&t構文)

start:
    movq    $0x1a,%rax
    stc
loop:
    adcb    %cl,(%rax)
    incq    %rax
    jnz     loop
    jnc     start
    hlt

逆アセンブル、26バイト:

start:
0000000000000000    movq    $0x0000001a,%rax
0000000000000007    stc
loop:
0000000000000008    adcb    %cl,(%rax)
000000000000000a    incq    %rax
000000000000000d    jne loop
0000000000000013    jae start
0000000000000019    hlt

ブレッドボックスのソリューションに似ていますが、16ビットのアドレスで停止する理由はありません。私のコードはx86-64を使用し、2 ^ 64バイトのメモリがあることを想定しており、コードを保持するメモリ以外のすべてを巨大なカウンターとして使用します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.