[SOLVED] My memcpy and memzero destroy the stack???
Posted: Thu Mar 20, 2014 3:34 pm
Hi All,
This is my first post so sorry if I do something stupid.
Anyway, to the heart of the matter.
I am developing a kernel in Free Pascal. I have these two procedures:
Please don't mind these are slow and shuffle only 1 byte at a go, at this point it is not important.
The problem is that these DO work when called from another procedure, i.e my screen handling
procedures use memzero and memcpy to scroll the screen up, all variables are initialized with memzero,
large variables or blocks are moved around and it works. However if I try to use these inside my kmain,
they cause the system to go bananas. The screen gets trashed, and the system reboots. Looking into
BOCHS's logs is not very usefull - there's info about accessing null descriptors in the GDT, and the cause
of the reboot is always a triple fault. CR2 has a value of FFFFFFFC or something similar, and ESP is 00000000.
Please note that my kernel is not higher half, so addresses like FFFFFFFC should normally invoke the page fault handler.
This does not happen, so it seems that the IDT gets trashed as well. Please note that EIP seems to be more or less where it should be.
So my guess is that somehow the stack gets trashed? Maybe the return address gets trashed? Changing the
size of the stack seems to change the behavior a bit, i meen if I make the kernel stack ridiculously large, say 128KB
or thereabouts, it is often possible to use memzero once or twice in kmain, as long as the number of bytes to zero/copy
is small. Copying/zeroing 1000 bytes (1000, not 0x1000) always crashes the kernel.
Another funny issue is that even disabling interrupts with cli before calling memzero/memcpy does not help.
Anyone has any ideas?
Cheers,
Andrew
This is my first post so sorry if I do something stupid.
Anyway, to the heart of the matter.
I am developing a kernel in Free Pascal. I have these two procedures:
Code: Select all
procedure kernel_memzero(dest : pointer; numbytes : dword);cdecl; [public, alias: 'kernel_memzero'];
begin
asm
mov edi, dest;
mov ecx, numbytes;
xor al, al
@loop1:
mov [edi], al
add edi, 1
dec ecx
jnz @loop1
end ['EAX','ECX','EDI'];
end;
procedure kernel_memcpy(source, dest : pointer; numbytes : dword); cdecl; [public, alias: 'kernel_memcpy'];
begin
asm
mov esi, source
mov edi, dest
mov ecx, numbytes
@loop1:
mov al, [esi]
mov [edi], al
add esi, 1
add edi, 1
dec ecx
jnz @loop1
end ['EAX','ECX','EDI','ESI'];
end;
The problem is that these DO work when called from another procedure, i.e my screen handling
procedures use memzero and memcpy to scroll the screen up, all variables are initialized with memzero,
large variables or blocks are moved around and it works. However if I try to use these inside my kmain,
they cause the system to go bananas. The screen gets trashed, and the system reboots. Looking into
BOCHS's logs is not very usefull - there's info about accessing null descriptors in the GDT, and the cause
of the reboot is always a triple fault. CR2 has a value of FFFFFFFC or something similar, and ESP is 00000000.
Please note that my kernel is not higher half, so addresses like FFFFFFFC should normally invoke the page fault handler.
This does not happen, so it seems that the IDT gets trashed as well. Please note that EIP seems to be more or less where it should be.
So my guess is that somehow the stack gets trashed? Maybe the return address gets trashed? Changing the
size of the stack seems to change the behavior a bit, i meen if I make the kernel stack ridiculously large, say 128KB
or thereabouts, it is often possible to use memzero once or twice in kmain, as long as the number of bytes to zero/copy
is small. Copying/zeroing 1000 bytes (1000, not 0x1000) always crashes the kernel.
Another funny issue is that even disabling interrupts with cli before calling memzero/memcpy does not help.
Anyone has any ideas?
Cheers,
Andrew