在x86中使用BIOS中断

时间:2015-03-03 18:44:42

标签: c assembly x86

我正在尝试在实模式下在QEmu上实现字符串操作。这是我所做的读取和打印功能:

int readString(char* line)
{
 int i = 0;
 char in = 0x0;
 while (in != 0xd)
   {
    in = interrupt(0x16, 0x0, 0x0, 0x0, 0x0);
    *(line + i) = in;
    interrupt(0x10,0xe*0x100+in,0x0,0x0,0x0);
    i++;
   }
 *(line + i) = 0x0;
 return i;
}

int printString(char* string)
{
 int i = 0;
 while (*(string + i) != '\0')
   {
    char al = *(string + i);
    char ah = 0xe;
    int ax = ah * 256 + al;
    interrupt(0x10,ax,0,0,0);
    i++;
   }
 return i;
}

在以下主程序中调用这些函数:

void main()
{
 char* line;
 printString("Reading from input:\n\r");
 readString(line);
 printString("Line read is:\n\r");
 printString(line);
}

readString函数从键盘输入,在我们输入输入字符串时将其输出到屏幕(在QEmu上),并将结果存储在传递的参数中(这是指向char的指针)。 但是光标在readString函数之后似乎没有移动。之后(在main函数中)调用printString函数会导致字符串被覆盖。例如,如果我写" Hello",那么我希望输出为:

Reading from input:
Hello Line read is:
Hello _

这里" _"是光标。 但相反,实际输出是:

Reading from input:
Line read is:
Hello

光标位于" H"上面的Hello(在实际输出中)和初始" Hello"在预期输出的第二行被覆盖。为什么在打印字符串时光标不会移动?

1 个答案:

答案 0 :(得分:4)

当用户按Enter键时,您将获得CR字符(代码13,\r)。然而,bios输出函数将其解释为严格的回车符,即它将光标移回到行的开头。您需要自己添加LF(代码10,\n)。例如:

int readString(char* line)
{
 int i = 0;
 char in = 0x0;
 while (in != 0xd)
   {
    in = interrupt(0x16, 0x0, 0x0, 0x0, 0x0);
    *(line + i) = in;
    interrupt(0x10,0xe*0x100+in,0x0,0x0,0x0);
    /* add LF to CR */
    if (in == 13) interrupt(0x10,0xe*0x100+10,0x0,0x0,0x0);
    i++;
   }
 *(line + i) = 0x0;
 return i;
}

int printString(char* string)
{
 int i = 0;
 while (*(string + i) != '\0')
   {
    char al = *(string + i);
    char ah = 0xe;
    int ax = ah * 256 + al;
    interrupt(0x10,ax,0,0,0);
    /* add LF to CR */
    if (al == 13) interrupt(0x10,0xe*0x100+10,0x0,0x0,0x0);
    i++;
   }
 return i;
}

qemu screenshot