扩展 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 编译器中 char
是 signed。 'ñ'
,即 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
。
我有一个简单的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 编译器中 char
是 signed。 'ñ'
,即 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
。