【发布时间】:2016-06-23 16:10:08
【问题描述】:
最近我决定编写一些简单的 MSDOS 游戏,这很有趣。不用说,我需要处理键盘事件的代码。
这是我想出的测试:
int i, c = 0;
for ( i = 0; i < 10; i++ )
{
asm
(
"mov $0x00, %%ah \n"
"mov $0x00, %%al \n"
"int $0x16 \n"
//"jnz keydn \n"
//"mov $0x00, %%al \n"
//"keydn: \n"
"movw %%ax, (%0) \n"
: "=r"(c)
);
printf( "%d\n", c & 0xFF );
}
代码应该等待按键,然后打印出字符的 ASCII 值。 除非我按 backspace 或 esc 之类的键,否则一切都会按预期工作 - 然后会发生分段错误。
我不熟悉组装,但我真的无法弄清楚可能导致此错误的原因。
我使用djgpp 编译,并在DosBox 中运行可执行文件
一切都基于此处提供的信息:
- https://courses.engr.illinois.edu/ece390/books/artofasm/CH20/CH20-3.html
- https://en.wikipedia.org/wiki/BIOS_interrupt_call
提前感谢您! :)
【问题讨论】:
-
"mov $0x00, %%ah\n" "mov $0x00, %%al\n"可以替换为"xor %%ax, %%ax\n"或更好,但使用输入操作数将0传递到模板中(寄存器a可以成为输入和输出操作数) .这将消除模板本身将 AX 寄存器归零的需要。 -
@MichaelPetch 对,我明白它是如何工作的,但正如我之前所说,我以前从未使用过裸组装,所以我想让一切尽可能简单。无论如何,它会提高执行速度还是什么?
-
是的,如果您为受限的内存环境编写代码,则需要更少的内存字节进行编码。
-
@MichaelPetch 我明白了。根据我今天的经验,我可以看到,即使是组装基础也相当棘手。无论如何,我认为在这种情况下我不需要一些出色的性能,至少在键盘处理程序中,因为我使用的系统计时器以 18.2Hz 运行,这真的很慢。当它通过软盘在真正的 PC 上运行时,我会将整个过程视为成功;)
-
这个问题:stackoverflow.com/questions/421860/…> 对您的问题有几个有效的、可移植的答案。
标签: c assembly segmentation-fault dos djgpp