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

3 c x86 bios nasm bootloader

我有一个简单的操作系统(实模式),用NASM(只有bootloader)编写,大多数用C编写.

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

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

void println(char *str)
{
    while (*str)
        putch(*str++);
}
Run Code Online (Sandbox Code Playgroud)

现在,我尝试打印ñ:

println("ñ\r\n");
Run Code Online (Sandbox Code Playgroud)

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

Ant*_*ala 6

问题很简单.在x86编译器char签名.'ñ',即被0xA4认为是否定的(-92).签名char被提升为int(通常的算术促销)|.这通过符号扩展来实现.

结果值当然是-92(0xFFA4),其中|ed 0x0E00将导致0xFFA4...这意味着代替函数AH = 0Eh我们现在调用函数AH = FFh ...如果它甚至存在.

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

void putch(int chr)
{
    __asm__ __volatile__ ("int $0x10"
                          :
                          : "a" ((0x0e<<8) | (unsigned char)chr),
                            "b" (0x0000));
}
Run Code Online (Sandbox Code Playgroud)

或者只是让它unsigned char像评论中建议的那样接受参数.

  • @MichaelPetch是的,效果就像你评论一样,但是当我传递的值已经为负时,对促销使得价值为负的步骤的解释听起来像我. (2认同)