x86マシンコード、70バイト
60 89 d7 31 db 43 88 ce b2 fe 49 d1 e1 87 da 0f
c7 f0 24 7f 3c 22 72 f7 48 3c 79 74 f2 3c 59 74
ee aa 49 7c 1c 00 df 79 06 86 f7 42 43 eb f6 f6
c3 01 74 03 b0 0a aa 51 88 f9 b0 20 f3 aa 59 eb
cc c6 07 00 61 c3
逆アセンブルされた私の実行可能コード:
0000003d <myheh>:
3d: 60 pusha
3e: 89 d7 mov %edx,%edi
40: 31 db xor %ebx,%ebx
42: 43 inc %ebx
43: 88 ce mov %cl,%dh
45: b2 fe mov $0xfe,%dl
47: 49 dec %ecx
48: d1 e1 shl %ecx
0000004a <myloop>:
4a: 87 da xchg %ebx,%edx
0000004c <myrand>:
4c: 0f c7 f0 rdrand %eax
4f: 24 7f and $0x7f,%al
51: 3c 22 cmp $0x22,%al
53: 72 f7 jb 4c <myrand>
55: 48 dec %eax
56: 3c 79 cmp $0x79,%al
58: 74 f2 je 4c <myrand>
5a: 3c 59 cmp $0x59,%al
5c: 74 ee je 4c <myrand>
5e: aa stos %al,%es:(%edi)
5f: 49 dec %ecx
60: 7c 1c jl 7e <mydone>
00000062 <mylab>:
62: 00 df add %bl,%bh
64: 79 06 jns 6c <myprint>
66: 86 f7 xchg %dh,%bh
68: 42 inc %edx
69: 43 inc %ebx
6a: eb f6 jmp 62 <mylab>
0000006c <myprint>:
6c: f6 c3 01 test $0x1,%bl
6f: 74 03 je 74 <myprint1>
71: b0 0a mov $0xa,%al
73: aa stos %al,%es:(%edi)
00000074 <myprint1>:
74: 51 push %ecx
75: 88 f9 mov %bh,%cl
77: b0 20 mov $0x20,%al
79: f3 aa rep stos %al,%es:(%edi)
7b: 59 pop %ecx
7c: eb cc jmp 4a <myloop>
0000007e <mydone>:
7e: c6 07 00 movb $0x0,(%edi)
81: 61 popa
82: c3 ret
これは、ecxでXのサイズを受け取り、edxで出力バッファーへのポインターを受け取る関数です。
出力バッファをバイトで順番に満たします。2 * n - 1
反復があります(出力する非スペース文字の数に等しい)。各反復で、次のことを行います。
- 乱数を生成する
- 範囲内に収まるように数値をいじります。悪い場合は、戻って新たに生成します
- ランダムな文字を印刷します
- 改行を印刷します(他のすべての反復)
- 適切な数のスペースを印刷する
乱数からランダムな文字への変換は注目に値しません:
myrand:
rdrand eax;
and al, 7fh;
cmp al, 22h;
jb myrand;
dec eax;
cmp al, 'y';
je myrand;
cmp al, 'Y';
je myrand;
興味深い部分は、スペースの数の計算です。次の番号を生成する必要があります(N = 9の例):
7 1
5 2
3 3
1 4
3
1 2
3 1
5 0
7
数値は、2つの算術進行から交互に取得されます。最初のステップはステップ-2で下がり、2番目のステップはステップ1で上がります。最初の進行が-1(Xの中央)に達すると、グリッチ(-1が除去される)があり、進行方向が変わります。
進行は、レジスタに格納されているebx
とedx
-高部品bh
とdh
現在の数、及び低い部品を格納bl
し、dl
ステップを格納します。進行を交互に行うために、コードはでレジスタを交換しxchg
ます。
進行が-1(mylab
ラベルの周り)に達すると、両方のレジスタが増加し、ステップがから-2, 1
に切り替わります-1, 2
。これにより、レジスタの役割も変更されるため、レジスタの上位部分がスワップされます。
関数の最後に、文字列の終わりを示すゼロバイトを保存します。