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).