Hi, here's one thing I don't understand. Windows may have multiple programs, processes, threads, whatever going at the same time. Each one runs in it's own memeory space, and that seems clear. Each one also gets slices of CPU time, that also makes sense.

But the registers are a pretty limite resource! Am I to presume that Windows turns over ALL of the registers to the process while it has CPU time? Does Windows page the data in and out of the registers (perhaps push them to the stack?) each time a new process takes over?

How does this affect optimizations? Does keeping data in registers really help? It seems that if Windows is obligated to push and pop these all the time, how does that help? It would be just as well to keep them in memory. I'm sure there is a simple (or not so simple) explanation.

Can someone help me see?

Greg
Posted on 2003-04-03 04:02:16 by bushpilot
Yeah, Win pushes all the registers and pops them when there's a transition. But do not be scared. Win does this usually no more than 18 times a second. And the transition takes almost nothing! A program of mine makes Windows switch between threads and processes 280 times a second, and everything is running perfectly, taking up to 20% cpu though 67 times a second the program {copies a 800x800 bitmap 3 times in sequence, each time processes it, after that it copies it to screen (redraws everything!) }
play with thread priorities if you want to make the optimizations 100% worthy, not 99.99%. :grin:

In plain English: Do NOT worry about task switching, pretend that it does not exist! The places where switching usually occurs is when you exit a window loop (WndProc (hWnd,msg,w,L){;}) and Sleep(100);. These are the places, after which you can be 99% sure that task switching occurs, so you can use them to control the cpu even more ;). I do so.
Posted on 2003-04-03 04:24:40 by Ultrano
Ah, and one more thing, you can use 8 of the registers, being sure that they will not be modified by Windows

In fact, you can use 7 registers:

EAX EBX ECX EDX ESI EDI
the 7th register that you can use is either ESP or EBP, you have to choose. To see how to use them, see
http://www.asmcommunity.net/board/index.php?topic=11767&highlight=esp2
(the bottom of the page, my post). There's described why only 7, not 8.

however, there are some nasty APIs that modify ecx and edx, and usually use eax, even if they're
void SomeApi(....);
After calling APIs, you can never be sure that EAX, ECX or EDX are the way you left them. But EBX, ESI, EDI, EBP and ESP are exactly the way you had them, so you don't have to care about saving them (push/pop tech)
Posted on 2003-04-03 04:33:25 by Ultrano
Originally posted by Ultrano
In fact, you can use 7 registers:

EAX EBX ECX EDX ESI EDI
the 7th register that you can use is either ESP or EBP, you have to choose.


You don't have to choose. Use both of them:



.DATA?
saveESP dd ? ; global variable that holds the value of ESP
saveEBP dd ? ; global variable that holds the value of EBP
saveEBX dd ? ; global variable that holds the value of EBX
saveEDI dd ? ; global variable that holds the value of EDI
saveESI dd ? ; global variable that holds the value of ESI

.CODE

myproc proc lpThis:DWORD, lpThat:DWORD

LOCAL myLocal :DWORD

mov saveESP, esp
mov saveEBP, ebp
mov saveEBX, ebx
mov saveEDI, edi
mov saveESI, esi

; Code that benefits from the use of all eight registers goes here.
; NOTE:
; Re-load EBP from saveEBP if you change it, but need to access
; the parameters or the local variable afterwards.

mov esp, saveESP
mov ebp, saveEBP
mov ebx, saveEBX
mov edi, saveEDI
mov esi, saveESI

ret

myproc endp

Regards, Frank
Posted on 2003-04-03 07:28:09 by Frank
bushpilot, there's a lot of switches going on all the time in windows. There's the usual thread switching, where the whole context is swapped (registers, FPU if used, etc). On process switching, CR3 (pagetable) is reloaded (on NT - 9x iirc patches the pagetable instead). Context is also changed on ring3<->ring0 transitions which also happen a lot, and on ugly 9x there's even 32<->16bit transitions (and for more often than you'd like).

This generally isn't much of a problem, though. Each thread gets a timeslice to run in, and the foreground application gets a priority boost. So most of the time, it's not necessary to play with thread priorities (and setting to realtime is generally foolish - it can be dangerous).
Posted on 2003-04-03 08:04:54 by f0dder
Even when Win is doing "alot" of task switching, you still usually get to run thousands, if not hundreds of thousands, of instructions in each slice. :)
Posted on 2003-04-04 01:37:04 by S/390
Frank, the code is good but prevents you from working with recursive algos. I would rather use pushes for most of the registers, push in the value of saveESP, THEN mov saveESP,esp. Then, to invert that, mov esp,saveESP, pop saveESP, then pop off all the other registers - this allows us to have completely reentrant and recursive code.

Not that reentrant code is actually USEFUL... It's just the way I'd prefer it.
Posted on 2003-04-04 02:37:29 by AmkG

But the registers are a pretty limite resource! Am I to presume that Windows turns over ALL of the registers to the process while it has CPU time? Does Windows page the data in and out of the registers (perhaps push them to the stack?) each time a new process takes over?
A process can have more than one thread. Windows keeps a copy of the registers when a thread gets switched out. This is necessary because the threads can be switched out at any time -- or from a coding point of view, at any point in the code.

Segment registers must not be altered by your code.
Posted on 2003-04-04 03:22:44 by tenkey
Well, that's not quite true. Just keep this in mind:
- avoid changing SS when executing with privilege level 0
- FS should be left with its original value when calling operating system functions
Posted on 2003-04-04 07:26:45 by Sephiroth3
Thanks for the help.

Greg
Posted on 2003-04-04 08:17:04 by bushpilot
I'm not trying to be mean or nuttin, but something I thought was a little funny..

you asked in a round-about way (but prolly didn't realize it/already knew it) if windoze owned the machine. answer is nope, it's the other way around.
It's like buying a car for it's looks and ignoring the edsel inside@.
Posted on 2003-04-15 03:13:17 by drarem
I'd say it's windows "owning" the machine - it's the one telling your CPU what to do, managing the hardware, controlling task switching (etc).
Posted on 2003-04-15 03:39:14 by f0dder
who owns the registers?

I own the registers:grin:
Posted on 2003-04-15 04:50:57 by clippy
Actually no. You're just borrowing them for a limited timeslice ^_^
Posted on 2003-04-15 04:53:57 by f0dder
They are mine. My precious :grin:

I got them. Bought then off the store. Dont need to borrow, "my precious" registers :grin:
Posted on 2003-04-15 05:00:44 by clippy
LOL true, but what allows windows to run on it? If it weren't for the structure there would not be any walls, paint, etc.. I guess windoze does the plumbing tho.

Rule of thumb: make sure your toilet is working properly or you could end up knee deep in some dark brown stuff.
Posted on 2003-04-15 06:48:01 by drarem

LOL true, but what allows windows to run on it? If it weren't for the structure there would not be any walls, paint, etc.. I guess windoze does the plumbing tho.

Rule of thumb: make sure your toilet is working properly or you could end up knee deep in some dark brown stuff.


I was eating :mad: ;)

I'm assuming that Windows will change the register contexts in the main CPU everytime it goes to another thread, but the I read somewhere in my Intel manuals that the once the CPU goes to a new task it sets the TS bit (which I think is in CR0). Once it is set and code tries to execute an FPU/SSE instruction the CPU will generate a Device Not Available exception and that is where I assume that Windows swaps the FPU/SSE context. You see its a good idea cause why restore an FPU context for a thread thats not going to use it ?
Posted on 2003-04-15 18:14:42 by x86asm
yes - especially since FPU and SSE2 registers take up quite some space.
Iirc, NT uses the IA32 tasking way to switch registers, while 9x does manual context switching - but it's been a while.
Posted on 2003-04-16 01:51:10 by f0dder