扩展 ASCII 字符在 int 10h 中不起作用

extended ASCII characters not working in int 10h

我有一个简单的OS(实模式),用NASM(仅引导加载程序)编写,大部分用C编写。

我想打印这个字符:ñ,我使用这个使用 int 10h 的函数将一个字符打印到屏幕上:

void putch(char chr)
{
    __asm__ __volatile__ ("int [=10=]x10"
                          :
                          : "a" ((0x0e<<8) | chr),
                            "b" (0x0000));
}

void println(char *str)
{
    while (*str)
        putch(*str++);
}

现在,我尝试打印 ñ:

println("ñ\r\n");

但是当我编译和执行时(在qemu和VB框中),字符“ñ”被忽略了。 我用 CP-437 编码保存了源代码,但问题仍然存在。 这也会影响所有扩展的 ASCII 字符。

问题很简单。在 x86 编译器中 charsigned'ñ',即 0xA4 被认为是负值 (-92)。对于 |,已签名的 char 被提升为 int(通常的算术提升)。这是通过符号扩展发生的。

结果值当然是 -92 (0xFFA4),用 |0x0E00 将导致 0xFFA4... 这意味着我们现在调用函数 AH=FFh 而不是函数 AH=0Eh... 如果它存在的话。

一个解决方案是让 putch 将参数作为 int 并将其转换为 unsigned char,就像 C 函数 putchar 一样:

void putch(int chr)
{
    __asm__ __volatile__ ("int [=10=]x10"
                          :
                          : "a" ((0x0e<<8) | (unsigned char)chr),
                            "b" (0x0000));
}

或者像评论中建议的那样,让它接受参数作为 unsigned char