mã máy 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
Mã thực thi của tôi, đã được tháo rời:
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
Đây là một hàm nhận kích thước của X trong ecx và là một con trỏ tới bộ đệm đầu ra trong edx.
Nó lấp đầy bộ đệm đầu ra tuần tự bằng byte. Có các 2 * n - 1
lần lặp (bằng số lượng ký tự không phải khoảng trắng để xuất). Ở mỗi lần lặp, nó thực hiện như sau:
- Tạo một số ngẫu nhiên
- Fiddle với số để phù hợp với nó trong phạm vi; nếu nó xấu, hãy quay lại và tạo lại
- In ký tự ngẫu nhiên
- In một dòng mới (mỗi lần lặp khác)
- In số lượng không gian thích hợp
Chuyển đổi từ một số ngẫu nhiên thành một ký tự ngẫu nhiên không đáng chú ý:
myrand:
rdrand eax;
and al, 7fh;
cmp al, 22h;
jb myrand;
dec eax;
cmp al, 'y';
je myrand;
cmp al, 'Y';
je myrand;
Phần thú vị là tính toán số lượng không gian. Nó phải tạo ra các số sau (ví dụ cho N = 9):
7 1
5 2
3 3
1 4
3
1 2
3 1
5 0
7
Các số được lấy xen kẽ từ hai tiến trình số học. Bước đầu tiên đi xuống với bước -2 và bước thứ hai đi lên với bước 1. Khi tiến trình đầu tiên đến -1 (ở giữa X), có một trục trặc (-1 bị loại bỏ), và sau đó sự tiến triển thay đổi hướng.
Các tiến trình được lưu trữ trong các thanh ghi ebx
và edx
- các phần cao bh
và dh
lưu trữ số hiện tại, và các phần thấp bl
và dl
lưu trữ các bước. Để xen kẽ giữa các tiến trình, mã hoán đổi các thanh ghi với xchg
.
Khi tiến trình đến -1 (xung quanh mylab
nhãn), nó sẽ tăng cả hai thanh ghi, chuyển các bước từ -2, 1
sang -1, 2
. Điều này cũng thay đổi vai trò của các thanh ghi, do đó nó hoán đổi các phần cao của các thanh ghi.
Ở cuối hàm, nó lưu một byte bằng 0 để chỉ ra phần cuối của chuỗi.