Page 1 of 1

populating a struct with the stack

Posted: Wed Mar 15, 2006 10:42 pm
by earlz
is there any simple way to copy stuff from the stack in C

like copy
this:
__asm(
".intel_syntax noprefix\n"
"pushad\n" //push general registers for old task
"push ds\npush es\npush fs\npush gs\n" //push segments for old task

".att_syntax\n");

into this struct:
typedef struct{
unsigned int eip,cs,eflags,esp,ss; //iret
segments segs;
registers gregs;
}Task
__attribute__((packed));

Re:populating a struct with the stack

Posted: Thu Mar 16, 2006 2:39 am
by Pype.Clicker
well, first you usually don't put preamble/postamble code as inline, but rather have it as a separate piece of code in a .asm file.

From then,
- either you want your struct populated for error reporting, in which case,

Code: Select all

  push esp    ; all the saved state is from current stack pos, 
  call C_interrupt_handler ; and will be arg. of C_i_h
  add esp,4   ; remove argument
should do it (e.g. no need for copying: just get the pointer.

- or you want it for some sort of software multitasking (which the "Task" name might confirm), in which case i suggest you read about the stack-switching mechanisms in the FAQ.
Software context switching can be used on all CPUs, and can be used to save and reload only the state that needs to be changed. The basic idea is to provide a function that saves the current stack pointer (ESP) and reloads a new stack pointer (SS:ESP). When the function is called EIP would be stored on the old stack and a new EIP would be popped off the new stack when the function returns. Of course the operating system usually needs to change much more than just the stack and EIP.

Re:populating a struct with the stack

Posted: Sat Mar 18, 2006 4:19 pm
by Candy
Jordan3 wrote: is there any simple way to copy stuff from the stack in C

like copy
this:
__asm(
".intel_syntax noprefix\n"
"pushad\n" //push general registers for old task
"push ds\npush es\npush fs\npush gs\n" //push segments for old task

".att_syntax\n");

into this struct:
typedef struct{
unsigned int eip,cs,eflags,esp,ss; //iret
segments segs;
registers gregs;
}Task
__attribute__((packed));
The first variable on the stack is just below the struct. Note that the struct reads values from the bottom up (in your struct the order would be wrong), whereas the processor uses the stack top-down. You take the address of the first variable and cast it (or it + its size) to the struct type. Then you have a struct parameter pointer.

You COULD just try to use the official way, but it's probably hard to get right:

Code: Select all

asm:

  push eax
  push ecx
  push edx
  push ebx
  push ss
  push cs
  call function ; pushes eip
  add esp, 24


c:
struct regs {
  unsigned int cs, ss, ebx, edx, ecx, eax;
};

void function(struct regs r) {
  // r points to the assembly-regs here
}
Is this what you meant? Note, you need to test this code first, I don't test this stuff.

Re:populating a struct with the stack

Posted: Sat Mar 18, 2006 9:59 pm
by earlz
I probably should have said something but i realized that i dont have to do this, all i have to do is know SS and ESP and then since i have all regs pushed and an int happened before i know everything i need to know for a failsafe task switch

Thank you anyway though