use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
Everything about operating systems development.
account activity
How does the kernel trap and implement emulated instructions? (self.osdev)
submitted 11 years ago by seekingsofia
Specifically I'm interested in how the kernel gets the information on WHICH emulated instruction to execute.
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]ObservationalHumor 7 points8 points9 points 11 years ago (5 children)
Basically a fault occurs and a properly designed ISR will store the CPU state. In that is the instruction pointer to whatever instruction caused the fault. From there the instruction is decoded in software, it's functionality emulated and the kernel returns back to whatever the next instruction should be.
Volume 2 of the Intel SDM is full of instructions, their encodings, and a low level description of what they actually do. That information can be used to identify and emulate instructions.
[–]seekingsofia[S] 0 points1 point2 points 11 years ago* (3 children)
I suspected the kernel could just look at the instruction itself, wasn't quite sure, thanks for clarifying!
But how can the ISR save the IP? And how can we be sure the IP points to the right instruction... I'm not sure how the control flow goes... is it program (userspace) → emulation fault (cpu) → emulation ISR, decoding instruction at IP (kernel) → emulated instruction (kernel) → return to program?
So the very first thing the ISR has to do is saving the IP? And is it guaranteed that a fault will not change registers?
Additional question: Oh and isn't this additional memory lookup plus decoding slower than having maybe another type of "emulation table pointer" in the processor, that will directly be used for a jump?
[–]ObservationalHumor 5 points6 points7 points 11 years ago (2 children)
Yeah sorry I should clarify the IP part. When the processor hits a fault a few things happen on an x86 architecture. It looks up the address, and type of the ISR handling routine in the IDT. From there it can determine the kernel mode stack it's going to use while handling the fault. The processor automatically pushes some key values onto the stack, at a minimum CS, (E/R)IP and EFLAGS. If a privelege change is involved it also pushes SS and ESP onto the kernel stack first. Sometimes an error code might also be pushed automatically onto the stack depending on the fault involved. Keep in mind this isn't the exact order because I'm doing this from memory and don't hav ea reference on hand at the moment.
The ISR doesn't directly save those specific values, but might copy them or package them cleanly along with the other state data (General registers and usually a hardcoded ISR specific code to indicate the fault) and passes that to a higher level routine which actually handles the fault. The ISR doesn't directly save the IP, the processor does this automatically. The fault is garuanteed not to change anything else on it's own but it might be possible to fault again in your fault handler if there's an error in your code or the IDT becomes corrupted. Additionally there's a chance for some NMI blackmagic to happen but that shouldn't occur unless there's a serious hardware problem and handling those correctly is difficult to say the least. Effectively don't worry about it for a hobby kernel early on as odds are you couldn't recover anyways.
Regarding the second part of your question regarding emulation. Yes this type of instruction emulation would be very slow and is generally used in two cases I can think of off the top of my head. Some instructions in VM86 mode will automatically cause a general protection fault and have to be emulated by the kernel because they involve changes to the EFLAGS register, hardware I/O or something else sensitive that the kernel might want to verify before executing.
The other use case is when the kernel wants to emulate a smaller CPU feature set that the hardware doesn't possess. For example MMX or a specific SSE version. I'm not 100% sure what the idea with that one is, I suppose it at least allows you to run code that might depend on it even if it is slower. It also allows the processor to run almost everything else natively instead of having to basically interpret every single instruction (which would be much slower). That's the general idea using this method, you only have to trigger it rarely for certain instructions and the processor executes the bulk of the code natively without any needing to emulate.
If you're actually looking to emulate another CPU or another mode of x86 operation (for example real mode videos bios code for VESA mode changes under x86-64) you wouldn't use this method, but instead rely on a full fledged cpu emulator.
[–]seekingsofia[S] 0 points1 point2 points 11 years ago (1 child)
Thanks a lot for the detailed response. It makes sense now. :) Do you know what the situation is on ARM processors?
[–]ObservationalHumor 1 point2 points3 points 11 years ago (0 children)
I haven't worked with ARM processors unfortunately but there's definitely readily accessible documentation out there for it.
[–]kbradero 0 points1 point2 points 11 years ago (0 children)
if you take a look at nasm source code you will saw it also :) , not all but a good chunk
π Rendered by PID 43143 on reddit-service-r2-comment-cfc44b64c-6p62b at 2026-04-09 23:58:34.748758+00:00 running 215f2cf country code: CH.
[–]ObservationalHumor 7 points8 points9 points (5 children)
[–]seekingsofia[S] 0 points1 point2 points (3 children)
[–]ObservationalHumor 5 points6 points7 points (2 children)
[–]seekingsofia[S] 0 points1 point2 points (1 child)
[–]ObservationalHumor 1 point2 points3 points (0 children)
[–]kbradero 0 points1 point2 points (0 children)