Page 1 of 1
Confused about IRET statement
Posted: Thu Feb 02, 2017 11:43 am
by michaellangford
I am working on multithreading, and I am wondering what
exactly an IRET does.
While I know that it pops cs, eip, and eflags off the stack, the struct that I borrowed for my interrupt handler has 2 more value: ss and esp. Do these also get popped off during an IRET? and if they do, does the interrupt always push them?
Confused.
Here is my struct (I pass a pointer to it every interrupt):
Code: Select all
struct x86_registers
{
uint32_t gs, fs, es, ds;
uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax;
uint32_t int_no, err_code;
uint32_t eip, cs, eflags, useresp, ss;
};
However, I have some simple code running that (for now) dumps the registers of the interrupted process on every interrupt. while the 'esp' value seems to correspond to a sane esp, 'useresp' has all sorts of odd values, even settling in at zero sometimes. Also, I read that popa doesn't pop esp. therefore, is the esp pushed by pusha valid?
EDIT: Here is a screenshot of registers:
Thank you!
Re: Confused about IRET statement
Posted: Thu Feb 02, 2017 12:18 pm
by BrightLight
IRET does the opposite of INT. INT instruction does the following in this order:
- Push current SS on the stack.
- Push ESP before pushing SS on the stack.
- Push EFLAGS.
- Push current code segment.
- Push pointer to the next instruction after the INT.
- Load the new stack from the TSS.
- Load the CS:EIP combination from the IDT and execute the ISR.
After that, the ISR would return using IRET, which does the opposite:
- Pop CS:EIP from the stack, as pushed by INT.
- Pop EFLAGS from the stack.
- Pop SS from the stack.
- Set ESP to the value it should be from the stack.
- Continue execution from the instruction after the INT.
As you can see, the stack frame looks like this for an IRET (from highest address to lowest address): return EIP, return CS, return EFLAGS, return ESP, return SS. This is all explained in great detail in the Intel documentation.
Re: Confused about IRET statement
Posted: Thu Feb 02, 2017 12:37 pm
by MollenOS
Omarrx, please you are forgetting an important factor here in your explanation.
INT does only push SS and ESP if a privilege switch happens, and that means going from Ring3 => Ring0, otherwise the information is not pushed.
IRET works exactly the same way, it ONLY restores SS and ESP if a ring switch happens, and that means from Ring0 => Ring3
Re: Confused about IRET statement
Posted: Thu Feb 02, 2017 2:49 pm
by dozniak
michaellangford wrote:and I am wondering what exactly an IRET does.
Why? You did not read IRET description in the Intel docs?
Re: Confused about IRET statement
Posted: Fri Feb 03, 2017 1:47 am
by Boris
Step 1: Know your instruction length. If you asm code is -m32 , [BITS 32] or like, you are using iretd
Step 2: You know iret goal is to jump back to a context.
intel CPU contexts have privileges, and hardware tasks ( if you use them) and a virtual mode for old code
Step 3:
Go to an instruction doc like here
http://x86.renejeschke.de/html/file_mod ... d_145.html
I'd suggest Intel developer doc. But it's big. Be careful for bug fixes and errata you don't have on other sources.
Read the pseudo code in it.
Re: Confused about IRET statement
Posted: Fri Feb 03, 2017 6:09 am
by rdos
The processor checks if the RPL (bits 0 and 1) of the CS selector on the stack is higher than the RPL of the current selector, and if so, also pops the SS:ESP. In addition to that, it also checks the VM bit 17 of EFLAGS on stack, and if set, it also pops the other segment registers.