Машинный код 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 == Falsey, 1 == Truey) в BL регистре ( байт BX) и печатает «лишнюю логическую» строку в стандартный вывод.
Он работает, вызывая прерывание (0x21) для вызова функции DOS (выбирается настройкой AH 2), которая печатает один символ (in DL) на стандартный вывод.
Сначала загружается символ ASCII '0' DL, счетчик ( CX) устанавливается в 31, и он зацикливается для вывода "лишних" байтов. Затем добавляется входное логическое значение DL(если BLfalse, добавление 0 не изменится DLкак ASCII '0'; если BLверно, DLбудет увеличено на единицу до 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) устанавливает ALзначение 0, если два значения были равны, или -1, если они были разными. Тогда очевидно , что если вычесть ALиз DL, это приводит либо ASCII «0» или «1», в зависимости от обстоятельств.
(Обратите внимание, что, по иронии судьбы, вы сломаете его, если передадите аргумент с начальным 0 в командной строке, так как он смотрит только на первый символ. Поэтому 01будет рассматриваться как фальси. :-)