Transfer from: Http://scc.qibebt.cas.cn/docs/optimization/VTune (TM)%20user ' s%20guide/mergedprojects/analyzer_ec/ Mergedprojects/reference_olh/instruct32_hh/vc143.htm
http://szkn28szkn.iteye.com/blog/1362460 Description
Programs or procedures that return program control from exceptions or interrupt handlers to exceptions, external interrupts, or software-generated interrupts. These directives are also used to perform returns from nested tasks. (nested tasks are created when you start a task switch using the call command, or when a break, an exception causes the task to switch to an interrupt, or to an exception program). Refer to the section titled "Task Links" in chapter 1th, "IA-32 Intel (R) Architecture software Developer's Manual", volume 6th.
IRET and iretd are mnemonic characters of the same opcode. The iretd mnemonic (interrupt return double word) is used to return an interrupt that uses a 32-bit operand size, but most assemblers use the IRET mnemonic interchangeably for both operands.
In real address mode, the IRET instruction executes far back to the interrupt program or procedure. During this operation, the processor returns the instruction pointer, the return code snippet selector, and the eflags image to the EIP, CS, and EFlags registers, respectively, from the stack, and resumes the program or procedure that executed the interrupt.
In protected mode, the operation of the IRET directive depends on the settings of the NT (nested task) and VM flags in the EFlags register, and the settings of the VM flags in the eflags image stored in the current stack. Depending on the settings of these flags, the processor performs the following types of interrupt return:
Returns from virtual 8086 mode.
Returns to virtual 8086 mode.
Returned within the privileged level. Returns between privilege levels.
Returns from a nested task (task switch).
If the NT flag (eflags Register) is cleared, the IRET instruction executes far back from the interrupt process without performing a task switch. The privileged level of the returned code snippet must be less than or equal to the privileged level of the interrupt handling routine (as shown in the PRL field of the code snippet selector for the stack popup). For real address mode interrupt returns, the IRET instruction returns the instruction pointer, the return code snippet selector, and the eflags image to the EIP, CS, and EFlags registers, respectively, from the stack, and resumes the program or procedure that executed the interrupt. If you return to another privilege level, the IRET instruction also pops the stack pointer from the stack and the SS before the recovery program executes. If you return to virtual 8086 mode, the processor also pops the data segment register from the stack.
If you set the NT flag, the IRET directive performs a task switch (return) from a nested task (a task invoked with a call instruction, interrupt, or exception) to the task that is called or interrupted. The updated state of the task performing the IRET instruction is kept in its TSS. If you re-enter the task later, execute the code that follows the IRET instruction. Operation
IF PE 0 Then GOTO Real-address-mode:;
ELSE GOTO Protected-mode;
FI;
Real-address-mode; If operandsize and if top bytes of stack not within stacks limits then #SS;
FI; IF instruction pointer not within code segment limits then #GP (0);
FI;
EIP Pop (); CS Pop ();
(* 32-bit pop, high-order-bits discarded *) tempeflags pop ();
EFlags (Tempeflags and 257fd5h) or (EFlags and 1a0000h); ELSE (* operandsize *) IF Top 6 bytes of stack is not within stack limits then #SS;
FI; IF instruction pointer not within code segment limits then #GP (0);
FI;
EIP Pop ();
EIP Eip and 0000FFFFH; CS Pop ();
(* 16-bit pop *)
EFLAGS[15:0] Pop ();
FI;
END; Protected-mode:if VM 1 (* Virtual-8086 mode:pe=1, vm=1 *) then GOTO Return-from-virtual-8086-mode;
(* pe=1, Vm=1 *)
FI;
IF NT 1 then GOTO Task-return; (*pe=1, vm=0, nt=1 *) FI;
If operandsize=32 then IF top bytes of stacks not within stacks limits then #SS (0) FI;
Tempeip Pop ();
Tempcs Pop ();
Tempeflags Pop (); ELSE (* operandsize 16*) IF Top 6 bytes of stack is not within stack limits then #SS (0);
FI;
Tempeip Pop ();
Tempcs Pop ();
Tempeflags Pop ();
Tempeip Tempeip and FFFFH;
Tempeflags Tempeflags and FFFFH;
FI;
IF tempeflags (VM) 1 and cpl=0 then GOTO Return-to-virtual-8086-mode;
(* pe=1, vm=1 in eflags image *)
ELSE GOTO Protected-mode-return;
(* pe=1, vm=0 in eflags image *)
FI; Return-from-virtual-8086-mode: (* Processor is in virtual-8086 mode when IRET are executed and stays in virtual-8086 mode *) If iopl=3 (* Virtual mode:pe=1, vm=1, iopl=3 *) Then if operandsize and if top bytes of stack not within stack Limits then #SS (0);
FI; IF instruction pointer not within code segment limits then #GP (0);
FI;
EIP Pop (); CS Pop ();
(* 32-bit pop, high-order-bits discarded *)
EFlags Pop ();
(*vm,iopl,vip,and VIF eflags bits is not modified by pop *) ELSE (* operandsize *) IF Top 6 bytes of stack is not within stack limits then #SS (0);
FI; IF instruction pointer not within code segment limits Then #GP (0);
FI;
EIP Pop ();
EIP Eip and 0000FFFFH; CS Pop ();
(* 16-bit pop *) EFLAGS[15:0] Pop ();
(* IOPL in EFlags isn't modified by pop *)
FI; ELSE #GP (0);
(* trap to virtual-8086 monitor:pe=1, Vm=1, iopl<3 *)
FI;
END; Return-to-virtual-8086-mode: (* Interrupted procedure is in virtual-8086 mode:pe=1, vm=1 in Flags image *) IF top
TES of stack is not within stack segment limits then #SS (0);
FI;
IF instruction pointer not within code segment limits then #GP (0);
FI;
CS tempcs;
EIP Tempeip;
EFlags tempeflags Tempesp Pop ();
TEMPSS Pop (); ES Pop ();
(* Pop 2 words; throw away high-order word *) DS Pop ();
(* Pop 2 words; throw away high-order word *) FS Pop ();
(* Pop 2 words; throw away high-order word *) GS Pop ();
(* Pop 2 words; throw away high-order word *)
Ss:esp Tempss:tempesp;
(* Resume Execution in Virtual-8086 mode *)
END;
Task-return: (* pe=1, Vm=1, Nt=1 *) Read segment selector in link field of the current TSS; IF Local/global bit is set to local OR INDEx not within GDT limits then #GP (TSS selector);
FI;
Access TSS for task specified in link field of the current TSS;
If TSS descriptor type is no TSS or if the TSS is marked not busy then #GP (TSS selector);
FI;
IF TSS not present then #NP (TSS selector);
FI;
Switch-tasks (without nesting) to TSS specified in link field of the current TSS;
Mark the task just abandoned as not BUSY;
IF EIP is a within code segment limit then #GP (0);
FI;
END; Protected-mode-return: (* pe=1, vm=0 in Flags image *) IF RETURN code segment selector are null then GP (0);
FI; IF return code segment Selector addrsses descriptor beyond Descriptor table limit then GP (selector;
FI; Read segment descriptor pointed to by the return code segment selector IF return code segment descriptor was not a code SEG ment then #GP (selector);
FI; IF return code segment selector RPL < CPL then #GP (selector);
FI; IF return code segment descriptor is conforming and return code segment DPL > Return code segment selector RPL then #GP (selector);
FI; IF return code segment descriptor is not present then #NP (selector);
Fi:if return code segment selector RPL > CPL then GOTO return-outer-privilege-level;
ELSE GOTO Return-to-same-privilege-level FI;
END; Return-to-same-privilege-level: (* pe=1, vm=0 in Flags image, Rpl=cpl *) IF EIP isn't within code segment limits then #GP (0);
FI;
EIP Tempeip; CS tempcs;
(* Segment Descriptor information also loaded *)
EFlags (CF, PF, AF, ZF, SF, TF, DF, OF, NT) tempeflags;
IF operandsize=32 then EFlags (RF, AC, ID) tempeflags;
FI;
If CPL IOPL then EFlags (IF) tempeflags;
FI;
IF CPL 0 Then EFlags (IOPL) tempeflags;
IF operandsize=32 then EFlags (VM, VIF, VIP) tempeflags;
FI;
FI;
END; Return-to-outer-privilge-level:if Operandsize=32 then IF the top 8 bytes on stack is not within limits then #SS (0);
FI; ELSE (* operandsize=16 *) IF top 4 bytes on stack is not within limits then #SS (0);
FI;
FI;
Read return segment selector; IF Stack segment selector is null then #GP (0);
FI; IF return stack Segment selector index is not within it descriptor table limits then #GP (Ssselector);
FI;
Read segment descriptor pointed to by return segment selector; If stack segment selector RPL RPL of the return code segment selector IF stack segment selector RPL RPL of the return Co
De segment selector OR the stack segment descriptor does not indicate a writable data segment;
OR Stack segment DPL RPL of the return code segment selector then #GP (SS selector);
FI; IF stack segment is not present then #SS (SS selector);
FI; IF Tempeip is not within code segment limit then #GP (0);
FI;
EIP Tempeip;
CS tempcs;
EFlags (CF, PF, AF, ZF, SF, TF, DF, OF, NT) tempeflags;
IF operandsize=32 then EFlags (RF, AC, ID) tempeflags;
FI;
If CPL IOPL then EFlags (IF) tempeflags;
FI;
IF CPL 0 Then EFlags (IOPL) tempeflags;
IF operandsize=32 then EFlags (VM, VIF, VIP) tempeflags;
FI;
FI;
CPL RPL of the return code segment selector;
For each of the segment registers (ES, FS, GS, and DS) do; IF segment Register points to data or non-conforming code segment and CPL > Segment Descriptor DPL (* stored in hidden part of SE Gment Register *) Then (* Segment Register invalid *) Segmentselector 0;
(* NULL segment selector *)
FI;
OD; END:
Flag of Influence
Depending on the operating mode of the processor, all flags and fields in the EFlags register may be modified. If you perform a return from a nested task to the previous task, the EFlags register is modified based on the eflags image of the TSS store of the previous task. Protected Mode Exception
#GP (0)-If the return code or stack segment selector is empty. If the return instruction pointer exceeds the return code snippet limit.
#GP (selector)-if the segment selector index exceeds the descriptor table limit. If the return code snippet selector RPL is greater than CPL. If the DPL of the compatible code snippet is greater than the return code snippet selector, RPL. If the DPL of a non-conforming code segment is not equal to the RPL of the code snippet selector. If the DPL of the stack segment descriptor is not equal to the RPL of the return code snippet selector. If the stack segment is not a writable data segment. If the stack segment selector RPL is not equal to the RPL that returns the code snippet selector. If the segment descriptor of the snippet does not indicate that it is a code snippet. If the segment selector of the TSS sets its own local/global bit to local. If the TSS segment descriptor indicates that the TSS is busy or unavailable.
#SS (0)-If the stack top byte is out of stack limit.
#NP (selector)-If the return code or stack segment does not exist.
#PF (Error code)-If a page error occurs.
#AC (0)-If an unaligned memory reference occurs when the CPL is 3 and the alignment check is enabled. Real Address Pattern exception
#GP-If the return instruction pointer exceeds the return code snippet limit.
#SS-If the stack top byte of the heap exceeds the stack limit. virtual 8086 Pattern Exception
#GP (0)-If the return instruction pointer exceeds the return code snippet limit. If IOPL is not equal to 3.
#PF (Error code)-If a page error occurs.
#SS (0)-If the stack top byte is out of stack limit.
#AC (0)-If misaligned memory references are made when snapping checks are enabled.