x86-16 Código da Máquina (DOS), 16 bytes
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
A função acima recebe um valor booleano (0 == falsey, 1 == truthy) no BL
registro (byte baixo de BX
) e imprime uma string "booleana redundante" na saída padrão.
Ele funciona chamando uma interrupção (0x21) para fazer uma chamada de função do DOS (selecionada pela configuração AH
2) que imprime um único caractere (in DL
) na saída padrão.
Primeiro, o caractere ASCII '0' é carregado DL
, o contador ( CX
) é definido como 31 e faz um loop para imprimir os bytes "redundantes". Em seguida, o valor booleano de entrada é adicionado a DL
(se BL
for falsey, adicionar 0 DL
permanecerá inalterado como ASCII '0'; se BL
for verdade, DL
será incrementado em um para ASCII '1') e o byte final será impresso.
A função não retorna um valor.
Bastante decente para uma linguagem que realmente não faz cordas.
Programa completo, 21 bytes
Se você deseja transformá-lo em um programa completo, são necessários apenas mais 5 bytes. Em vez de passar a entrada em um registro, ela lê a entrada dos argumentos transmitidos na linha de comando ao invocar o aplicativo. Um argumento de 0 é interpretado como falsey, assim como a completa falta de argumentos; um argumento maior que 0 é interpretado como verdade.
Simplesmente monte o código a seguir como um programa COM e execute-o na linha de comando.
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
Saída de amostra:
C:\>bool.com
00000000000000000000000000000000
C:\>bool.com 0
00000000000000000000000000000000
C:\>bool.com 1
00000000000000000000000000000001
C:\>bool.com 2
00000000000000000000000000000001
C:\>bool.com 7
00000000000000000000000000000001
Como funciona? Bem, é basicamente a mesma coisa, até você chegar às CMP
instruções. Isso compara o argumento da linha de comando com o valor do DL
registrador (que você se lembra, contém um ASCII '0'). Em um programa COM, os bytes de código são carregados no deslocamento 0x100. O precedente é o prefixo do segmento de programa (PSP) , que contém informações sobre o estado de um programa DOS. Especificamente, no deslocamento 0x82, você encontra o primeiro argumento (na verdade o segundo, já que o primeiro é um espaço) que foi especificado na linha de comando quando o programa foi chamado. Então, estamos apenas comparando esse byte com um ASCII '0'.
A comparação define os sinalizadores e, em seguida, a SALC
instrução (um código de operação não documentado anterior ao Pentium, equivalente a sbb al, al
, mas apenas 1 byte em vez de 2) define AL
como 0 se os dois valores forem iguais ou -1 se forem diferentes. Em seguida, é óbvio que, quando nós subtraímos AL
a partir DL
, isso resulta em ASCII '0' ou '1', conforme o caso.
(Observe que, ironicamente, você o quebrará se passar um argumento com um 0 à esquerda na linha de comando, pois ele olha apenas para o primeiro caractere. Portanto 01
, será tratado como falsey. :-)