x86-Maschinencode, 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
Mein ausführbarer Code, zerlegt:
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
Es ist eine Funktion, die in ecx die Größe des X und in edx einen Zeiger auf den Ausgabepuffer erhält.
Es füllt den Ausgabepuffer sequentiell mit Bytes. Es gibt 2 * n - 1
Iterationen (gleich der Anzahl der auszugebenden Nicht-Leerzeichen). Bei jeder Iteration wird Folgendes ausgeführt:
- Generiere eine Zufallszahl
- Spielen Sie mit der Zahl, um sie in die Reichweite zu bringen. Wenn es schlecht ist, gehen Sie zurück und generieren Sie neu
- Drucken Sie das zufällige Zeichen
- Eine neue Zeile drucken (jede zweite Iteration)
- Drucken Sie die richtige Anzahl von Leerzeichen
Die Umwandlung einer Zufallszahl in ein zufälliges Zeichen ist nicht bemerkenswert:
myrand:
rdrand eax;
and al, 7fh;
cmp al, 22h;
jb myrand;
dec eax;
cmp al, 'y';
je myrand;
cmp al, 'Y';
je myrand;
Der interessante Teil ist die Berechnung der Anzahl der Räume. Es muss die folgenden Zahlen erzeugen (Beispiel für N = 9):
7 1
5 2
3 3
1 4
3
1 2
3 1
5 0
7
Die Zahlen werden abwechselnd von zwei arithmetischen Folgen genommen. Der erste geht mit Schritt -2 runter und der zweite geht mit Schritt 1 rauf. Wenn der erste Fortschritt bei -1 (in der Mitte des X) ankommt, gibt es einen Fehler (-1 wird entfernt), und dann Die Progressionen ändern ihre Richtung.
Die Progressionen werden in Registern ebx
und edx
- den oberen Teilen gespeichert bh
und dh
speichern die aktuelle Nummer und die unteren Teile bl
und dl
speichern den Schritt. Um zwischen den Fortschritten zu wechseln, tauscht der Code die Register mit xchg
.
Wenn der Fortschritt -1 (um das mylab
Etikett herum ) erreicht, werden beide Register vergrößert und die Schritte von -2, 1
auf umgeschaltet -1, 2
. Dies ändert auch die Rollen der Register, so dass dann die oberen Teile der Register vertauscht werden.
Am Ende der Funktion wird ein Null-Byte gespeichert, um ein Ende der Zeichenfolge anzuzeigen.