У меня есть простая реализация 32-битного ядра, которую я написал в C (это автономная реализация): (Экран VGA в цветном текстовом режиме 80 * 25)
#include<stdint.h>
#define COLOR 0x39
#define VIDEO_MEMORY 0xb8000
uint32_t get_cursor();
void set_cursor(uint32_t);
void puts(char* Message);
void kmain()
{
puts("This is a test message..");
return;
}
void puts(char* Message)
{
uint32_t pointer = get_cursor();
pointer <<= 1;
char* VGA_CURSOR = (char*) VIDEO_MEMORY;
VGA_CURSOR += pointer;
while (*Message)
{
*VGA_CURSOR = *Message;
Message++;
VGA_CURSOR ++;
*VGA_CURSOR = COLOR;
VGA_CURSOR ++;
}
VGA_CURSOR -= VIDEO_MEMORY;
pointer = (uint32_t)VGA_CURSOR;
pointer >>= 1;
set_cursor(pointer);
}
Функции set_cursor и get_cursor определены в сборке следующим образом:
[bits 32]
[global set_cursor]
[global get_cursor]
set_cursor: ;ebx is the location
mov ebx,[esp+0x18]
mov al, 0x0f ;Refer to the index register table port mapping for CRT (low byte)
mov dx, 0x3d4 ; port number CRT index
out dx,al ;Write 0x0f in port 0x3D4 --- note that the port registers are 1 byte in size
mov dx,0x3d5 ;port number CRT data
mov al,bl
out dx,al
mov al, 0x0e ;Refer to the index register table port mapping for CRT (high byte)
mov dx, 0x3d4 ; port number CRT index
out dx,al
mov dx,0x3d5 ;port number CRT data
mov al,bh
out dx,al
ret
get_cursor:
mov al, 0x0f ;Refer to the index register table port mapping for CRT (low byte)
mov dx, 0x3d4 ; port number CRT index
out dx,al ;Write 0x0f in port 0x3D4 --- note that the port registers are 1 byte in size
mov dx,0x3d5 ;port number CRT data
in al,dx ;Store the low byte in al -- Hardware forced to use al
mov bl,al
mov al, 0x0e ;Refer to the index register table port mapping for CRT (high byte)
mov dx, 0x3d4 ; port number CRT index
out dx,al ;Write 0x0f in port 0x3D4 --- note that the port registers are 1 byte in size
mov dx,0x3d5 ;port number CRT data
in al,dx ;Store the high byte in al -- Hardware forced to use al
mov bh,al ;Store the high byte in bh
xor eax,eax
mov ax,bx
ret
Здесь функция getcursor, кажется, работает нормально (она получает значение курсора в диапазоне от 0 до 80 * 25). Я знаю, что реализация setcursor тоже правильная. (Я использовал это в чистых ассемблерных кодах). Я считаю, что произошла ошибка при передаче значений в стеке. Где я мог ошибаться?