Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

290 lines
4.3 KiB

  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name:
  4. jmpops.c
  5. Abstract:
  6. This module implements the code to emulate jump opcodes.
  7. Author:
  8. David N. Cutler (davec) 13-Sep-1994
  9. Environment:
  10. Kernel mode only.
  11. Revision History:
  12. --*/
  13. #include "nthal.h"
  14. #include "emulate.h"
  15. VOID
  16. XmJcxzOp (
  17. IN PRXM_CONTEXT P
  18. )
  19. /*++
  20. Routine Description:
  21. This function emulates a jcxz instruction.
  22. Arguments:
  23. P - Supplies a pointer to the emulation context structure.
  24. Return Value:
  25. None.
  26. --*/
  27. {
  28. ULONG Condition;
  29. //
  30. // If eCX is zero, then set the new IP value.
  31. //
  32. if (P->OpsizePrefixActive != FALSE) {
  33. Condition = P->Gpr[ECX].Exx;
  34. } else {
  35. Condition = P->Gpr[CX].Xx;
  36. }
  37. if (Condition == 0) {
  38. P->Eip = P->DstValue.Word;
  39. XmTraceJumps(P);
  40. }
  41. return;
  42. }
  43. VOID
  44. XmJmpOp (
  45. IN PRXM_CONTEXT P
  46. )
  47. /*++
  48. Routine Description:
  49. This function emulates a jmp near relative instruction.
  50. Arguments:
  51. P - Supplies a pointer to the emulation context structure.
  52. Return Value:
  53. None.
  54. --*/
  55. {
  56. //
  57. // Set the destination segment, if required, and set the new IP.
  58. //
  59. P->Eip = P->DstValue.Long;
  60. if ((P->CurrentOpcode == 0xea) || (P->FunctionIndex != X86_JMP_OP)) {
  61. P->SegmentRegister[CS] = P->DstSegment;
  62. }
  63. XmTraceJumps(P);
  64. return;
  65. }
  66. VOID
  67. XmJxxOp (
  68. IN PRXM_CONTEXT P
  69. )
  70. /*++
  71. Routine Description:
  72. This function emulates conditional jump instructions.
  73. Arguments:
  74. P - Supplies a pointer to the emulation context structure.
  75. Return Value:
  76. None.
  77. --*/
  78. {
  79. ULONG Complement;
  80. ULONG Condition;
  81. //
  82. // Case on the jump control value.
  83. //
  84. Complement = P->SrcValue.Long & 1;
  85. switch (P->SrcValue.Long >> 1) {
  86. //
  87. // Jump if overflow/not overflow.
  88. //
  89. case 0:
  90. Condition = P->Eflags.EFLAG_OF;
  91. break;
  92. //
  93. // Jump if below/not below.
  94. //
  95. case 1:
  96. Condition = P->Eflags.EFLAG_CF;
  97. break;
  98. //
  99. // Jump if zero/not zero.
  100. //
  101. case 2:
  102. Condition = P->Eflags.EFLAG_ZF;
  103. break;
  104. //
  105. // Jump if below or equal/not below or equal.
  106. //
  107. case 3:
  108. Condition = P->Eflags.EFLAG_CF | P->Eflags.EFLAG_ZF;
  109. break;
  110. //
  111. // Jump if signed/not signed.
  112. //
  113. case 4:
  114. Condition = P->Eflags.EFLAG_SF;
  115. break;
  116. //
  117. // Jump if parity/not parity.
  118. //
  119. case 5:
  120. Condition = P->Eflags.EFLAG_PF;
  121. break;
  122. //
  123. // Jump if less/not less.
  124. //
  125. case 6:
  126. Condition = (P->Eflags.EFLAG_SF ^ P->Eflags.EFLAG_OF);
  127. break;
  128. //
  129. // Jump if less or equal/not less or equal.
  130. //
  131. case 7:
  132. Condition = (P->Eflags.EFLAG_SF ^ P->Eflags.EFLAG_OF) | P->Eflags.EFLAG_ZF;
  133. break;
  134. }
  135. //
  136. // If the specified condition is met, then set the new IP value.
  137. //
  138. if ((Condition ^ Complement) != 0) {
  139. P->Eip = P->DstValue.Word;
  140. XmTraceJumps(P);
  141. }
  142. return;
  143. }
  144. VOID
  145. XmLoopOp (
  146. IN PRXM_CONTEXT P
  147. )
  148. /*++
  149. Routine Description:
  150. This function emulates loop, loopz, or a loopnz instructions.
  151. Arguments:
  152. P - Supplies a pointer to the emulation context structure.
  153. Return Value:
  154. None.
  155. --*/
  156. {
  157. ULONG Condition;
  158. ULONG Result;
  159. ULONG Type;
  160. //
  161. // Set the address of the destination and compute the result value.
  162. //
  163. Result = P->Gpr[ECX].Exx - 1;
  164. P->DstLong = (UNALIGNED ULONG *)(&P->Gpr[ECX].Exx);
  165. if (P->OpaddrPrefixActive != FALSE) {
  166. P->DataType = LONG_DATA;
  167. } else {
  168. P->DataType = WORD_DATA;
  169. Result &= 0xffff;
  170. }
  171. XmStoreResult(P, Result);
  172. //
  173. // Isolate the loop type and test the appropriate condition.
  174. //
  175. // Type 0 - loopnz
  176. // 1 - loopz
  177. // 2 - loop
  178. //
  179. Type = P->CurrentOpcode & 3;
  180. if (Type == 0) {
  181. Condition = P->Eflags.EFLAG_ZF ^ 1;
  182. } else if (Type == 1) {
  183. Condition = P->Eflags.EFLAG_ZF;
  184. } else {
  185. Condition = TRUE;
  186. }
  187. //
  188. // If the loop condition is met, then set the new IP value.
  189. //
  190. if ((Condition != FALSE) && (Result != 0)) {
  191. P->Eip = P->DstValue.Word;
  192. XmTraceJumps(P);
  193. }
  194. return;
  195. }