x86-16 Machine Code (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
The above function receives a boolean value (0 == falsey, 1 == truthy) in the BL
register (low byte of BX
), and prints a "redundant boolean" string to the standard output.
It works by invoking an interrupt (0x21) to make a DOS function call (selected by setting AH
to 2) that prints a single character (in DL
) to the standard output.
First, the ASCII character '0' is loaded into DL
, the counter (CX
) is set to 31, and it loops to print the "redundant" bytes. Then, the input boolean value is added to DL
(if BL
is falsey, adding 0 will leave DL
unchanged as ASCII '0'; if BL
is truthy, DL
will be incremented by one to ASCII '1'), and the final byte is printed.
The function does not return a value.
Pretty decent for a language that doesn't really do strings.
Full Program, 21 bytes
If you want to make it into a full program, only 5 more bytes are required. Instead of passing the input in a register, this reads the input from the arguments passed on the command line when invoking the application. An argument of 0 is interpreted as falsey, as is the complete lack of arguments; an argument greater than 0 is interpreted as truthy.
Simply assemble the following code as a COM program, and then execute it on the command line.
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
Sample Output:
C:\>bool.com
00000000000000000000000000000000
C:\>bool.com 0
00000000000000000000000000000000
C:\>bool.com 1
00000000000000000000000000000001
C:\>bool.com 2
00000000000000000000000000000001
C:\>bool.com 7
00000000000000000000000000000001
How does it work? Well, it's basically the same thing, until you get down to the CMP
instruction. This compares the command-line argument with the value of the DL
register (which, you recall, contains an ASCII '0'). In a COM program, the bytes of code are loaded at offset 0x100. Preceding that is the program segment prefix (PSP), which contains information about the state of a DOS program. Specifically, at offset 0x82, you find the first (actually the second, since the first is a space) argument that was specified on the command line when the program was invoked. So, we are just comparing this byte against an ASCII '0'.
The comparison sets the flags, and then the SALC
instruction (an undocumented opcode prior to the Pentium, equivalent to sbb al, al
, but only 1 byte instead of 2) sets AL
to 0 if the two values were equal, or -1 if they were different. It is then obvious that when we subtract AL
from DL
, this results in either ASCII '0' or '1', as appropriate.
(Note that, somewhat ironically, you will break it if you pass an argument with a leading 0 on the command line, since it looks only at the first character. So 01
will be treated as falsey. :-)