为什么 DOS 不能正确处理 '#' (INT 21/AH=01h)

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

我原计划在 DOS 中提交一个简短而快速的 ;# 解释器作为代码高尔夫挑战,当我发现 DOS 没有正确解释 # 键时。

最好通过一个同样表现出行为的较小示例开始剖析它:

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

在程序中输入#,会导致测试为false,并跳转到最后。和大多数其他角色一样。但是,当我输入以下一个或多个字符时:DLHX,它会输出 1 并循环。这显然不是预期的。

可能需要注意的是,我使用 Dosbox 进行测试。

根据测试,它发生在 '#'0x230x010x1b(最后两个扫描码来自 this pdf 的第二页,通过随机搜索找到)。

这里到底发生了什么?

test a,b 计算 ab 的按位与,设置标志并丢弃结果。 test 通常不能用于比较两个值是否相等,为此目的使用 cmp

cmp al, '#'