简体   繁体   中英

Using BIOS interrupts in x86

I am trying to implement string operations on QEmu in real-mode. Here is the read and print function that I made:

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;
}

These functions are called in the following main program:

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

The readString function takes the input from the keyboard, prints it to the screen (on QEmu) as we type the input string and stores the result in the argument passed (which is pointer to char). But the cursor doesn't seem to move after the readString function. And the call to printString function afterwards (in the main function) causes the string to be overwritten. For example, if I write "Hello ", then I expect output to be:

Reading from input:
Hello Line read is:
Hello _

Here "_" is the cursor. But instead the actual output coming is:

Reading from input:
Line read is:
Hello

The cursor is under the "H" of the Hello above (in actual output) and the initial "Hello" in the second line of the expected output is overwritten. Why is the cursor not moving as I print the string?

When the user presses enter, you will get the CR character (code 13, \\r ). However the bios output function interprets this as strictly a carriage return, that is it moves the cursor back to the start of the line. You need to add the LF (code 10, \\n ) yourself. For example:

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屏幕截图

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM