在一个简单的 32 位内核中混合 C 和汇编代码
Mixing C and assembly code in a simple 32 bit kernel
我有一个用C写的32位内核的简单实现(这是一个独立的实现):(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的实现也是对的。 (我在纯汇编代码中使用过它)。我相信在堆栈上传递值时存在错误。
我哪里错了?
貌似错误的地方是在函数参数传递上。
c代码的objdump在调用函数的地方显示了这一点:
73: ff 75 f0 pushl -0x10(%ebp)
76: e8 fc ff ff ff call 77 <printf+0x5e>
7b: 83 c4 10 add [=10=]x10,%esp
[ebp-0x10] 是我的 指针
多变的...
我感到困惑的地方可能是 add esp,0x10。即使我只传递了 1 个参数(4 个字节),它似乎在堆栈上保留 16 个字节?
但是,看起来 [esp] 是 return 地址(4 字节 = 32 位),[esp + 4] 是第一个参数....也许 16 个字节是为了正确对齐
感谢迈克尔·佩奇:https://whosebug.com/users/3857942/michael-petch
和 Peter Cordes:https://whosebug.com/users/224132/peter-cordes 发表评论!
我有一个用C写的32位内核的简单实现(这是一个独立的实现):(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的实现也是对的。 (我在纯汇编代码中使用过它)。我相信在堆栈上传递值时存在错误。 我哪里错了?
貌似错误的地方是在函数参数传递上。 c代码的objdump在调用函数的地方显示了这一点:
73: ff 75 f0 pushl -0x10(%ebp)
76: e8 fc ff ff ff call 77 <printf+0x5e>
7b: 83 c4 10 add [=10=]x10,%esp
[ebp-0x10] 是我的 指针 多变的... 我感到困惑的地方可能是 add esp,0x10。即使我只传递了 1 个参数(4 个字节),它似乎在堆栈上保留 16 个字节?
但是,看起来 [esp] 是 return 地址(4 字节 = 32 位),[esp + 4] 是第一个参数....也许 16 个字节是为了正确对齐
感谢迈克尔·佩奇:https://whosebug.com/users/3857942/michael-petch 和 Peter Cordes:https://whosebug.com/users/224132/peter-cordes 发表评论!