kode mesin x86, 70 byte
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
Kode yang dapat dieksekusi saya, dibongkar:
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
Ini adalah fungsi yang menerima ukuran X di ecx, dan penunjuk ke buffer output di edx.
Ini mengisi buffer output secara berurutan dengan byte. Ada 2 * n - 1
iterasi (sama dengan jumlah karakter non-spasi untuk output). Pada setiap iterasi, ia melakukan hal berikut:
- Hasilkan nomor acak
- Mengotak-atik nomor agar pas ke dalam jangkauan; jika buruk, kembali dan hasilkan yang baru
- Cetak karakter acak
- Cetak baris baru (setiap iterasi lainnya)
- Cetak jumlah spasi yang tepat
Konversi dari angka acak ke karakter acak tidak luar biasa:
myrand:
rdrand eax;
and al, 7fh;
cmp al, 22h;
jb myrand;
dec eax;
cmp al, 'y';
je myrand;
cmp al, 'Y';
je myrand;
Bagian yang menarik adalah perhitungan jumlah spasi. Itu harus menghasilkan angka-angka berikut (contoh untuk N = 9):
7 1
5 2
3 3
1 4
3
1 2
3 1
5 0
7
Angka-angka diambil secara bergantian dari dua perkembangan aritmatika. Yang pertama turun dengan langkah -2, dan yang kedua naik dengan langkah 1. Ketika perkembangan pertama tiba di -1 (di tengah-tengah X), ada kesalahan (-1 dihapus), dan kemudian perkembangannya berubah arah.
Kemajuan disimpan dalam register ebx
dan edx
- bagian tinggi bh
dan dh
menyimpan nomor saat ini, dan bagian rendah bl
dan dl
menyimpan langkah. Untuk bergantian di antara progres, kode bertukar register dengan xchg
.
Ketika progres tiba di -1 (di sekitar mylab
label), ia meningkatkan kedua register, mengalihkan langkah dari -2, 1
ke -1, 2
. Ini juga mengubah peran register, sehingga kemudian bertukar bagian register yang tinggi.
Di akhir fungsi, ini menyimpan nol byte untuk menunjukkan akhir dari string.