Search code examples
assemblynasmdos

Why does DOS not handle '#' correctly (INT 21/AH=01h)


I had planned to submit a short and quick interpreter for ;# in DOS as a code golf challenge, when I discovered that DOS did not interpret the # key correctly.

It's probably better to start dissecting it via a smaller example that also exhibits the behaviour:

org 0x100
L:
  mov ah, 01h      ; new input -> al
  int 21h
test al, '#'       ; check if the hash key was pressed
jnz end            ; if it wasn't, jump to the end of program
  mov dl, '1'
  mov ah, 02h
  int 21h          ; otherwise, output `1`
  jmp L            ; and loop to the beginning
end:
  mov ah, 00h      ; end the program
  int 21h

Entering # into the program, will cause it to test as false, and jump to the end. As will most other characters. However, when I enter one or more of the following characters: D, L, H, X, it outputs 1 and loops. This is obviously not what was intended.

It is probably important to note that I used Dosbox for the test.

From testing, it happens for '#', 0x23, 0x01, 0x1b (The last two scancodes were from page two of this pdf, found via a random search).

What, exactly, is going on here?


Solution

  • test a,b computes the bitwise and of a and b, sets the flags and discards the results. test can in general not be used to compare two values for equality, use cmp for that purpose:

    cmp al, '#'