已编辑:仅显示带有""的printf。
int main (int argc, char *argv[])
{
REGPACK Regs;
KEY_DATA KeyData
//Set cursor position AH= 02h, BH = Page Number, DH = Row, DL = Column
Regs.h.ah = 0x02;
Regs.h.bh = 0;
Regs.h.dh = 15;
Regs.h.dl = 40;
intr(0x10, &Regs);
printf("Test");
while (KeyData.Key.ScanCode != SCAN_ESC) {
GetKey(&KeyData);
printf("Key: %c", KeyCode.Key.AsciiChar);
}
return 0;
}
代码段如上所示:
编码环境:视窗8.1
工具链:Open Watcom (WCL & WASM) v1.9
执行于: DOSBox, 真正的 DOS 6.22
首先,我发现"printf"不会在屏幕上打印任何内容,没有显示"测试"或"键:X"。然后我开始敲击键盘,大约4~6次击键,琴弦会成堆地出来,就像:
TestKey: aKey: bKey: cKey: d
每连续击键4~6次出现相同的症状。
另一种情况,我没有按任何东西,printf 将无法运行,一旦我通过按"ESC"终止该程序,两个字符串将显示在屏幕的左上角,就像没有问题一样。
所以我开始认为这个片段有问题,printf 仅在发生 DOS 程序终止信号时起作用(INT 21h AH=4Ch)。
我已经在纯汇编中重写了"设置光标位置"的东西,并对 proc 进行了近乎调用,该错误仍然发生,并且我将设置光标位置从视频模式 3(INT 10h,AH=00,AL=03h)更改为设置视频模式 3)刷新屏幕,也没有运气。
无论我使用什么方法,在 INT10h 之后,printf 在 DOS 终止信号之前都不起作用。
有谁知道为什么会这样?有没有办法避免这种情况,或者让我使用与 INT10h 混合的 printf?
但是在这种情况下,putc 和 put 可以正常地打印在屏幕上,并且 printf 仅在存在""字符(例如"helloworld")时才有效。我超级困惑...
我不能放弃 INT10h,因为 MSDOS 没有原生支持这类操作,而 BIOS 调用也很有效,我也不能放弃 printf,因为可变参数真的为我节省了很多屁股。
谢谢大家!
the indicated source would fail to successfully compile
for several reasons, including:
1) two warnings about unused parameters argc and argv
2) unrecognized function: prtinf()
You can get 'immediate' output from printf calls by ending the
format string with 'n'
--or--
following the printf with the statement: fflush(stdout);
otherwise, the output is buffered until the OS feels like/has time to
actually output it. (as for instance, when the program terminates
谢谢大家!发现我真的缺乏这种知识。
无论如何,如果禁用标准输出缓冲,整个事情都可以工作。
仍然不知道为什么它在 INT10h 之后表现得如此奇怪,我预计在大规模页面打印上会产生很大的开销,但至少它现在可以工作。下面是代码片段。
int main (int argc, char *argv[])
{
REGPACK Regs;
KEY_DATA KeyData
//Disable stdout buffer
setbuf(stdout, NULL);
//Set cursor position AH= 02h, BH = Page Number, DH = Row, DL = Column
Regs.h.ah = 0x02;
Regs.h.bh = 0;
Regs.h.dh = 15;
Regs.h.dl = 40;
intr(0x10, &Regs);
printf("Test");
while (KeyData.Key.ScanCode != SCAN_ESC) {
GetKey(&KeyData);
printf("Key: %c", KeyCode.Key.AsciiChar);
}
return 0;
}