我正在创建一个非常低级的应用程序,我已准备好引导加载程序。我基本上必须重建scanf()函数,因为我不能在项目中使用任何库。在Assembly中可以读取输入的一个好的基本应用程序是什么?我可以处理它读入C char []或我想要的任何其他数据类型,我只需要弄清楚如何在没有任何系统调用的情况下读取输入。
答案 0 :(得分:1)
看来你正在为真实模式编写代码。您没有说明您正在使用哪个 C 编译器,但您自己的答案表明您实际上处于实模式。我推荐WATCOM's C compiler,因为它可以生成真正的16位代码。如果您使用带有-m16
选项的 GCC ,我不建议将其用于16位代码。我有另一个Stackoverflow答案,讨论了一些GCC issues。
DOS和BIOS中断信息的最佳来源是Ralph Brown's Interrupt List。有关通过Int 16h/AH=00进行单次击键的信息是:
键盘 - 获取钥匙扣
AH = 00h
返回:
AH = BIOS scan code AL = ASCII character
此BIOS功能不会回显字符,因此另一个有用的BIOS功能是Int 10h/AH=0eh向终端显示单个字符:
视频 - TELETYPE OUTPUT
AH = 0Eh AL = character to write BH = page number BL = foreground color (graphics modes only)
返回:
Nothing
描述:在屏幕上显示一个字符,推进光标并根据需要滚动屏幕
要在文本模式下打印字符,您可以将 BX 置于0,该字符将在 AL 中打印并调用中断。
使用上面的信息,您可以使用内联汇编在两个BIOS中断周围编写一些简单的包装器。在 GCC 中,您可以使用Extended Inline Assembly templates。它们看起来像这样:
#include <stdint.h>
static inline void
printch (char outchar, uint16_t attr)
{
__asm__ ("int $0x10\n\t"
:
: "a"((0x0e << 8) | outchar),
"b"(attr));
}
static inline char
getch (void)
{
uint16_t inchar;
__asm__ __volatile__ ("int $0x16\n\t"
: "=a"(inchar)
: "0"(0x0));
return ((char)inchar);
}
在Watcom C中,您可以使用#pragma aux
创建函数:
#include <stdint.h>
void printch(char c, uint16_t pageattr);
char getch(void);
#pragma aux printch = \
"mov ah, 0x0e" \
"int 0x10" \
parm [al] [bx] nomemory \
modify [ah] nomemory
#pragma aux getch = \
"xor ah, ah" \
"int 0x16" \
parm [] nomemory \
modify [ah] nomemory \
value [al]
使用这些基本功能,您只需要编写一个从用户获取字符串的函数,在输入时回显字符,并将它们存储在缓冲区中。返回换行符的ASCII字符getch
是回车符 \r
(0x0d)。当我们达到所请求的最大字符数或遇到换行符时,我们停止并且NUL终止该字符串。这样的功能看起来像:
/* Get string up to maxchars. NUL terminate string.
Ensure inbuf has enough space for NUL.
Carriage return is stripped from string.
Return a pointer to the buffer passed in.
*/
char *getstr_echo(char *inbuf, int maxchars)
{
char *bufptr = inbuf;
while(bufptr < (inbuf + maxchars) && (*bufptr = getch()) != '\r')
printch(*bufptr++, 0);
*bufptr = '\0';
return inbuf;
}
如果您不希望使用内联汇编,则可以创建一个装配模块,其中getch
和printch
在纯装配中完成。这比使用内联汇编生成的代码效率低,但它更不容易出错。
getstr_echo
函数功能不完整,可用作您自己代码的起点。它无法正确处理 backspace 等内容。