在 x86 中使用 BIOS 中断
Using BIOS interrupts in 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) != '[=10=]')
{
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 函数之后光标似乎没有移动。之后(在主函数中)调用 printString 函数会导致字符串被覆盖。例如,如果我写 "Hello ",那么我希望输出为:
Reading from input:
Hello Line read is:
Hello _
这里“_”是光标。
但是实际的输出是:
Reading from input:
Line read is:
Hello
光标在上面(实际输出中)Hello的"H"下,预期输出的第二行开头的"Hello"被覆盖了。为什么我打印字符串时光标不动?
当用户按下回车键时,你会得到CR
字符(代码13,\r
)。但是 bios 输出函数将其严格解释为回车符 return,即将光标移回行首。您需要自己添加 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) != '[=10=]')
{
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 执行字符串操作。这是我制作的读取和打印功能:
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) != '[=10=]')
{
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 函数之后光标似乎没有移动。之后(在主函数中)调用 printString 函数会导致字符串被覆盖。例如,如果我写 "Hello ",那么我希望输出为:
Reading from input:
Hello Line read is:
Hello _
这里“_”是光标。 但是实际的输出是:
Reading from input:
Line read is:
Hello
光标在上面(实际输出中)Hello的"H"下,预期输出的第二行开头的"Hello"被覆盖了。为什么我打印字符串时光标不动?
当用户按下回车键时,你会得到CR
字符(代码13,\r
)。但是 bios 输出函数将其严格解释为回车符 return,即将光标移回行首。您需要自己添加 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) != '[=10=]')
{
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;
}