Stack Problem

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
HardEnough

Stack Problem

Post by HardEnough »

hi guys
i've a problem with the stack.
my code works fine if the interrupt() function returns the esp it takes as a parameter, but i got [CPU ] can_push(): expand-down: esp-N < limit when i return my own stack.
i can't figure what's wrong, can any body help me ?

here is my code

Code: Select all

isr20h:
irq0:
   pusha
   push   gs
   push   fs
   push   es
   push   ds
   mov   ax, 10h
   mov   gs, ax
   mov   fs, ax
   mov   es, ax
   mov   ds, ax
   push   dword 00h
   push   dword 20h
   push   dword esp
   call   interrupt
   mov   esp, eax
   mov   al, 20h
   out   20h, al
   add   esp, 08h
   pop   ds
   pop   es
   pop   fs
   pop   gs
   popa
   iret

Code: Select all

int stack[87];
main()
{
stack[70]=0x28;
  stack[71]=0xfffffffe;
  stack[72]=0x0202;
  stack[73]=0x18;
  stack[74]=(int)test;
  stack[75]=0;
  stack[76]=0;
  stack[77]=0;
  stack[78]=0;
  stack[79]=0;
  stack[80]=0;
  stack[81]=0;
  stack[82]=0xfe;
  stack[83]=0x20;
  stack[84]=0x20;
  stack[85]=0x20;
  stack[86]=0x20;
  for(;;);

Code: Select all

int interrupt(int esp, int num, int err)
{
  int *p;
  p=&stack;
  p+=87;
  return (int)p;
}

Code: Select all

void test()
{
  kprint('T');
}
bluecode

Re:Stack Problem

Post by bluecode »

hi
HardEnough wrote:

Code: Select all

isr20h:
irq0:
   pusha
   push   gs
   push   fs
   push   es
   push   ds
   mov   ax, 10h
   mov   gs, ax
   mov   fs, ax
   mov   es, ax
   mov   ds, ax
   ;Push 3dword = 12byte
   push   dword 00h
   push   dword 20h
   push   dword esp
   call   interrupt
   mov   esp, eax
   mov   al, 20h
   out   20h, al
   ;You should also pop 3dwords
   add   esp, 0Ch
   pop   ds
   pop   es
   pop   fs
   pop   gs
   popa
   iret
HardEnough

Re:Stack Problem

Post by HardEnough »

sorry, no
it didn't work if i added esp, 0ch
it only works if i added esp,08h and i return the same esp which was pushed on the stack
HardEnough

Re:Stack Problem

Post by HardEnough »

do u know why we need just add esp,8h
because we pushed esp to interrupt() which was the esp value before this push (esp+4) and interrupt function just returns the same esp it takes as a parameter which is (esp before the push esp) so just need to add esp,8
AR

Re:Stack Problem

Post by AR »

The stack creation code doesn't account for:

Code: Select all

; ...
   push   dword 00h
   push   dword 20h
   push   dword esp
   call   interrupt
; ...
as far as I can tell which may cause problems popping the segment registers.

Your test function can cause stack problems as well, that C function compiles as:

Code: Select all

.global test
.type test, @function
test:
push %ebp
mov %esp, %ebp
pushl $test_string_constant
call kprintf
leave
ret
The RET will pop EIP which will send the CPU to some undefined location until the next timer interrupt, you'll want to put a forever loop at the end of it as well to prevent this.
AR

Re:Stack Problem

Post by AR »

The Add 8 instead of 12 thing is caused by a little quirk with "push esp", it breaks down as "[ESP - 4] = ESP" (so the value pushed is actually a pointer to before the ESP value itself).

Essentially, by returning that ESP value it automatically pops ESP for you.
HardEnough

Re:Stack Problem

Post by HardEnough »

The RET will pop EIP which will send the CPU to some undefined location until the next timer interrupt, you'll want to put a forever loop at the end of it as well to prevent this.
i did, but nothing
HardEnough

Re:Stack Problem

Post by HardEnough »

Code: Select all

osdk_create_task:
   push   ebp
   mov   ebp, esp
   push   ebx
   mov   ebx, dword [ebp+8]
   mov   [ebx], dword 0202h ; eflags
   mov   [ebx+4], dword 18h ;  cs
   mov   eax, dword [ebp+12]
   mov   [ebx+8], dword eax   ; eip
   mov   [ebx+12], dword 00h ; ebp
   mov   eax, dword [ebp+16]
   mov   [ebx+16], dword eax ; esp
   mov   [ebx+20], dword   00h ; edi
   mov   [ebx+24], dword 00h ; esi
   mov   [ebx+28], dword   00h ; edx
   mov   [ebx+32], dword   00h ; ecx
   mov   [ebx+36], dword 00h ; ebx
   mov   [ebx+40], dword   00h ; eax
   mov   [ebx+44], dword 20h ; gs
   mov   [ebx+48], dword 20h ; fs
   mov   [ebx+52], dword 20h ; es
   mov   [ebx+56], dword   20h ; ds
   mov   [ebx+60], dword 00h ; error code
   mov   [ebx+64], dword   20h ; interrupt 20h
   mov   eax, ebx
   add   eax, 64
   pop   ebx
   mov   esp, ebp
   pop   ebp
   ret

Code: Select all

unsigned int osdk_create_task(unsigned int, void(* func)(), unsigned int);


unsigned int stack[99]; /*i don't have a mm till now, so i reserve space*/
unsigned int taskesp;

main()
{
  taskesp=osdk_create_task((unsigned int)stack,test, 0xffffffe);
  for(;;);
}

int interrupt(int esp, int num, int err)
{
  //return esp;
  return taskesp;
}

void test()
{
  kprint('M');
  for(;;);
}
This latest code gives [CPU ] fetch_raw_descriptor: LDTR.valid=0 !!!
HardEnough

Re:Stack Problem

Post by HardEnough »

sorry, there will a problem in osdk_create_task

Code: Select all

osdk_create_task:
   push   ebp
   mov   ebp, esp
   push   ebx
   mov   ebx, dword [ebp+8]
   mov   [ebx+00], dword 0202h ; eflags
   mov   [ebx+04], dword 08h ;  cs
   mov   eax, dword [ebp+12]
   mov   [ebx+08], dword eax   ; eip
   mov   [ebx+12], dword 00h ; ebp
   mov   eax, dword [ebp+16]
   mov   [ebx+16], dword eax ; esp
   mov   [ebx+20], dword   00h ; edi
   mov   [ebx+24], dword 00h ; esi
   mov   [ebx+28], dword   00h ; edx
   mov   [ebx+32], dword   00h ; ecx
   mov   [ebx+36], dword 00h ; ebx
   mov   [ebx+40], dword   00h ; eax
   mov   [ebx+44], dword 10h ; gs
   mov   [ebx+48], dword 10h ; fs
   mov   [ebx+52], dword 10h ; es
   mov   [ebx+56], dword   10h ; ds
   mov   [ebx+60], dword 00h ; error code
   mov   [ebx+64], dword   20h ; interrupt 20h
   add   ebx, 68
   mov   eax, ebx
   pop   ebx
   mov   esp, ebp
   pop   ebp
   ret
HardEnough

Re:Stack Problem

Post by HardEnough »

This my last code, it works ;-)

Code: Select all

isr20h:
irq00h:
   pusha
   push   gs
   push   fs
   push   es
   push   ds
   mov   ax, 10h
   mov   gs, ax
   mov   fs, ax
   mov   es, ax
   mov   ds, ax
   push   dword 00h
   push   dword 20h
   push   dword esp
   call   interrupt
   mov   esp, eax
   mov   al, 20h
   out   20h, al
   add   esp, 08h
   pop   ds
   pop   es
   pop   fs
   pop   gs
   popa
   iret

Code: Select all

create_task:
   push   ebp
   mov   ebp, esp
   mov   esp, dword [ebp+08]
   push   dword   0202h  ; eflags
   push   dword   08h   ; cs
   mov   eax, dword [ebp+12]
   push   dword   eax   ; eip
   push   dword   00h   ; eax
   push   dword   00h   ; ecx
   push   dword   00h   ; edx
   push   dword   00h   ; ebx
   mov   eax, dword [ebp+16]
   push   dword   eax   ; esp
   push   dword   00h   ; ebp
   push   dword   00h   ; esi
   push   dword   00h   ; edi
   push   dword   10h   ; gs
   push   dword   10h   ; fs
   push   dword   10h   ; es
   push   dword   10h   ; ds
   push   dword   00h   ; error code
   push   dword   20h   ; interrupt number
   mov   eax, esp
   mov   esp, ebp
   pop   ebp
   ret

Code: Select all

void koko(void);
void wawa(void);
int create_task(int, int, int);

int timer=0;
int seconds=0;

int koko_kstack[90];
int wawa_kstack[90];
int koko_ustack[90];
int wawa_ustack[90];
int koko_esp;
int wawa_esp;

#define NONE -1
#define KOKO 1
#define WAWA 2
int task;

main()
{
  koko_esp=osdk_create_task((int)&koko_kstack[89],(int)&koko, (int)&koko_ustack[89]);
  wawa_esp=osdk_create_task((int)&wawa_kstack[89],(int)&wawa, (int)&wawa_ustack[89]);
  task=NONE;
  for(;;);
}

int interrupt(int esp, int num, int err)
{
 if(num==0x20)
    {
      timer++;
      if(timer % 50 == 0)
   seconds++;
     }

if(task!=NONE)
    {  
      if (task==KOKO){
   koko_esp=esp;
   task=WAWA;
   return wawa_esp;
      }

    else{
      wawa_esp=esp;
      task=KOKO;
      return koko_esp;
    }
    }else{
      task=KOKO;
      return koko_esp;
  }
}

Code: Select all

void koko()
{
  kputchar('K');
  while(1){
    if(seconds==10){
      kputchar('K');
      while(1){
   if(seconds==11){
     kputchar('W');
     break;
   }
      }
    }
  }
}

void wawa()
{
  kputchar('W');
  while(1){
    if(seconds==12){
      kputchar('W');
      while(1){
   if(seconds=15){
     kputchar('W');
     break;
   }
      }
    }
  }
}

So if i need to use cpl3 tasks, (i know i should update tss) should i push ss3 and esp3 in create_task() function before the eflags ??
Thanks alot
Post Reply