Code machine x86-16 (DOS), 16 octets
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
La fonction ci-dessus reçoit une valeur booléenne (0 == falsey, 1 == truey) dans le BL
registre (octet bas de BX
) et imprime une chaîne "booléenne redondante" sur la sortie standard.
Il fonctionne en appelant une interruption (0x21) pour effectuer un appel de fonction DOS (sélectionné en définissant AH
sur 2) qui imprime un seul caractère (in DL
) sur la sortie standard.
Tout d'abord, le caractère ASCII «0» est chargé dans DL
, le compteur ( CX
) est défini sur 31 et il boucle pour imprimer les octets «redondants». Ensuite, la valeur booléenne d'entrée est ajoutée à DL
(s'il BL
s'agit de falsey, l'ajout de 0 restera DL
inchangé en tant que ASCII '0'; s'il BL
est véridique, DL
sera incrémenté de un à ASCII '1'), et l'octet final sera imprimé.
La fonction ne renvoie pas de valeur.
Assez décent pour une langue qui ne fait pas vraiment de cordes.
Programme complet, 21 octets
Si vous voulez en faire un programme complet, seulement 5 octets supplémentaires sont nécessaires. Au lieu de passer l'entrée dans un registre, cela lit l'entrée des arguments passés sur la ligne de commande lors de l'appel de l'application. Un argument de 0 est interprété comme falsey, tout comme l'absence totale d'arguments; un argument supérieur à 0 est interprété comme véridique.
Assemblez simplement le code suivant en tant que programme COM, puis exécutez-le sur la ligne de commande.
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
Exemple de sortie:
C:\>bool.com
00000000000000000000000000000000
C:\>bool.com 0
00000000000000000000000000000000
C:\>bool.com 1
00000000000000000000000000000001
C:\>bool.com 2
00000000000000000000000000000001
C:\>bool.com 7
00000000000000000000000000000001
Comment ça marche? Eh bien, c'est essentiellement la même chose, jusqu'à ce que vous arriviez à l' CMP
instruction. Cela compare l'argument de ligne de commande avec la valeur du DL
registre (qui, vous vous en souvenez, contient un «0» ASCII). Dans un programme COM, les octets de code sont chargés à l'offset 0x100. Il s'agit du préfixe de segment de programme (PSP) , qui contient des informations sur l'état d'un programme DOS. Plus précisément, à l'offset 0x82, vous trouvez le premier argument (en fait le second, car le premier est un espace) qui a été spécifié sur la ligne de commande lorsque le programme a été appelé. Donc, nous comparons simplement cet octet avec un «0» ASCII.
La comparaison définit les indicateurs, puis l' SALC
instruction (un opcode non documenté avant le Pentium, équivalent à sbb al, al
, mais seulement 1 octet au lieu de 2) prend la valeur AL
0 si les deux valeurs sont égales, ou -1 si elles sont différentes. Il est alors évident que lorsque nous soustrayons AL
de DL
, cela se traduit par ASCII «0» ou «1», selon le cas.
(Notez que, quelque peu ironiquement, vous le casserez si vous passez un argument avec un 0 de tête sur la ligne de commande, car il ne regarde que le premier caractère. Il 01
sera donc traité comme falsey. :-)