home *** CD-ROM | disk | FTP | other *** search
/ PC World 2001 December / PCWorld_2001-12_cd.bin / Software / Topware / Hackman / _SETUP.1 / ModuleI.dat < prev    next >
Text File  |  1998-09-15  |  53KB  |  986 lines

  1. <IDIV>
  2. [1]
  3. "IDIV: Signed Divide"
  4. ""
  5. "Divides (signed) the value in the AL, AX, or EAX register by the source operand and stores the result in the AX, DX:AX, or EDX:EAX registers. The source operand can be a general-purpose register or a memory location. The action of this instruction depends on the operand size, as shown in the following table:"
  6. ""
  7. "Operand Size     Dividend    Divisor   Quotient  Remainder   Quotient Range"
  8. "Word/byte           AX        r/m8        AL       AH         -128 to +127"
  9. "Doubleword/word     DX:AX     r/m16       AX       DX      -32,768 to +32,767"
  10. "Quadword/doubleword EDX:EAX   r/m32       EAX      EDX     -2^31 to 2^32 - 1"
  11. ""
  12. "Non-integral results are truncated (chopped) towards 0. The sign of the remainder is always the same as the sign of the dividend. The absolute value of the remainder is always less than the absolute value of the divisor. Overflow is indicated with the #DE (divide error) exception rather than with the OF (overflow) flag."
  13. [2]
  14. "IF SRC = 0"
  15. "THEN #DE; (* divide error *)"
  16. "FI;"
  17. "IF OpernadSize = 8 (* word/byte operation *)"
  18. "THEN"
  19. "temp ¼ AX / SRC; (* signed division *)"
  20. "IF (temp > 7FH) OR (temp < 80H)"
  21. "(* if a positive result is greater than 7FH or a negative result is less than 80H *)"
  22. "THEN #DE; (* divide error *) ;"
  23. "ELSE"
  24. "AL ¼ temp;"
  25. "AH ¼ AX SignedModulus SRC;"
  26. "FI;"
  27. "ELSE"
  28. "IF OperandSize = 16 (* doubleword/word operation *)"
  29. "THEN"
  30. "temp ¼ DX:AX / SRC; (* signed division *)"
  31. "IF (temp > 7FFFH) OR (temp < 8000H)"
  32. "(* if a positive result is greater than 7FFFH *)"
  33. "(* or a negative result is less than 8000H *)"
  34. "THEN #DE; (* divide error *) ;"
  35. "ELSE"
  36. "AX ¼ temp;"
  37. "DX ¼ DX:AX SignedModulus SRC;"
  38. "FI;"
  39. "ELSE (* quadword/doubleword operation *)"
  40. "temp ¼ EDX:EAX / SRC; (* signed division *)"
  41. "IF (temp > 7FFFFFFFH) OR (temp < 80000000H)"
  42. "(* if a positive result is greater than 7FFFFFFFH *)"
  43. "(* or a negative result is less than 80000000H *)"
  44. "THEN #DE; (* divide error *) ;"
  45. "ELSE"
  46. "EAX ¼ temp;"
  47. "EDX ¼ EDXE:AX SignedModulus SRC;"
  48. "FI;"
  49. "FI;"
  50. "FI;"
  51. [3]
  52. "The CF, OF, SF, ZF, AF, and PF flags are undefined."
  53. [4]
  54. "Protected Mode Exceptions"
  55. ""
  56. "#DE If the source operand (divisor) is 0. The signed result (quotient) is too large for the destination."
  57. "#GP(0) If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit. If the DS, ES, FS, or GS register is used to access memory and it contains a null segment selector."
  58. "#SS(0) If a memory operand effective address is outside the SS segment limit."
  59. "#PF(fault-code) If a page fault occurs."
  60. "#AC(0) If alignment checking is enabled and an unaligned memory reference is made while the current privilege level is 3."
  61. ""
  62. "Real-Address Mode Exceptions"
  63. ""
  64. "#DE If the source operand (divisor) is 0. The signed result (quotient) is too large for the destination."
  65. "#GP If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit."
  66. "#SS If a memory operand effective address is outside the SS segment limit."
  67. ""
  68. "Virtual-8086 Mode Exceptions"
  69. ""
  70. "#DE If the source operand (divisor) is 0. The signed result (quotient) is too large for the destination."
  71. "#GP(0) If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit."
  72. "#SS(0) If a memory operand effective address is outside the SS segment limit."
  73. "#PF(fault-code) If a page fault occurs."
  74. "#AC(0) If alignment checking is enabled and an unaligned memory reference is made."
  75. [5]
  76. "F6 /7 IDIV r/m8 Signed divide AX (where AH must contain sign-extension of AL) by r/m byte. (Results: AL=Quotient, AH=Remainder)"
  77. "F7 /7 IDIV r/m16 Signed divide DX:AX (where DX must contain sign-extension of AX) by r/m word. (Results: AX=Quotient, DX=Remainder)"
  78. "F7 /7 IDIV r/m32 Signed divide EDX:EAX (where EDX must contain sign-extension of EAX) by r/m doubleword. (Results: EAX=Quotient, EDX=Remainder)"
  79. [6]
  80. </IDIV>
  81. <IMUL>
  82. [1]
  83. "IMUL: Signed Multiply"
  84. ""
  85. "Performs a signed multiplication of two operands. This instruction has three forms, depending on the number of operands."
  86. ""
  87. "ò One-operand form. This form is identical to that used by the MUL instruction. Here, the source operand (in a general-purpose register or memory location) is multiplied by the value in the AL, AX, or EAX register (depending on the operand size) and the product is stored in the AX, DX:AX, or EDX:EAX registers, respectively."
  88. "ò Two-operand form. With this form the destination operand (the first operand) is multiplied by the source operand (second operand). The destination operand is a general-purpose register and the source operand is an immediate value, a general-purpose register, or a memory location. The product is then stored in the destination operand location."
  89. "ò Three-operand form. This form requires a destination operand (the first operand) and two source operands (the second and the third operands). Here, the first source operand (which can be a general-purpose register or a memory location) is multiplied by the second source operand (an immediate value). The product is then stored in the destination operand (a general-purpose register)."
  90. ""
  91. "When an immediate value is used as an operand, it is sign-extended to the length of the destination operand format. The CF and OF flags are set when significant bits are carried into the upper half of the result. The CF and OF flags are cleared when the result fits exactly in the lower half of the result."
  92. "The three forms of the IMUL instruction are similar in that the length of the product is calculated to twice the length of the operands. With the one-operand form, the product is stored exactly in the destination. With the two- and three- operand forms, however, result is truncated to the length of the destination before it is stored in the destination register. Because of this truncation, the CF or OF flag should be tested to ensure that no significant bits are lost."
  93. "The two- and three-operand forms may also be used with unsigned operands because the lower half of the product is the same regardless if the operands are signed or unsigned. The CF and OF flags, however, cannot be used to determine if the upper half of the result is non-zero."
  94. [2]
  95. "IF (NumberOfOperands = 1)"
  96. "THEN IF (OperandSize = 8)"
  97. "THEN"
  98. "AX ¼ AL * SRC (* signed multiplication *)"
  99. "IF ((AH = 00H) OR (AH = FFH))"
  100. "THEN CF = 0; OF = 0;"
  101. "ELSE CF = 1; OF = 1;"
  102. "FI;"
  103. "ELSE IF OperandSize = 16"
  104. "THEN"
  105. "DX:AX ¼ AX * SRC (* signed multiplication *)"
  106. "IF ((DX = 0000H) OR (DX = FFFFH))"
  107. "THEN CF = 0; OF = 0;"
  108. "ELSE CF = 1; OF = 1;"
  109. "FI;"
  110. "ELSE (* OperandSize = 32 *)"
  111. "EDX:EAX ¼ EAX * SRC (* signed multiplication *)"
  112. "IF ((EDX = 00000000H) OR (EDX = FFFFFFFFH))"
  113. "THEN CF = 0; OF = 0;"
  114. "ELSE CF = 1; OF = 1;"
  115. "FI;"
  116. "FI;"
  117. "ELSE IF (NumberOfOperands = 2)"
  118. "THEN"
  119. "temp ¼ DEST * SRC (* signed multiplication; temp is double DEST size*)"
  120. "DEST ¼ DEST * SRC (* signed multiplication *)"
  121. "IF temp ╣ DEST"
  122. "THEN CF = 1; OF = 1;"
  123. "ELSE CF = 0; OF = 0;"
  124. "FI;"
  125. "ELSE (* NumberOfOperands = 3 *)"
  126. "DEST ¼ SRC1 * SRC2 (* signed multiplication *)"
  127. "temp ¼ SRC1 * SRC2 (* signed multiplication; temp is double SRC1 size *)"
  128. "IF temp ╣ DEST"
  129. "THEN CF = 1; OF = 1;"
  130. "ELSE CF = 0; OF = 0;"
  131. "FI;"
  132. "FI;"
  133. "FI;"
  134. [3]
  135. "For the one operand form of the instruction, the CF and OF flags are set when significant bits are carried into the upper half of the result and cleared when the result fits exactly in the lower half of the result. For the two- and three-operand forms of the instruction, the CF and OF flags are set when the result must be truncated to fit in the destination operand size and cleared when the result fits exactly in the destination operand size. The SF, ZF, AF, and PF flags are undefined."
  136. [4]
  137. "Protected Mode Exceptions"
  138. ""
  139. "#GP(0) If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit. If the DS, ES, FS, or GS register is used to access memory and it contains a null segment selector."
  140. "#SS(0) If a memory operand effective address is outside the SS segment limit."
  141. "#PF(fault-code) If a page fault occurs."
  142. "#AC(0) If alignment checking is enabled and an unaligned memory reference is made while the current privilege level is 3."
  143. ""
  144. "Real-Address Mode Exceptions"
  145. ""
  146. "#GP If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit."
  147. "#SS If a memory operand effective address is outside the SS segment limit."
  148. ""
  149. "Virtual-8086 Mode Exceptions"
  150. ""
  151. "#GP(0) If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit."
  152. "#SS(0) If a memory operand effective address is outside the SS segment limit."
  153. "#PF(fault-code) If a page fault occurs."
  154. "#AC(0) If alignment checking is enabled and an unaligned memory reference is made."
  155. [5]
  156. "F6 /5 IMUL r/m8 AX¼ AL * r/m byte"
  157. "F7 /5 IMUL r/m16 DX:AX ¼ AX * r/m word"
  158. "F7 /5 IMUL r/m32 EDX:EAX ¼ EAX * r/m doubleword"
  159. "0F AF / r IMUL r16,r/m16 word register ¼ word register * r/m word"
  160. "0F AF / r IMUL r32,r/m32 doubleword register ¼ doubleword register * r/m doubleword"
  161. "6B / r ib IMUL r16,r/m16,imm8 word register ¼ r/m16 * sign-extended immediate byte"
  162. "6B / r ib IMUL r32,r/m32,imm8 doubleword register ¼ r/m32 * sign-extended immediate byte"
  163. "6B / r ib IMUL r16,imm8 word register ¼ word register * sign-extended immediate byte"
  164. "6B / r ib IMUL r32,imm8 doubleword register ¼ doubleword register * sign-extended immediate byte"
  165. "69 / r iw IMUL r16,r/m16,imm16 word register ¼ r/m16 * immediate word"
  166. "69 / r id IMUL r32,r/m32,imm32 doubleword register ¼ r/m32 * immediate doubleword"
  167. "69 / r iw IMUL r16,imm16 word register ¼ r/m16 * immediate word"
  168. "69 / r id IMUL r32,imm32 doubleword register ¼ r/m32 * immediate doubleword"
  169. [6]
  170. </IMUL>
  171. <IN>
  172. [1]
  173. "IN: Input from Port"
  174. ""
  175. "Copies the value from the I/O port specified with the second operand (source operand) to the destination operand (first operand). The source operand can be a byte-immediate or the DX register; the destination operand can be register AL, AX, or EAX, depending on the size of the port being accessed (8, 16, or 32 bits, respectively). Using the DX register as a source operand allows I/O port addresses from 0 to 65,535 to be accessed; using a byte immediate allows I/O port addresses 0 to 255 to be accessed."
  176. "When accessing an 8-bit I/O port, the opcode determines the port size; when accessing a 16- and 32-bit I/O port, the operand-size attribute determines the port size. At the machine code level, I/O instructions are shorter when accessing 8-bit I/O ports. Here, the upper eight bits of the port address will be 0. This instruction is only useful for accessing I/O ports located in the processorÆs I/O address space."
  177. [2]
  178. "IF ((PE = 1) AND ((CPL > IOPL) OR (VM = 1)))"
  179. "THEN (* Protected mode with CPL > IOPL or virtual-8086 mode *)"
  180. "IF (Any I/O Permission Bit for I/O port being accessed = 1)"
  181. "THEN (* I/O operation is not allowed *)"
  182. "#GP(0);"
  183. "ELSE ( * I/O operation is allowed *)"
  184. "DEST ¼ SRC; (* Reads from selected I/O port *)"
  185. "FI;"
  186. "ELSE (Real Mode or Protected Mode with CPL ú IOPL *)"
  187. "DEST ¼ SRC; (* Reads from selected I/O port *)"
  188. "FI;"
  189. [3]
  190. "None."
  191. [4]
  192. "Protected Mode Exceptions"
  193. ""
  194. "#GP(0) If the CPL is greater than (has less privilege) the I/O privilege level (IOPL) and any of the corresponding I/O permission bits in TSS for the I/O port being accessed is 1."
  195. ""
  196. "Real-Address Mode Exceptions"
  197. ""
  198. "None."
  199. ""
  200. "Virtual-8086 Mode Exceptions"
  201. ""
  202. "#GP(0) If any of the I/O permission bits in the TSS for the I/O port being accessed is 1."
  203. [5]
  204. "E4 ib IN AL, imm8 Input byte from imm8 I/O port address into AL"
  205. "E5 ib IN AX, imm8 Input byte from imm8 I/O port address into AX"
  206. "E5 ib IN EAX, imm8 Input byte from imm8 I/O port address into EAX"
  207. "EC IN AL,DX Input byte from I/O port in DX into AL"
  208. "ED IN AX,DX Input word from I/O port in DX into AX"
  209. "ED IN EAX,DX Input doubleword from I/O port in DX into EAX"
  210. [6]
  211. </IN>
  212. <INC>
  213. [1]
  214. "INC: Increment by 1"
  215. ""
  216. "Adds 1 to the destination operand, while preserving the state of the CF flag. The destination operand can be a register or a memory location. This instruction allows a loop counter to be updated without disturbing the CF flag. (Use a ADD instruction with an immediate operand of 1 to perform an increment operation that does updates the CF flag.)"
  217. [2]
  218. "DEST ¼ DEST +1;"
  219. [3]
  220. "The CF flag is not affected. The OF, SF, ZF, AF, and PF flags are set according to the result."
  221. [4]
  222. "Protected Mode Exceptions"
  223. ""
  224. "#GP(0) If the destination operand is located in a nonwritable segment. If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit. If the DS, ES, FS, or GS register is used to access memory and it contains a null segment selector."
  225. "#SS(0) If a memory operand effective address is outside the SS segment limit."
  226. "#PF(fault-code) If a page fault occurs."
  227. "#AC(0) If alignment checking is enabled and an unaligned memory reference is made while the current privilege level is 3."
  228. ""
  229. "Real-Address Mode Exceptions"
  230. ""
  231. "#GP If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit."
  232. "#SS If a memory operand effective address is outside the SS segment limit."
  233. ""
  234. "Virtual-8086 Mode Exceptions"
  235. ""
  236. "#GP(0) If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit."
  237. "#SS(0) If a memory operand effective address is outside the SS segment limit."
  238. "#PF(fault-code) If a page fault occurs."
  239. "#AC(0) If alignment checking is enabled and an unaligned memory reference is made."
  240. [5]
  241. "FE /0 INC r/m8 Increment r/m byte by 1"
  242. "FF /0 INC r/m16 Increment r/m word by 1"
  243. "FF /0 INC r/m32 Increment r/m doubleword by 1"
  244. "40+ rw INC r16 Increment word register by 1"
  245. "40+ rd INC r32 Increment doubleword register by 1"
  246. [6]
  247. </INC>
  248. <INS>
  249. <INSB>
  250. <INSD>
  251. <INSW>
  252. [1]
  253. "INS/INSB/INSW/INSD: Input from Port to String"
  254. ""
  255. "Copies the data from the I/O port specified with the source operand (second operand) to the destination operand (first operand). The source operand is an I/O port address (from 0 to 65,535) that is read from the DX register. The destination operand is a memory location, the address of which is read from either the ES:EDI or the ES:DI registers (depending on the address-size attribute of the instruction, 32 or 16, respectively). (The ES segment cannot be overridden with a segment override prefix.) The size of the I/O port being accessed (that is, the size of the source and destination operands) is determined by the opcode for an 8-bit I/O port or by the operand-size attribute of the instruction for a 16- or 32-bit I/O port."
  256. "At the assembly-code level, two forms of this instruction are allowed: the ôexplicit-operandsö form and the ôno-operandsö form. The explicit-operands form (specified with the INS mnemonic) allows the source and destination operands to be specified explicitly. Here, the source operand must be ôDX,ö and the destination operand should be a symbol that indicates the size of the I/O port and the destination address. This explicit-operands form is provided to allow documentation; however, note that the documentation provided by this form can be misleading. That is, the destination operand symbol must specify the correct type (size) of the operand (byte, word, or doubleword), but it does not have to specify the correct location. The location is always specified by the ES:(E)DI registers, which must be loaded correctly before the INS instruction is executed."
  257. "The no-operands form provides ôshort formsö of the byte, word, and doubleword versions of the INS instructions. Here also DX is assumed by the processor to be the source operand and ES:(E)DI is assumed to be the destination operand. The size of the I/O port is specified with the choice of mnemonic: INSB (byte), INSW (word), or INSD (doubleword)."
  258. "After the byte, word, or doubleword is transfer from the I/O port to the memory location, the (E)DI register is incremented or decremented automatically according to the setting of the DF flag in the EFLAGS register. (If the DF flag is 0, the (E)DI register is incremented; if the DF flag is 1, the (E)DI register is decremented.) The (E)DI register is incremented or decremented by 1 for byte operations, by 2 for word operations, or by 4 for doubleword operations."
  259. "The INS, INSB, INSW, and INSD instructions can be preceded by the REP prefix for block input of ECX bytes, words, or doublewords. See ôREP/REPE/REPZ/REPNE /REPNZùRepeat String Operation Prefixö in this chapter for a description of the REP prefix. These instructions are only useful for accessing I/O ports located in the processorÆs I/O address space."
  260. [2]
  261. "IF ((PE = 1) AND ((CPL > IOPL) OR (VM = 1)))"
  262. "THEN (* Protected mode with CPL > IOPL or virtual-8086 mode *)"
  263. "IF (Any I/O Permission Bit for I/O port being accessed = 1)"
  264. "THEN (* I/O operation is not allowed *)"
  265. "#GP(0);"
  266. "ELSE ( * I/O operation is allowed *)"
  267. "DEST ¼ SRC; (* Reads from I/O port *)"
  268. "FI;"
  269. "ELSE (Real Mode or Protected Mode with CPL ú IOPL *)"
  270. "DEST ¼ SRC; (* Reads from I/O port *)"
  271. "FI;"
  272. "IF (byte transfer)"
  273. "THEN IF DF = 0"
  274. "THEN (E)DI ¼ (E)DI + 1;"
  275. "ELSE (E)DI ¼ (E)DI û 1;"
  276. "FI;"
  277. "ELSE IF (word transfer)"
  278. "THEN IF DF = 0"
  279. "THEN (E)DI ¼ (E)DI + 2;"
  280. "ELSE (E)DI ¼ (E)DI û 2;"
  281. "FI;"
  282. "ELSE (* doubleword transfer *)"
  283. "THEN IF DF = 0"
  284. "THEN (E)DI ¼ (E)DI + 4;"
  285. "ELSE (E)DI ¼ (E)DI û 4;"
  286. "FI;"
  287. "FI;"
  288. "FI;"
  289. [3]
  290. "None."
  291. [4]
  292. "Protected Mode Exceptions"
  293. ""
  294. "#GP(0) If the CPL is greater than (has less privilege) the I/O privilege level (IOPL) and any of the corresponding I/O permission bits in TSS for the I/O port being accessed is 1. If the destination is located in a nonwritable segment. If an illegal memory operand effective address in the ES segments is given."
  295. "#PF(fault-code) If a page fault occurs."
  296. "#AC(0) If alignment checking is enabled and an unaligned memory reference is made while the current privilege level is 3."
  297. ""
  298. "Real-Address Mode Exceptions"
  299. ""
  300. "#GP If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit."
  301. "#SS If a memory operand effective address is outside the SS segment limit."
  302. ""
  303. "Virtual-8086 Mode Exceptions"
  304. ""
  305. "#GP(0) If any of the I/O permission bits in the TSS for the I/O port being accessed is 1."
  306. "#PF(fault-code) If a page fault occurs."
  307. "#AC(0) If alignment checking is enabled and an unaligned memory reference is made."
  308. [5]
  309. "6C INS m8, DX Input byte from I/O port specified in DX into memory location specified in ES:(E)DI"
  310. "6D INS m16, DX Input word from I/O port specified in DX into memory location specified in ES:(E)DI"
  311. "6D INS m32, DX Input doubleword from I/O port specified in DX into memory location specified in ES:(E)DI"
  312. "6C INSB Input byte from I/O port specified in DX into memory location specified with ES:(E)DI"
  313. "6D INSW Input word from I/O port specified in DX into memory location specified in ES:(E)DI"
  314. "6D INSD Input doubleword from I/O port specified in DX into memory location specified in ES:(E)DI"
  315. [6]
  316. </INS>
  317. </INSB>
  318. </INSD>
  319. </INSW>
  320. <INT>
  321. <INTO>
  322. <INT 3>
  323. [1]
  324. "INT n/INTO/INT 3: Call to Interrupt Procedure"
  325. ""
  326. "The INT n instruction generates a call to the interrupt or exception handler specified with the destination operand. The destination operand specifies an interrupt vector number from 0 to 255, encoded as an 8-bit unsigned intermediate value. Each interrupt vector number provides an index to a gate descriptor in the IDT. The first 32 interrupt vector numbers are reserved by Intel for system use. Some of these interrupts are used for internally generated exceptions."
  327. "The INT n instruction is the general mnemonic for executing a software-generated call to an interrupt handler. The INTO instruction is a special mnemonic for calling overflow exception (#OF), interrupt vector number 4. The overflow interrupt checks the OF flag in the EFLAGS register and calls the overflow interrupt handler if the OF flag is set to 1."
  328. "The INT 3 instruction generates a special one byte opcode (CC) that is intended for calling the debug exception handler. (This one byte form is valuable because it can be used to replace the first byte of any instruction with a breakpoint, including other one byte instructions, without over-writing other code). To further support its function as a debug breakpoint, the interrupt generated with the CC opcode also differs from the regular software interrupts as follows:"
  329. ""
  330. "ò Interrupt redirection does not happen when in VME mode; the interrupt is handled by a protected-mode handler."
  331. "ò The virtual-8086 mode IOPL checks do not occur. The interrupt is taken without faulting at any IOPL level."
  332. ""
  333. "Note that the ônormalö 2-byte opcode for INT 3 (CD03) does not have these special features. Intel and Microsoft assemblers will not generate the CD03 opcode from any mnemonic, but this opcode can be created by direct numeric code definition or by self-modifying code."
  334. "The action of the INT n instruction (including the INTO and INT 3 instructions) is similar to that of a far call made with the CALL instruction. The primary difference is that with the INT n instruction, the EFLAGS register is pushed onto the stack before the return address. (The return address is a far address consisting of the current values of the CS and EIP registers.) Returns from interrupt procedures are handled with the IRET instruction, which pops the EFLAGS information and return address from the stack."
  335. "The interrupt vector number specifies an interrupt descriptor in the interrupt descriptor table (IDT); that is, it provides index into the IDT. The selected interrupt descriptor in turn contains a pointer to an interrupt or exception handler procedure. In protected mode, the IDT contains an array of 8-byte descriptors, each of which is an interrupt gate, trap gate, or task gate. In real-address mode, the IDT is an array of 4-byte far pointers (2-byte code segment selector and a 2-byte instruction pointer), each of which point directly to a procedure in the selected segment. (Note that in real-address mode, the IDT is called the interrupt vector table, and itÆs pointers are called interrupt vectors.)"
  336. "When the processor is executing in virtual-8086 mode, the IOPL determines the action of the INT n instruction. If the IOPL is less than 3, the processor generates a general protection exception (#GP); if the IOPL is 3, the processor executes a protected mode interrupt to privilege level 0. The interrupt gate's DPL must be set to three and the target CPL of the interrupt handler procedure must be 0 to execute the protected mode interrupt to privilege level 0. The interrupt descriptor table register (IDTR) specifies the base linear address and limit of the IDT. The initial base address value of the IDTR after the processor is powered up or reset is 0."
  337. [2]
  338. "The following operational description applies not only to the INT n and INTO instructions, but also to external interrupts and exceptions."
  339. ""
  340. "IF PE=0"
  341. "THEN"
  342. "GOTO REAL-ADDRESS-MODE;"
  343. "ELSE (* PE=1 *)"
  344. "IF (VM=1 AND IOPL < 3 AND INT n)"
  345. "THEN"
  346. "#GP(0);"
  347. "ELSE (* protected mode or virtual-8086 mode interrupt *)"
  348. "GOTO PROTECTED-MODE;"
  349. "FI;"
  350. "FI;"
  351. ""
  352. "REAL-ADDRESS-MODE:"
  353. "IF ((DEST * 4) + 3) is not within IDT limit THEN #GP; FI;"
  354. "IF stack not large enough for a 6-byte return information THEN #SS; FI;"
  355. "Push (EFLAGS[15:0]);"
  356. "IF ¼ 0; (* Clear interrupt flag *)"
  357. "TF ¼ 0; (* Clear trap flag *)"
  358. "AC ¼ 0; (*Clear AC flag*)"
  359. "Push(CS);"
  360. "Push(IP);"
  361. "(* No error codes are pushed *)"
  362. "CS ¼ IDT(Descriptor (vector_number * 4), selector));"
  363. "EIP ¼ IDT(Descriptor (vector_number * 4), offset)); (* 16 bit offset AND 0000FFFFH *)"
  364. "END;"
  365. ""
  366. "PROTECTED-MODE:"
  367. "IF ((DEST * 8) + 7) is not within IDT limits"
  368. "OR selected IDT descriptor is not an interrupt-, trap-, or task-gate type"
  369. "THEN #GP((DEST * 8) + 2 + EXT);"
  370. "(* EXT is bit 0 in error code *)"
  371. "FI;"
  372. "IF software interrupt (* generated by INT n, INT 3, or INTO *)"
  373. "THEN"
  374. "IF gate descriptor DPL < CPL"
  375. "THEN #GP((vector_number * 8) + 2 );"
  376. "(* PE=1, DPL<CPL, software interrupt *)"
  377. "FI;"
  378. "FI;"
  379. "IF gate not present THEN #NP((vector_number * 8) + 2 + EXT); FI;"
  380. "IF task gate (* specified in the selected interrupt table descriptor *)"
  381. "THEN GOTO TASK-GATE;"
  382. "ELSE GOTO TRAP-OR-INTERRUPT-GATE; (* PE=1, trap/interrupt gate *)"
  383. "FI;"
  384. "END;"
  385. ""
  386. "TASK-GATE: (* PE=1, task gate *)"
  387. "Read segment selector in task gate (IDT descriptor);"
  388. "IF local/global bit is set to local"
  389. "OR index not within GDT limits"
  390. "THEN #GP(TSS selector);"
  391. "FI;"
  392. "Access TSS descriptor in GDT;"
  393. "IF TSS descriptor specifies that the TSS is busy (low-order 5 bits set to 00001)"
  394. "THEN #GP(TSS selector);"
  395. "FI;"
  396. "IF TSS not present"
  397. "THEN #NP(TSS selector);"
  398. "FI;"
  399. "SWITCH-TASKS (with nesting) to TSS;"
  400. "IF interrupt caused by fault with error code"
  401. "THEN"
  402. "IF stack limit does not allow push of error code"
  403. "THEN #SS(0);"
  404. "FI;"
  405. "Push(error code);"
  406. "FI;"
  407. "IF EIP not within code segment limit"
  408. "THEN #GP(0);"
  409. "FI;"
  410. "END;"
  411. ""
  412. "TRAP-OR-INTERRUPT-GATE"
  413. "Read segment selector for trap or interrupt gate (IDT descriptor);"
  414. "IF segment selector for code segment is null"
  415. "THEN #GP(0H + EXT); (* null selector with EXT flag set *)"
  416. "FI;"
  417. "IF segment selector is not within its descriptor table limits"
  418. "THEN #GP(selector + EXT);"
  419. "FI;"
  420. "Read trap or interrupt handler descriptor;"
  421. "IF descriptor does not indicate a code segment"
  422. "OR code segment descriptor DPL > CPL"
  423. "THEN #GP(selector + EXT);"
  424. "FI;"
  425. "IF trap or interrupt gate segment is not present,"
  426. "THEN #NP(selector + EXT);"
  427. "FI;"
  428. "IF code segment is non-conforming AND DPL < CPL"
  429. "THEN IF VM=0"
  430. "THEN"
  431. "GOTO INTER-PRIVILEGE-LEVEL-INTERRUPT;"
  432. "(* PE=1, interrupt or trap gate, nonconforming *)"
  433. "(* code segment, DPL<CPL, VM=0 *)"
  434. "ELSE (* VM=1 *)"
  435. "IF code segment DPL ╣ 0 THEN #GP(new code segment selector); FI;"
  436. "GOTO INTERRUPT-FROM-VIRTUAL-8086-MODE;"
  437. "(* PE=1, interrupt or trap gate, DPL<CPL, VM=1 *)"
  438. "FI;"
  439. "ELSE (* PE=1, interrupt or trap gate, DPL │ CPL *)"
  440. "IF VM=1 THEN #GP(new code segment selector); FI;"
  441. "IF code segment is conforming OR code segment DPL = CPL"
  442. "THEN"
  443. "GOTO INTRA-PRIVILEGE-LEVEL-INTERRUPT;"
  444. "ELSE"
  445. "#GP(CodeSegmentSelector + EXT);"
  446. "(* PE=1, interrupt or trap gate, nonconforming *)"
  447. "(* code segment, DPL>CPL *)"
  448. "FI;"
  449. "FI;"
  450. "END;"
  451. ""
  452. "INTER-PREVILEGE-LEVEL-INTERRUPT"
  453. "(* PE=1, interrupt or trap gate, non-conforming code segment, DPL<CPL *)"
  454. "(* Check segment selector and descriptor for stack of new privilege level in current TSS *)"
  455. "IF current TSS is 32-bit TSS"
  456. "THEN"
  457. "TSSstackAddress ¼ (new code segment DPL * 8) + 4"
  458. "IF (TSSstackAddress + 7) > TSS limit"
  459. "THEN #TS(current TSS selector); FI;"
  460. "NewSS ¼ TSSstackAddress + 4;"
  461. "NewESP ¼ stack address;"
  462. "ELSE (* TSS is 16-bit *)"
  463. "TSSstackAddress ¼ (new code segment DPL * 4) + 2"
  464. "IF (TSSstackAddress + 4) > TSS limit"
  465. "THEN #TS(current TSS selector); FI;"
  466. "NewESP ¼ TSSstackAddress;"
  467. "NewSS ¼ TSSstackAddress + 2;"
  468. "FI;"
  469. "IF segment selector is null THEN #TS(EXT); FI;"
  470. "IF segment selector index is not within its descriptor table limits"
  471. "OR segment selector's RPL ╣ DPL of code segment,"
  472. "THEN #TS(SS selector + EXT);"
  473. "FI;"
  474. "Read segment descriptor for stack segment in GDT or LDT;"
  475. "IF stack segment DPL ╣ DPL of code segment,"
  476. "OR stack segment does not indicate writable data segment,"
  477. "THEN #TS(SS selector + EXT);"
  478. "FI;"
  479. "IF stack segment not present THEN #SS(SS selector+EXT); FI;"
  480. "IF 32-bit gate"
  481. "THEN"
  482. "IF new stack does not have room for 24 bytes (error code pushed)"
  483. "OR 20 bytes (no error code pushed)"
  484. "THEN #SS(segment selector + EXT);"
  485. "FI;"
  486. "ELSE (* 16-bit gate *)"
  487. "IF new stack does not have room for 12 bytes (error code pushed)"
  488. "OR 10 bytes (no error code pushed);"
  489. "THEN #SS(segment selector + EXT);"
  490. "FI;"
  491. "FI;"
  492. "IF instruction pointer is not within code segment limits THEN #GP(0); FI;"
  493. "SS:ESP ¼ TSS(NewSS:NewESP) (* segment descriptor information also loaded *)"
  494. "IF 32-bit gate"
  495. "THEN"
  496. "CS:EIP ¼ Gate(CS:EIP); (* segment descriptor information also loaded *)"
  497. "ELSE (* 16-bit gate *)"
  498. "CS:IP ¼ Gate(CS:IP); (* segment descriptor information also loaded *)"
  499. "FI;"
  500. "IF 32-bit gate"
  501. "THEN"
  502. "Push(far pointer to old stack); (* old SS and ESP, 3 words padded to 4 *);"
  503. "Push(EFLAGS);"
  504. "Push(far pointer to return instruction); (* old CS and EIP, 3 words padded to 4*);"
  505. "Push(ErrorCode); (* if needed, 4 bytes *)"
  506. "ELSE(* 16-bit gate *)"
  507. "Push(far pointer to old stack); (* old SS and SP, 2 words *);"
  508. "Push(EFLAGS(15..0));"
  509. "Push(far pointer to return instruction); (* old CS and IP, 2 words *);"
  510. "Push(ErrorCode); (* if needed, 2 bytes *)"
  511. "FI;"
  512. "CPL ¼ CodeSegmentDescriptor(DPL);"
  513. "CS(RPL) ¼ CPL;"
  514. "IF interrupt gate"
  515. "THEN IF ¼ 0 (* interrupt flag to 0 (disabled) *); FI;"
  516. "TF ¼ 0;"
  517. "VM ¼ 0;"
  518. "RF ¼ 0;"
  519. "NT ¼ 0;"
  520. "END;"
  521. ""
  522. "INTERRUPT-FROM-VIRTUAL-8086-MODE:"
  523. "(* Check segment selector and descriptor for privilege level 0 stack in current TSS *)"
  524. "IF current TSS is 32-bit TSS"
  525. "THEN"
  526. "TSSstackAddress ¼ (new code segment DPL * 8) + 4"
  527. "IF (TSSstackAddress + 7) > TSS limit"
  528. "THEN #TS(current TSS selector); FI;"
  529. "NewSS ¼ TSSstackAddress + 4;"
  530. "NewESP ¼ stack address;"
  531. "ELSE (* TSS is 16-bit *)"
  532. "TSSstackAddress ¼ (new code segment DPL * 4) + 2"
  533. "IF (TSSstackAddress + 4) > TSS limit"
  534. "THEN #TS(current TSS selector); FI;"
  535. "NewESP ¼ TSSstackAddress;"
  536. "NewSS ¼ TSSstackAddress + 2;"
  537. "FI;"
  538. "IF segment selector is null THEN #TS(EXT); FI;"
  539. "IF segment selector index is not within its descriptor table limits"
  540. "OR segment selector's RPL ╣ DPL of code segment,"
  541. "THEN #TS(SS selector + EXT);"
  542. "FI;"
  543. "Access segment descriptor for stack segment in GDT or LDT;"
  544. "IF stack segment DPL ╣ DPL of code segment,"
  545. "OR stack segment does not indicate writable data segment,"
  546. "THEN #TS(SS selector + EXT);"
  547. "FI;"
  548. "IF stack segment not present THEN #SS(SS selector+EXT); FI;"
  549. "IF 32-bit gate"
  550. "THEN"
  551. "IF new stack does not have room for 40 bytes (error code pushed)"
  552. "OR 36 bytes (no error code pushed);"
  553. "THEN #SS(segment selector + EXT);"
  554. "FI;"
  555. "ELSE (* 16-bit gate *)"
  556. "IF new stack does not have room for 20 bytes (error code pushed)"
  557. "OR 18 bytes (no error code pushed);"
  558. "THEN #SS(segment selector + EXT);"
  559. "FI;"
  560. "FI;"
  561. "IF instruction pointer is not within code segment limits THEN #GP(0); FI;"
  562. "tempEFLAGS ¼ EFLAGS;"
  563. "VM ¼ 0;"
  564. "TF ¼ 0;"
  565. "RF ¼ 0;"
  566. "IF service through interrupt gate THEN IF ¼ 0; FI;"
  567. "TempSS ¼ SS;"
  568. "TempESP ¼ ESP;"
  569. "SS:ESP ¼ TSS(SS0:ESP0); (* Change to level 0 stack segment *)"
  570. "(* Following pushes are 16 bits for 16-bit gate and 32 bits for 32-bit gates *)"
  571. "(* Segment selector pushes in 32-bit mode are padded to two words *)"
  572. "Push(GS);"
  573. "Push(FS);"
  574. "Push(DS);"
  575. "Push(ES);"
  576. "Push(TempSS);"
  577. "Push(TempESP);"
  578. "Push(TempEFlags);"
  579. "Push(CS);"
  580. "Push(EIP);"
  581. "GS ¼ 0; (*segment registers nullified, invalid in protected mode *)"
  582. "FS ¼ 0;"
  583. "DS ¼ 0;"
  584. "ES ¼ 0;"
  585. "CS ¼ Gate(CS);"
  586. "IF OperandSize=32"
  587. "THEN"
  588. "EIP ¼ Gate(instruction pointer);"
  589. "ELSE (* OperandSize is 16 *)"
  590. "EIP ¼ Gate(instruction pointer) AND 0000FFFFH;"
  591. "FI;"
  592. "(* Starts execution of new routine in Protected Mode *)"
  593. "END;"
  594. ""
  595. "INTRA-PRIVILEGE-LEVEL-INTERRUPT:"
  596. "(* PE=1, DPL = CPL or conforming segment *)"
  597. "IF 32-bit gate"
  598. "THEN"
  599. "IF current stack does not have room for 16 bytes (error code pushed)"
  600. "OR 12 bytes (no error code pushed); THEN #SS(0);"
  601. "FI;"
  602. "ELSE (* 16-bit gate *)"
  603. "IF current stack does not have room for 8 bytes (error code pushed)"
  604. "OR 6 bytes (no error code pushed); THEN #SS(0);"
  605. "FI;"
  606. "IF instruction pointer not within code segment limit THEN #GP(0); FI;"
  607. "IF 32-bit gate"
  608. "THEN"
  609. "Push (EFLAGS);"
  610. "Push (far pointer to return instruction); (* 3 words padded to 4 *)"
  611. "CS:EIP ¼ Gate(CS:EIP); (* segment descriptor information also loaded *)"
  612. "Push (ErrorCode); (* if any *)"
  613. "ELSE (* 16-bit gate *)"
  614. "Push (FLAGS);"
  615. "Push (far pointer to return location); (* 2 words *)"
  616. "CS:IP ¼ Gate(CS:IP); (* segment descriptor information also loaded *)"
  617. "Push (ErrorCode); (* if any *)"
  618. "FI;"
  619. "CS(RPL) ¼ CPL;"
  620. "IF interrupt gate"
  621. "THEN"
  622. "IF ¼ 0; FI;"
  623. "TF ¼ 0;"
  624. "NT ¼ 0;"
  625. "VM ¼ 0;"
  626. "RF ¼ 0;"
  627. "FI;"
  628. "END;"
  629. [3]
  630. "The EFLAGS register is pushed onto the stack. The IF, TF, NT, AC, RF, and VM flags may be cleared, depending on the mode of operation of the processor when the INT instruction is executed (see the ôOperationö section). If the interrupt uses a task gate, any flags may be set or cleared, controlled by the EFLAGS image in the new taskÆs TSS."
  631. [4]
  632. "Protected Mode Exceptions"
  633. ""
  634. "#GP(0) If the instruction pointer in the IDT or in the interrupt-, trap-, or task gate is beyond the code segment limits."
  635. "#GP(selector) If the segment selector in the interrupt-, trap-, or task gate is null. If a interrupt-, trap-, or task gate, code segment, or TSS segment selector index is outside its descriptor table limits. If the interrupt vector number is outside the IDT limits. If an IDT descriptor is not an interrupt-, trap-, or task-descriptor. If an interrupt is generated by the INT n, INT 3, or INTO instruction and the DPL of an interrupt-, trap-, or task-descriptor is less than the CPL. If the segment selector in an interrupt- or trap-gate does not point to a segment descriptor for a code segment. If the segment selector for a TSS has its local/global bit set for local. If a TSS segment descriptor specifies that the TSS is busy or not available."
  636. "#SS(0) If pushing the return address, flags, or error code onto the stack exceeds the bounds of the stack segment and no stack switch occurs."
  637. "#SS(selector) If the SS register is being loaded and the segment pointed to is marked not present. If pushing the return address, flags, error code, or stack segment pointer exceeds the bounds of the new stack segment when a stack switch occurs."
  638. "#NP(selector) If code segment, interrupt-, trap-, or task gate, or TSS is not present."
  639. "#TS(selector) If the RPL of the stack segment selector in the TSS is not equal to the DPL of the code segment being accessed by the interrupt or trap gate. If DPL of the stack segment descriptor pointed to by the stack segment selector in the TSS is not equal to the DPL of the code segment descriptor for the interrupt or trap gate. If the stack segment selector in the TSS is null. If the stack segment for the TSS is not a writable data segment. If segment-selector index for stack segment is outside descriptor table limits."
  640. "#PF(fault-code) If a page fault occurs."
  641. ""
  642. "Real-Address Mode Exceptions"
  643. ""
  644. "#GP If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit. If the interrupt vector number is outside the IDT limits."
  645. "#SS If stack limit violation on push. If pushing the return address, flags, or error code onto the stack exceeds the bounds of the stack segment."
  646. ""
  647. "Virtual-8086 Mode Exceptions"
  648. ""
  649. "#GP(0) (For INT n, INTO, or BOUND instruction) If the IOPL is less than 3 or the DPL of the interrupt-, trap-, or task-gate descriptor is not equal to 3. If the instruction pointer in the IDT or in the interrupt-, trap-, or task gate is beyond the code segment limits."
  650. "#GP(selector) If the segment selector in the interrupt-, trap-, or task gate is null. If a interrupt-, trap-, or task gate, code segment, or TSS segment selector index is outside its descriptor table limits. If the interrupt vector number is outside the IDT limits. If an IDT descriptor is not an interrupt-, trap-, or task-descriptor. If an interrupt is generated by the INT n instruction and the DPL of an interrupt-, trap-, or task-descriptor is less than the CPL. If the segment selector in an interrupt- or trap-gate does not point to a segment descriptor for a code segment. If the segment selector for a TSS has its local/global bit set for local."
  651. "#SS(selector) If the SS register is being loaded and the segment pointed to is marked not present. If pushing the return address, flags, error code, stack segment pointer, or data segments exceeds the bounds of the stack segment."
  652. "#NP(selector) If code segment, interrupt-, trap-, or task gate, or TSS is not present."
  653. "#TS(selector) If the RPL of the stack segment selector in the TSS is not equal to the DPL of the code segment being accessed by the interrupt or trap gate. If DPL of the stack segment descriptor for the TSSÆs stack segment is not equal to the DPL of the code segment descriptor for the interrupt or trap gate. If the stack segment selector in the TSS is null. If the stack segment for the TSS is not a writable data segment. If segment-selector index for stack segment is outside descriptor table limits."
  654. "#PF(fault-code) If a page fault occurs."
  655. "#BP If the INT 3 instruction is executed."
  656. "#OF If the INTO instruction is executed and the OF flag is set."
  657. [5]
  658. "CC INT 3 Interrupt 3ùtrap to debugger"
  659. "CD ib INT imm8 Interrupt vector number specified by immediate byte"
  660. "CE INTO Interrupt 4ùif overflow flag is 1"
  661. [6]
  662. </INT>
  663. </INTO>
  664. </INT 3>
  665. <INVD>
  666. [1]
  667. "INVD: Invalidate Internal Caches"
  668. ""
  669. "Invalidates (flushes) the processorÆs internal caches and issues a special-function bus cycle that directs external caches to also flush themselves. Data held in internal caches is not written back to main memory. After executing this instruction, the processor does not wait for the external caches to complete their flushing operation before proceeding with instruction execution. It is the responsibility of hardware to respond to the cache flush signal. The INVD instruction is a privileged instruction. When the processor is running in protected mode, the CPL of a program or procedure must be 0 to execute this instruction."
  670. "Use this instruction with care. Data cached internally and not written back to main memory will be lost. Unless there is a specific requirement or benefit to flushing caches without writing back modified cache lines (for example, testing or fault recovery where cache coherency with main memory is not a concern), software should use the WBINVD instruction."
  671. ""
  672. "Intel Architecture Compatibility"
  673. ""
  674. "The INVD instruction is implementation dependent, and its function may be implemented differently on future Intel Architecture processors. This instruction is not supported on Intel Architecture processors earlier than the Intel486 processor."
  675. [2]
  676. "Flush(InternalCaches);"
  677. "SignalFlush(ExternalCaches);"
  678. "Continue (* Continue execution);"
  679. [3]
  680. "None."
  681. [4]
  682. "Protected Mode Exceptions"
  683. ""
  684. "#GP(0) If the current privilege level is not 0."
  685. ""
  686. "Real-Address Mode Exceptions"
  687. ""
  688. "None."
  689. ""
  690. "Virtual-8086 Mode Exceptions"
  691. ""
  692. "#GP(0) The INVD instruction cannot be executed in virtual-8086 mode."
  693. [5]
  694. "0F 08 INVD Flush internal caches; initiate flushing of external caches."
  695. [6]
  696. </INVD>
  697. <INVLPG>
  698. [1]
  699. "INVLPG: Invalidate TLB Entry"
  700. ""
  701. "Invalidates (flushes) the translation lookaside buffer (TLB) entry specified with the source operand. The source operand is a memory address. The processor determines the page that contains that address and flushes the TLB entry for that page. The INVLPG instruction is a privileged instruction. When the processor is running in protected mode, the CPL of a program or procedure must be 0 to execute this instruction. The INVLPG instruction normally flushes the TLB entry only for the specified page; however, in some cases, it flushes the entire TLB."
  702. ""
  703. "Intel Architecture Compatibility"
  704. ""
  705. "The INVLPG instruction is implementation dependent, and its function may be implemented differently on future Intel Architecture processors. This instruction is not supported on Intel Architecture processors earlier than the Intel486 processor."
  706. [2]
  707. "Flush(RelevantTLBEntries);"
  708. "Continue (* Continue execution);"
  709. [3]
  710. "None."
  711. [4]
  712. "Protected Mode Exceptions"
  713. ""
  714. "#GP(0) If the current privilege level is not 0."
  715. "#UD Operand is a register."
  716. ""
  717. "Real-Address Mode Exceptions"
  718. ""
  719. "#UD Operand is a register."
  720. ""
  721. "Virtual-8086 Mode Exceptions"
  722. ""
  723. "#GP(0) The INVLPG instruction cannot be executed at the virtual-8086 mode."
  724. [5]
  725. "0F 01/7 INVLPG m Invalidate TLB Entry for page that contains m"
  726. [6]
  727. </INVLPG>
  728. <IRET>
  729. <IRETD>
  730. [1]
  731. "IRET/IRETD: Interrupt Return"
  732. ""
  733. "Returns program control from an exception or interrupt handler to a program or procedure that was interrupted by an exception, an external interrupt, or a software-generated interrupt. These instructions are also used to perform a return from a nested task. (A nested task is created when a CALL instruction is used to initiate a task switch or when an interrupt or exception causes a task switch to an interrupt or exception handler.)"
  734. "IRET and IRETD are mnemonics for the same opcode. The IRETD mnemonic (interrupt return double) is intended for use when returning from an interrupt when using the 32-bit operand size; however, most assemblers use the IRET mnemonic interchangeably for both operand sizes. In Real-Address Mode, the IRET instruction preforms a far return to the interrupted program or procedure. During this operation, the processor pops the return instruction pointer, return code segment selector, and EFLAGS image from the stack to the EIP, CS, and EFLAGS registers, respectively, and then resumes execution of the interrupted program or procedure."
  735. "In Protected Mode, the action of the IRET instruction depends on the settings of the NT (nested task) and VM flags in the EFLAGS register and the VM flag in the EFLAGS image stored on the current stack. Depending on the setting of these flags, the processor performs the following types of interrupt returns:"
  736. ""
  737. "ò Return from virtual-8086 mode."
  738. "ò Return to virtual-8086 mode."
  739. "ò Intra-privilege level return."
  740. "ò Inter-privilege level return."
  741. "ò Return from nested task (task switch)."
  742. ""
  743. "If the NT flag (EFLAGS register) is cleared, the IRET instruction performs a far return from the interrupt procedure, without a task switch. The code segment being returned to must be equally or less privileged than the interrupt handler routine (as indicated by the RPL field of the code segment selector popped from the stack). As with a real-address mode interrupt return, the IRET instruction pops the return instruction pointer, return code segment selector, and EFLAGS image from the stack to the EIP, CS, and EFLAGS registers, respectively, and then resumes execution of the interrupted program or procedure. If the return is to another privilege level, the IRET instruction also pops the stack pointer and SS from the stack, before resuming program execution. If the return is to virtual-8086 mode, the processor also pops the data segment registers from the stack."
  744. "If the NT flag is set, the IRET instruction performs a task switch (return) from a nested task  (a task called with a CALL instruction, an interrupt, or an exception) back to the calling or interrupted task. The updated state of the task executing the IRET instruction is saved in its TSS. If the task is reentered later, the code that follows the IRET instruction is executed."
  745. [2]
  746. "IF PE = 0"
  747. "THEN"
  748. "GOTO REAL-ADDRESS-MODE:;"
  749. "ELSE"
  750. "GOTO PROTECTED-MODE;"
  751. "FI;"
  752. ""
  753. "REAL-ADDRESS-MODE;"
  754. "IF OperandSize = 32"
  755. "THEN"
  756. "IF top 12 bytes of stack not within stack limits THEN #SS; FI;"
  757. "IF instruction pointer not within code segment limits THEN #GP(0); FI;"
  758. "EIP ¼ Pop();"
  759. "CS ¼ Pop(); (* 32-bit pop, high-order 16-bits discarded *)"
  760. "tempEFLAGS ¼ Pop();"
  761. "EFLAGS ¼ (tempEFLAGS AND 257FD5H) OR (EFLAGS AND 1A0000H);"
  762. "ELSE (* OperandSize = 16 *)"
  763. "IF top 6 bytes of stack are not within stack limits THEN #SS; FI;"
  764. "IF instruction pointer not within code segment limits THEN #GP(0); FI;"
  765. "EIP ¼ Pop();"
  766. "EIP ¼ EIP AND 0000FFFFH;"
  767. "CS ¼ Pop(); (* 16-bit pop *)"
  768. "EFLAGS[15:0] ¼ Pop();"
  769. "FI;"
  770. "END;"
  771. ""
  772. "PROTECTED-MODE:"
  773. "IF VM = 1 (* Virtual-8086 mode: PE=1, VM=1 *)"
  774. "THEN"
  775. "GOTO RETURN-FROM-VIRTUAL-8086-MODE; (* PE=1, VM=1 *)"
  776. "FI;"
  777. "IF NT = 1"
  778. "THEN"
  779. "GOTO TASK-RETURN;( *PE=1, VM=0, NT=1 *)"
  780. "FI;"
  781. "IF OperandSize=32"
  782. "THEN"
  783. "IF top 12 bytes of stack not within stack limits"
  784. "THEN #SS(0)"
  785. "FI;"
  786. "tempEIP ¼ Pop();"
  787. "tempCS ¼ Pop();"
  788. "tempEFLAGS ¼ Pop();"
  789. "ELSE (* OperandSize = 16 *)"
  790. "IF top 6 bytes of stack are not within stack limits"
  791. "THEN #SS(0);"
  792. "FI;"
  793. "tempEIP ¼ Pop();"
  794. "tempCS ¼ Pop();"
  795. "tempEFLAGS ¼ Pop();"
  796. "tempEIP ¼ tempEIP AND FFFFH;"
  797. "tempEFLAGS ¼ tempEFLAGS AND FFFFH;"
  798. "FI;"
  799. "IF tempEFLAGS(VM) = 1 AND CPL=0"
  800. "THEN"
  801. "GOTO RETURN-TO-VIRTUAL-8086-MODE;"
  802. "(* PE=1, VM=1 in EFLAGS image *)"
  803. "ELSE"
  804. "GOTO PROTECTED-MODE-RETURN;"
  805. "(* PE=1, VM=0 in EFLAGS image *)"
  806. "FI;"
  807. "RETURN-FROM-VIRTUAL-8086-MODE:"
  808. "(* Processor is in virtual-8086 mode when IRET is executed and stays in virtual-8086 mode *)"
  809. "IF IOPL=3 (* Virtual mode: PE=1, VM=1, IOPL=3 *)"
  810. "THEN IF OperandSize = 32"
  811. "THEN"
  812. "IF top 12 bytes of stack not within stack limits THEN #SS(0); FI;"
  813. "IF instruction pointer not within code segment limits THEN #GP(0); FI;"
  814. "EIP ¼ Pop();"
  815. "CS ¼ Pop(); (* 32-bit pop, high-order 16-bits discarded *)"
  816. "EFLAGS ¼ Pop();"
  817. "(*VM,IOPL,VIP,and VIF EFLAGS bits are not modified by pop *)"
  818. "ELSE (* OperandSize = 16 *)"
  819. "IF top 6 bytes of stack are not within stack limits THEN #SS(0); FI;"
  820. "IF instruction pointer not within code segment limits THEN #GP(0); FI;"
  821. "EIP ¼ Pop();"
  822. "EIP ¼ EIP AND 0000FFFFH;"
  823. "CS ¼ Pop(); (* 16-bit pop *)"
  824. "EFLAGS[15:0] ¼ Pop(); (* IOPL in EFLAGS is not modified by pop *)"
  825. "FI;"
  826. "ELSE"
  827. "#GP(0); (* trap to virtual-8086 monitor: PE=1, VM=1, IOPL<3 *)"
  828. "FI;"
  829. "END;"
  830. ""
  831. "RETURN-TO-VIRTUAL-8086-MODE:"
  832. "(* Interrupted procedure was in virtual-8086 mode: PE=1, VM=1 in flags image *)"
  833. "IF top 24 bytes of stack are not within stack segment limits"
  834. "THEN #SS(0);"
  835. "FI;"
  836. "IF instruction pointer not within code segment limits"
  837. "THEN #GP(0);"
  838. "FI;"
  839. "CS ¼ tempCS;"
  840. "EIP ¼ tempEIP;"
  841. "EFLAGS ¼ tempEFLAGS"
  842. "TempESP ¼ Pop();"
  843. "TempSS ¼ Pop();"
  844. "ES ¼ Pop(); (* pop 2 words; throw away high-order word *)"
  845. "DS ¼ Pop(); (* pop 2 words; throw away high-order word *)"
  846. "FS ¼ Pop(); (* pop 2 words; throw away high-order word *)"
  847. "GS ¼ Pop(); (* pop 2 words; throw away high-order word *)"
  848. "SS:ESP ¼ TempSS:TempESP;"
  849. "(* Resume execution in Virtual-8086 mode *)"
  850. "END;"
  851. ""
  852. "TASK-RETURN: (* PE=1, VM=1, NT=1 *)"
  853. "Read segment selector in link field of current TSS;"
  854. "IF local/global bit is set to local"
  855. "OR index not within GDT limits"
  856. "THEN #GP(TSS selector);"
  857. "FI;"
  858. "Access TSS for task specified in link field of current TSS;"
  859. "IF TSS descriptor type is not TSS or if the TSS is marked not busy"
  860. "THEN #GP(TSS selector);"
  861. "FI;"
  862. "IF TSS not present"
  863. "THEN #NP(TSS selector);"
  864. "FI;"
  865. "SWITCH-TASKS (without nesting) to TSS specified in link field of current TSS;"
  866. "Mark the task just abandoned as NOT BUSY;"
  867. "IF EIP is not within code segment limit"
  868. "THEN #GP(0);"
  869. "FI;"
  870. "END;"
  871. ""
  872. "PROTECTED-MODE-RETURN: (* PE=1, VM=0 in flags image *)"
  873. "IF return code segment selector is null THEN GP(0); FI;"
  874. "IF return code segment selector addrsses descriptor beyond descriptor table limit"
  875. "THEN GP(selector; FI;"
  876. "Read segment descriptor pointed to by the return code segment selector"
  877. "IF return code segment descriptor is not a code segment THEN #GP(selector); FI;"
  878. "IF return code segment selector RPL < CPL THEN #GP(selector); FI;"
  879. "IF return code segment descriptor is conforming"
  880. "AND return code segment DPL > return code segment selector RPL"
  881. "THEN #GP(selector); FI;"
  882. "IF return code segment descriptor is not present THEN #NP(selector); FI:"
  883. "IF return code segment selector RPL > CPL"
  884. "THEN GOTO RETURN-OUTER-PRIVILEGE-LEVEL;"
  885. "ELSE GOTO RETURN-TO-SAME-PRIVILEGE-LEVEL"
  886. "FI;"
  887. "END;"
  888. ""
  889. "RETURN-TO-SAME-PRIVILEGE-LEVEL: (* PE=1, VM=0 in flags image, RPL=CPL *)"
  890. "IF EIP is not within code segment limits THEN #GP(0); FI;"
  891. "EIP ¼ tempEIP;"
  892. "CS ¼ tempCS; (* segment descriptor information also loaded *)"
  893. "EFLAGS (CF, PF, AF, ZF, SF, TF, DF, OF, NT) ¼ tempEFLAGS;"
  894. "IF OperandSize=32"
  895. "THEN"
  896. "EFLAGS(RF, AC, ID) ¼ tempEFLAGS;"
  897. "FI;"
  898. "IF CPL ú IOPL"
  899. "THEN"
  900. "EFLAGS(IF) ¼ tempEFLAGS;"
  901. "FI;"
  902. "IF CPL = 0"
  903. "THEN"
  904. "EFLAGS(IOPL) ¼ tempEFLAGS;"
  905. "IF OperandSize=32"
  906. "THEN EFLAGS(VM, VIF, VIP) ¼ tempEFLAGS;"
  907. "FI;"
  908. "FI;"
  909. "END;"
  910. ""
  911. "RETURN-TO-OUTER-PRIVILGE-LEVEL:"
  912. "IF OperandSize=32"
  913. "THEN"
  914. "IF top 8 bytes on stack are not within limits THEN #SS(0); FI;"
  915. "ELSE (* OperandSize=16 *)"
  916. "IF top 4 bytes on stack are not within limits THEN #SS(0); FI;"
  917. "FI;"
  918. "Read return segment selector;"
  919. "IF stack segment selector is null THEN #GP(0); FI;"
  920. "IF return stack segment selector index is not within its descriptor table limits"
  921. "THEN #GP(SSselector); FI;"
  922. "Read segment descriptor pointed to by return segment selector;"
  923. "IF stack segment selector RPL ╣ RPL of the return code segment selector"
  924. "IF stack segment selector RPL ╣ RPL of the return code segment selector"
  925. "OR the stack segment descriptor does not indicate a a writable data segment;"
  926. "OR stack segment DPL ╣ RPL of the return code segment selector"
  927. "THEN #GP(SS selector);"
  928. "FI;"
  929. "IF stack segment is not present THEN #SS(SS selector); FI;"
  930. "IF tempEIP is not within code segment limit THEN #GP(0); FI;"
  931. "EIP ¼ tempEIP;"
  932. "CS ¼ tempCS;"
  933. "EFLAGS (CF, PF, AF, ZF, SF, TF, DF, OF, NT) ¼ tempEFLAGS;"
  934. "IF OperandSize=32"
  935. "THEN"
  936. "EFLAGS(RF, AC, ID) ¼ tempEFLAGS;"
  937. "FI;"
  938. "IF CPL ú IOPL"
  939. "THEN"
  940. "EFLAGS(IF) ¼ tempEFLAGS;"
  941. "FI;"
  942. "IF CPL = 0"
  943. "THEN"
  944. "EFLAGS(IOPL) ¼ tempEFLAGS;"
  945. "IF OperandSize=32"
  946. "THEN EFLAGS(VM, VIF, VIP) ¼ tempEFLAGS;"
  947. "FI;"
  948. "FI;"
  949. "CPL ¼ RPL of the return code segment selector;"
  950. "FOR each of segment register (ES, FS, GS, and DS)"
  951. "DO;"
  952. "IF segment register points to data or non-conforming code segment"
  953. "AND CPL > segment descriptor DPL (* stored in hidden part of segment register *)"
  954. "THEN (* segment register invalid *)"
  955. "SegmentSelector ¼ 0; (* null segment selector *)"
  956. "FI;"
  957. "OD;"
  958. "END:"
  959. [3]
  960. "All the flags and fields in the EFLAGS register are potentially modified, depending on the mode of operation of the processor. If performing a return from a nested task to a previous task, the EFLAGS register will be modified according to the EFLAGS image stored in the previous taskÆs TSS."
  961. [4]
  962. "Protected Mode Exceptions"
  963. "#GP(0) If the return code or stack segment selector is null. If the return instruction pointer is not within the return code segment limit."
  964. "#GP(selector) If a segment selector index is outside its descriptor table limits. If the return code segment selector RPL is greater than the CPL. If the DPL of a conforming-code segment is greater than the return code segment selector RPL. If the DPL for a nonconforming-code segment is not equal to the RPL of the code segment selector. If the stack segment descriptor DPL is not equal to the RPL of the return code segment selector. If the stack segment is not a writable data segment. If the stack segment selector RPL is not equal to the RPL of the return code segment selector. If the segment descriptor for a code segment does not indicate it is a code segment. If the segment selector for a TSS has its local/global bit set for local. If a TSS segment descriptor specifies that the TSS is busy or not available."
  965. "#SS(0) If the top bytes of stack are not within stack limits."
  966. "#NP(selector) If the return code or stack segment is not present."
  967. "#PF(fault-code) If a page fault occurs."
  968. "#AC(0) If an unaligned memory reference occurs when the CPL is 3 and alignment checking is enabled."
  969. ""
  970. "Real-Address Mode Exceptions"
  971. ""
  972. "#GP If the return instruction pointer is not within the return code segment limit."
  973. "#SS If the top bytes of stack are not within stack limits."
  974. ""
  975. "Virtual-8086 Mode Exceptions"
  976. ""
  977. "#GP(0) If the return instruction pointer is not within the return code segment limit. IF IOPL not equal to 3"
  978. "#PF(fault-code) If a page fault occurs."
  979. "#SS(0) If the top bytes of stack are not within stack limits."
  980. "#AC(0) If an unaligned memory reference occurs and alignment checking is enabled."
  981. [5]
  982. "CF IRET Interrupt return (16-bit operand size)"
  983. "CF IRETD Interrupt return (32-bit operand size)"
  984. [6]
  985. </IRET>
  986. </IRETD>