From: Jason FU wrote:
No, it doesn't 'work fine' under Linux.  In fact it doesn't work at all,
on any platform.

My apologies for sending something that doesn't work under Linux, but I had 
something similar working, but I wanted to cut it down for the sake of the 
mailing list, and I didn't have access to a Linux machine just then to test it 
again.

Anyway, this similar code does work under Linux, or at least it appears to:

#include <stdio.h>
int main() {
        void * st1, *oldstack;
        st1 = (void *)malloc(5000) + 5000;
        asm("mov %%esp, %0" : "=r" (oldstack));
        asm("mov %0, %%esp" : : "r" (st1));
        a();
        asm("mov %0, %%esp" : : "r" (oldstack));
}

int a() {
        printf("hello\n");
}

This is a cut down of a more complex bit of code that does a lot of switching 
stacks and works fine on Linux but not cygwin.

Where on earth do you think main is going to return to after
you've discarded the old stack like that?

Yes I know I didn't restore the stack, because I wasn't trying to show what 
happens when main returns, I was trying to show that printf crashes way before 
that ever becomes an issue. I've left the stack restoring code in the above 
version.

The stack is for the compiler's use, keep your hands off of it!

Uh, did you ask Linus Torvalds what he thinks about that?

You just threw away the stack and jumped into space.  What did you expect
to happen?

While I don't claim to be an uber-expert in assembler, I know I didn't "jump into 
space". I've written task switching programs in C under DOS that switch stacks with 
no problem.

Christopher Faylor wrote:

I would expect that a multi-threaded linux app would not like the above.

That may well be, but I can't see why. Multiple threads generally are just 
saving and restoring the registers, and don't care what stack those registers 
point to. In the old days with user space threading, I presume the user space 
code would be doing what I'm trying to do and creating its own stack.

Windows stores information about the stack in offsets from the %fs register.

You may be onto something there. Maybe Windows checks with the TEB that the 
stack hasn't overflowed and gets confused or something. Maybe restoring the 
system stack before any system calls is the only work around. The following 
code seems to work under cygwin. That work around might be fine for what I'm 
doing. Will have to think about it.

#include <stdio.h>
#include <setjmp.h>

int main() {
        void * st1, *oldstack;
        st1 = (void *)malloc(5000) + 5000;
        asm("mov %%esp, %0" : "=r" (oldstack));
        asm("mov %0, %%esp" : : "r" (st1));
        a(oldstack);
        asm("mov %0, %%esp" : : "r" (oldstack));
fprintf(stderr, "hello2\n"); }

int a(void * oldstack) { void * savestack;
        asm("mov %%esp, %0" : "=r" (savestack));
        asm("mov %0, %%esp" : : "r" (oldstack));
fprintf(stderr, "hello\n"); asm("mov %%esp, %0" : "=r" (savestack));
}



--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

Reply via email to