Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Switching stacks in C++

I have some old code written in C for 16-bit using Borland C++ that switches between multiple stacks, using longjmps. It creates a new stack by doing a malloc, and then setting the SS and SP registers to the segment and offset, resp., of the address of the malloc'd area, using inline Assembler. I would like to convert it to Win32, and it looks like the two instructions should be replaced by a single one setting the ESP. The two instructions were surrounded by a CLI/STI pair, but in Win32 these give "privileged instructions", so I have cut them out for now. I am a real innocent when it comes to Windows, so, I was rather surprised that my first test case worked! So, my rather vague question is to ask the experts here if what I am doing is a) too dangerous to continue with, or b) will work if I add some code, take certain precautions, etc.? If the latter, what should be added, and where can I find out about it? Do I have to worry about any other registers, like the SS, EBX, etc.? I am using no optimization... Thanks for any tips people can give me.

like image 887
Paul Morrison Avatar asked May 15 '09 01:05

Paul Morrison


2 Answers

Removing CLI/STI still works due to the differences in the operating environment.

On 16-bit DOS, an interrupt could occur and this interrupt would be initially running on the same stack. If you got interrupted in the middle of the operation, the interrupt could crash because you only updated ss and not sp.

On Windows, and any other modern environment, each user mode thread gets its own stack. If your thread is interrupted for whatever reason, it's stack and context are safely preserved - you don't have to worry about something else running on your thread and your stack. cli/sti in this case would be protecting against something you're already protected against by the OS.

As Greg mentioned, the safe, supported way of swapping stacks like this on Windows is CreateFiber/SwitchToFiber. This does have the side-effect of changing your entire context, so it is not like just switching the stack.

This really raises the question of what you want to do. A lot of times, switching stacks is to get by limited stack space, which was 64k on 16-bit DOS. On Windows, you have a 1 MB stack and you can allocate even larger. Why are you trying to switch stacks?

like image 149
Michael Avatar answered Nov 09 '22 22:11

Michael


By far the safest way to do this is to port the code to official Win32 multiprogramming structures, such as threads or fibers. Fibers provide a very lightweight multi-stack paradigm that sounds like it might be suitable for your application.

The Why does Win32 even have fibers? article is an interesting read too.

like image 42
Greg Hewgill Avatar answered Nov 09 '22 23:11

Greg Hewgill