views:

373

answers:

2

How does Windows switch to supervisor mode during a system call? I heard something about a "trap 0", but that doesn't even seem like an x86 instruction. I stepped through some system calls, but I can't find any. Do a lot of Windows system calls run in user mode? Which DO run in supervisor mode?

+3  A: 

A system call is also known as a software interrupt. The x86 instruction which calls a software interrupt has the mnemonic INT. How data is passed to the operative system is defined by the operative system ABI. As far as I know, Windows uses the immediate 0x80 for all its routines and sends additional data via registers, but I'm not sure. 0x20 is the first available immediate, since the range 0 through 31 is reserved and used for general exceptions like integer division by zero and memory faults.

What basically happens is that the CPU changes to privileged mode and reads the IDTR (Interupt Descriptor Table Register). There it finds the physical memory address for the IDT (Interupt Descriptor Table) and does a lookup into the IDT, based on the 8-bit immediate baked into the software interrupt instruction. The IDT can be stored wherever in memory. The IDTR can be read/written by the instructions LIDT and SIDT. The IDT can store a variety of information, but for interrupts it stores the address to the service routine associated with the INT immediate.

Examples of win32-functions which fires a software interrupt.. hm. printf and friends sure does, as does EnterCriticalSection. In Windows Vista and Windows 7, some OpenGL and DirectX API calls now require a roundtrip into kernel land due to the new composite manager. For OpenGL, that applies for all functions who reads the current backbuffer, like glReadPixels, glCopy(Sub)TexImage2D, etc.

P.S: Take this post with a pinch of salt. It's been a while since I messed around with Windows this way, and I didn't perform a lot of fact checking. Edits and comments are welcome.

And here is a link to the original Intel 386 manual (which I quoted anyway)

Mads Elvheim
Ummm... the wave callbacks are 100% user mode code in Vista and above. There IS a kernel mode call made during the processing of the APIs, but that's just because there's an IPC call made from one user mode process to another and that involves system calls.
Larry Osterman
Fixed, thanks :-)I'm pretty sure this was the case in Windows 3.1 through Windows 98 though.
Mads Elvheim
So switches to supervisor mode are those INT3s I see scattered all around? Never seen one in executed code though.I'm on win64 (W7) right now, and I can't detect any jumps to supervisor mode in EnterCriticalSection. (http://slask.sys5.se/q/RtlEnterCriticalSection.png)Printf is not an api call, it's a C function.
Jens Björnhager
INT 3 is reserved to always mean a breakpoint. It is one of the interrupts with the highest priority. When you compile your applications with debugging information, INT 3 is filled between functions and data storage to perform a break inside the debugger instead of potentially doing nasty stuff with undefined memory regions.The standard C libraries surely fits the description of an API. Programmers just tend to think of APIs as "everything not covered by the language specification".
Mads Elvheim
Right, it seems like NT used INT2E for the supervisor switch. Guess the INT3s were just padding.I meant that it wasn't a winapi call.
Jens Björnhager
This isn't exactly accurate - ntdll uses sysenter, so a lot of the stuff you're describing is the old-school DOS/Win3.1 way of doing things.
Paul Betts
+2  A: 

x86 CPUs provide the SYSENTER and SYSEXIT instructions. These instructions execute a very fast switch from user mode to kernel mode and back, and modern OSes running on modern CPUs most likely use these instead of very costly interrupts or far calls.

You can see more details in Intel's Software Developer's Manuals, specifically volume 2B

Nathan Fellman
Also read the Windows Internals books. They are good for understanding.
ChristianWimmer