I'm testing user level context switching. Wanted to control vehaviors of the
switching process in detail. So borrowed the following code which are
basically setjmp and longjmp from glibc.
I faced a exotic situation soon. Originally I tested the code with gcc
version 2.96-85. and the test program worked. But using gcc version 2.96-81,
the result was segmentation fault when executing the line -- movl
(4*5)(%ecx), %edx /* PC */ -- in restore_context().
want to know why the difference is made.
thanks in advance.
Here is header file.
---------------------------------------------------------
#ifndef __CSW_H__
#define __CSW_H__
typedef int hdcontext[6];
extern int save_context(hdcontext env);
extern int restore_context(hdcontext env, int val);
#endif /* __CSW_H__ */
---------------------------------------------------------
And assembly code
---------------------------------------------------------
/* on i386 platform */
.section .text
.globl save_context
save_context:
movl 4(%esp), %eax /* jump_buf address */
movl %ebx, (4*0)(%eax) /* BX */
movl %esi, (4*1)(%eax) /* SI */
movl %edi, (4*2)(%eax) /* DI */
leal 8(%esp), %ecx /* pointer of jmup_buf address */
movl %ecx, (4*4)(%eax) /* SP */
movl (%esp), %ecx /* the return address */
movl %ecx, (4*5)(%eax) /* PC */
movl %ebp, (4*3)(%eax) /* BP */
xorl %eax, %eax
ret
.globl restore_context
restore_context: /* Don't care current stack frame */
/* two arguments: pointer to buffer for context and return value */
movl 8(%esp), %eax /* return value */
movl 4(%esp), %ecx /* pointer to buffer */
movl (4*5)(%ecx), %edx /* PC */
movl (4*0)(%ecx), %ebx /* BX */
movl (4*1)(%ecx), %esi /* SI */
movl (4*2)(%ecx), %edi /* DI */
movl (4*3)(%ecx), %ebp /* BP */
movl (4*4)(%ecx), %esp /* SP */
jmp *%edx
---------------------------------------------------------
finally source code for test.
---------------------------------------------------------
#include "csw.h"
#include <stdio.h>
#include <unistd.h>
char teststack[1024*8];
void* test(void* arg) {
while(1) {
printf("doing jobs\n");
sleep(1);
}
return NULL;
}
unsigned int ctx[6];
int main() {
printf("stack: %p ~ %p\n", teststack, teststack + sizeof(teststack) -
1);
ctx[3] = teststack + sizeof(teststack)-1;
ctx[4] = teststack + sizeof(teststack)-1;
ctx[5] = (unsigned char*)test;
printf("before restore_context -- test: %p, ctx: %p\n", test, ctx);
restore_context(ctx, 0xdeadbeef);
return 0;
}
---------------------------------------------------------
I suspect that *should* always fail, but random chance keeps it from dying in
one instance.
Just for my own amusement I wrote something like
that some time ago. My code can be found here:
http://www.daimi.au.dk/~kasperd/scheduler.c
It is C code all the way through, but that doesn't
mean it is portable. The code does rely on the use
of registers and stacklayout.
--
Kasper Dupont -- der bruger for meget tid pĺ usenet.
For sending spam use mailto:aaa...@daimi.au.dk
or mailto:mcxumhv...@skrammel.yaboo.dk
"mlw" <deve...@mohawksoft.com> ~{P4HkO{O"PBNE~}
:3D56668E...@mohawksoft.com...
> I would compile the test program with -S on both compiles and see what the
> difference in the generated assmebly code is.
>
> I suspect that *should* always fail, but random chance keeps it from dying
in
> one instance.
>
> > printf("stack: %p ~~ %p\n", teststack, teststack +
"Bill zhao" <zh...@onelink.com.cn> 写入消息新闻
:ak2394$k82$1...@debian.bentium.com...
> By the way, Where can I find out the materials about explaining
> "assembly language"
http://webster.cs.ucr.edu/Page_asm/0_Page_asm.html
This gets you to Art of Assembly Language, a college-level text in PDF,
It seems well done.
--
Larry Ebbitt - Linux(Cntr #80621) + OS/2 - Atlanta
"Linux Assembly language programming" by Bob Neveln is an excellent
introduction.
Eric Worrall
--
You have just received an Etech Solution
For all your Linux requirements contact
ewor...@netcomuk.co.uk