x86-16 Машинний код (DOS), 16 байт
B4 02 mov ah, 2
B2 30 mov dl, '0'
B9 1F 00 mov cx, 31
PrintZeros:
CD 21 int 0x21
E2 FC loop PrintZeros
00 CA add dl, bl
CD 21 int 0x21
C3 ret
Вищенаведена функція отримує булеве значення (0 == фальси, 1 == truthy) у BL (низький байт BX) і друкує "зайвий булевий" рядок до стандартного виводу.
Він працює, викликаючи переривання (0x21), щоб здійснити виклик функції DOS (вибрано налаштуванням) AH на 2), який друкує один символ (в DL) на стандартний вихід.
По-перше, символ "0" ASCII завантажується в DLлічильник, лічильник ( CX) встановлюється на 31, і він петлює для друку "зайвих" байтів. Потім додається булева величина вводу DL(якщо BLє фальси, додавання 0 залишатиметься DLнезмінним як ASCII '0'; якщо BLє truthy, DLбуде збільшуватися на 1 до ASCII '1'), і друкується остаточний байт.
Функція не повертає значення.
Досить пристойний для мови, яка насправді не створює рядки.
Повна програма, 21 байт
Якщо ви хочете перетворити його на повну програму, потрібно лише ще 5 байт. Замість передачі введення в регістр, це зчитує вхід з аргументів, переданих у командному рядку при виклику програми. Аргумент 0 трактується як фальси, як і повна відсутність аргументів; аргумент, більший за 0, трактується як правдивий.
Просто зберіть наступний код як програму COM і виконайте його в командному рядку.
B4 02 mov ah, 2
B2 30 mov dl, '0'
B9 1F 00 mov cx, 31
PrintZeros:
CD 21 int 0x21
E2 FC loop PrintZeros
3A 16 82 00 cmp dl, BYTE PTR [0x82] ; compare to 2nd arg, at offset 0x82 in PSP
D6 salc ; equivalent to sbb al, al
28 C2 sub dl, al
CD 21 int 0x21
C3 ret ; you can simply 'ret' to end a COM program
Вибірка зразка:
C:\>bool.com
00000000000000000000000000000000
C:\>bool.com 0
00000000000000000000000000000000
C:\>bool.com 1
00000000000000000000000000000001
C:\>bool.com 2
00000000000000000000000000000001
C:\>bool.com 7
00000000000000000000000000000001
Як це працює? Ну, це в основному те саме, поки ви не приступите до CMPінструкції. Це порівнює аргумент командного рядка зі значенням DLрегістру (який, нагадаєте, містить ASCII '0'). У програмі COM байти коду завантажуються зі зміщенням 0x100. Попередній префікс програмного сегмента (PSP) , який містить інформацію про стан програми DOS. Зокрема, при зміщенні 0x82 ви знаходите перший (власне другий, оскільки перший - пробіл) аргумент, який був вказаний у командному рядку під час виклику програми. Отже, ми просто порівнюємо цей байт з ASCII '0'.
Порівняння встановлює прапори, а потім SALCінструкція (незадокументований код коду перед Pentium, еквівалентний sbb al, al, але лише 1 байт замість 2) встановлює AL0, якщо два значення були рівними, або -1, якщо вони були різними. Тоді очевидно, що коли ми віднімаємо ALвідDL , це призводить або ASCII «0» або «1», в залежності від обставин.
(Зауважте, що дещо іронічно, ви зламаєте його, якщо передасте аргумент із провідним 0 у командному рядку, оскільки він виглядає лише на першому символі. Тому 01буде трактуватися як фальси. :-)