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:
VirtualBox_Clement_02_02_2017_12_55_49.png
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.