รหัสเครื่อง 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
มันเป็นฟังก์ชั่นที่รับขนาดของ X ใน ecx และตัวชี้ไปยังบัฟเฟอร์เอาต์พุตใน edx
มันเติมบัฟเฟอร์ผลลัพธ์ตามลำดับด้วยไบต์ มี2 * n - 1
การวนซ้ำ (เท่ากับจำนวนของอักขระที่ไม่ใช่ช่องว่างเพื่อส่งออก) ในการทำซ้ำแต่ละครั้งจะทำสิ่งต่อไปนี้:
- สร้างตัวเลขสุ่ม
- ซอที่มีตัวเลขเพื่อให้พอดีกับช่วง; ถ้ามันไม่ดีให้กลับไปสร้างใหม่อีกครั้ง
- พิมพ์ตัวอักษรแบบสุ่ม
- พิมพ์ newline (ซ้ำทุก ๆ )
- พิมพ์จำนวนช่องว่างที่เหมาะสม
การแปลงจากจำนวนสุ่มไปเป็นอักขระสุ่มไม่น่าทึ่ง:
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 และอันที่สองขึ้นไปด้วยขั้นตอนที่ 1 เมื่อความก้าวหน้าครั้งแรกมาถึงที่ -1 (ตรงกลางของ X) จะมีความผิดพลาด (-1 ถูกลบ) แล้ว ความก้าวหน้าเปลี่ยนทิศทาง
ความคืบหน้าจะถูกเก็บไว้ในการลงทะเบียนebx
และedx
- ส่วนสูงbh
และdh
เก็บหมายเลขปัจจุบันและส่วนที่ต่ำbl
และdl
จัดเก็บขั้นตอน ที่จะสลับกันระหว่างก้าวหน้ารหัส swaps xchg
ลงทะเบียนกับ
เมื่อขบวนมาถึงที่ -1 (รอบmylab
ฉลาก) ก็เพิ่มขึ้นทั้งลงทะเบียนเปลี่ยนขั้นตอนจากไป-2, 1
-1, 2
สิ่งนี้จะเปลี่ยนบทบาทของรีจิสเตอร์ด้วยดังนั้นมันจึงสลับส่วนของรีจิสเตอร์ระดับสูง
ในตอนท้ายของฟังก์ชั่นมันจะเก็บศูนย์ไบต์เพื่อระบุจุดสิ้นสุดของสตริง