Mã máy 8086 + DOS, 61 byte
Hexdump (với chế độ xem ASCII ở bên phải):
B8 1E 01 8B F8 CD 21 B1 1F F2 AE 8B F7 AC 8A D0 ......!.........
B4 02 CD 21 80 E2 20 74 02 CD 21 E2 F0 C3 71 77 ...!.. t..!...qw
65 72 74 79 75 69 6F 70 0D 0A 61 73 64 66 67 68 ertyuiop..asdfgh
6A 6B 6C 0D 0A 7A 78 63 76 62 6E 6D 0D jkl..zxcvbnm.
Mã nguồn hội (có thể được lắp ráp bằng tasm):
.MODEL TINY
.CODE
org 100h
MAIN PROC
mov ax, offset qwerty ; sets ah=1 (coincidence)
mov di, ax ; di points to the string
int 21h ; reads a char from keyboard into al
mov cl, 31 ; cx is the length of the string
repne scasb ; look for the char
mov si, di ; si now points beyond the found char
myloop:
lodsb ; load a char
mov dl, al
mov ah, 2
int 21h ; output the char
and dl, 20h ; if it's a letter, set it to a space
jz print_done ; if it's not a letter, don't print a space
int 21h ; if it's a letter, print a space
print_done:
loop myloop ; repeat until end of string
ret
qwerty db 'qwertyuiop',13,10,'asdfghjkl',13,10,'zxcvbnm',13
MAIN ENDP
END MAIN
Hai điều thú vị ở đây:
- Phần bù của
qwerty
chuỗi là 0x011e
. Byte trên của nó là 1, là số chức năng của DOS cho đầu vào ký tự. Điều này tiết kiệm 1 byte trong mã.
- Tất cả các chữ cái viết thường có bit 5 được đặt. Khi thực hiện
AND
với 0x20
, tất cả chúng được biến thành một khoảng trắng, sau đó được in ra. Nếu char trước đó là byte cuối dòng, nó sẽ được chuyển thành 0 và không có khoảng trắng nào được xuất ra. Điều này được sử dụng để tránh các chuỗi vô nghĩa 0d 20 0a 20
ở cuối dòng.
Một điều gần như thú vị:
Tôi đã cố gắng tìm kiếm char đầu vào bắt đầu từ địa chỉ 0 (làm giảm kích thước chương trình xuống 2 byte), thay vì vị trí thông thường (bắt đầu chuỗi). Điều này gần như đã làm việc; tuy nhiên, nó không thành công cho đầu vào t
, vì bản thân mã chứa byte t
(như một phần mã hóa của bước nhảy có điều kiện). Vì vậy t
, nó sẽ xuất ra một vài byte rác: