Page 1 of 1
C/C++ Stack
Posted: Fri Dec 27, 2002 12:03 pm
by pskyboy
Hey Guys
A relatively quick question, when i jump from my bootloader to my C Kernel does the C Code create itsown stack or continue to use the stack that i set up in the boot loader.
Peter
Re:C/C++ Stack
Posted: Fri Dec 27, 2002 12:13 pm
by richie
Code that is generated by gcc will never change the segment registers. So your ss will have it's old value. Also esp will have it's old value but if your c-code calls a function gcc will produce a ASM-Code using a call-instruction. So your esp-register will change when gcc uses ASM-Instructions that manipulate the stack like pop, push, call, ret.
To answer your question: The C-code will use the old stack.
Re:C/C++ Stack
Posted: Fri Dec 27, 2002 8:27 pm
by Pype.Clicker
so this means that either the boot loader need to set up a large stack, or that some ASM module will be required in your kernel to move to a better stack ...
Re:C/C++ Stack
Posted: Sat Dec 28, 2002 4:18 am
by df
you will need to setup your own ESP + SS before jumping into the kernel.., I have a bit of code in the part with my multiboot header that sets all this up just before jumping into the kernel.
Code: Select all
%define d dword
%define w word
%define b byte
[bits 32]
[section .text]
global start
global __k32_startup
global _main
global ___main
global start_gdt
extern eend
extern edata
extern edata
extern etext
extern _hi_mem_start
extern _stage1_main
start:
__k32_startup:
;; init our own _known_ trusted minimal gdt.
lgdt [start_gdt]
jmp dword 8:lgdt_fixup
alignb 4, db 0x0
lgdt_fixup:
;; init our new selectors
mov edx, 0x10
mov ds,dx
mov es,dx
mov fs,dx
mov gs,dx
mov ss,dx
;; save multiboot info
mov [0x600],eax
mov [0x604],ebx
;; init mini stack
mov esp,0x10000-4
mov ebp,esp
;; clear flags
push dword 0
popfl
;; zero BSS segment
xor eax,eax
mov edi,edata
mov ecx,eend
sub ecx,edi
shr ecx,2
inc ecx
cld
rep stosd
;; page size end of kernel
add edi,0xFFF
and edi,0xFFFFF000
;; end of memory, now take 8kb for init stack
add edi,8192
mov [_hi_mem_start],edi
;; setup new esp
lea esp,[edi-4]
call _stage1_main
__k32_end: jmp __k32_end ;;/* bizarre * rule in GCC 2.9.5 */
___main: ret
alignb 4, db 0x0
start_gdt:
dw 23
dd start_gdt
dw 0
dd 0x0000ffff
dd 0x00CF9A00
dd 0x0000ffff
dd 0x00CF9200
;//
;// put our GRUB bootloader header code here
;//
align 4, db 0x0
db "GRUB Multiboot\x0"
align 8, db 0x0
multiboot_header:
dd 0x1BADB002 ;## magic
dd 0x00000003 ;## flags[16]
dd 0-(0x1BADB002 + 0x00000003) ;## zero crc of fields 1+2
Re:C/C++ Stack
Posted: Sat Dec 28, 2002 5:52 am
by pskyboy
Yeah i have one set up after i jump to PMode i just wasn't sure if the C kernel would change it when it loaded but now i know it doesn't it answers a few questions about what is going wrong. It also work out better for me as i can now put my stack exactly where i want it.
cheers
Peter
Re:C/C++ Stack
Posted: Sat Dec 28, 2002 6:29 am
by pskyboy
Hmm can you explain this to me, I have loaded my kernel at 0bytes up in memory. My data segment starts from 0 up to 4gb as does my code. I set my stack pointer to the data selector which is 0. So how come the stack doesn't go through and start overwriting the kernel?
Peter
Re:C/C++ Stack
Posted: Sat Dec 28, 2002 6:49 am
by Tim
Because the stack grows downwards. When you push something, the CPU subtracts from ESP before it writes. If you set ESP=0 and PUSH 12345678h, the CPU will write 12345678h to address FFFFFFFCh. Of course, unless you've got paging set up, that's probably not going to be a valid address (actually, it's more likely to be part of the BIOS).