C/C++ Stack

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
pskyboy

C/C++ Stack

Post 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
richie

Re:C/C++ Stack

Post 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.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:C/C++ Stack

Post 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 ...
User avatar
df
Member
Member
Posts: 1076
Joined: Fri Oct 22, 2004 11:00 pm
Contact:

Re:C/C++ Stack

Post 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

-- Stu --
pskyboy

Re:C/C++ Stack

Post 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
pskyboy

Re:C/C++ Stack

Post 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
Tim

Re:C/C++ Stack

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