modrm.rs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. use cpu::cpu::*;
  2. use paging::OrPageFault;
  3. pub unsafe fn resolve_modrm16(modrm_byte: i32) -> OrPageFault<i32> {
  4. Ok(match modrm_byte {
  5. 0 | 8 | 16 | 24 | 32 | 40 | 48 | 56 => {
  6. get_seg_prefix_ds(read_reg16(BX) + read_reg16(SI) & 0xFFFF)?
  7. },
  8. 64 | 72 | 80 | 88 | 96 | 104 | 112 | 120 => {
  9. get_seg_prefix_ds(read_reg16(BX) + read_reg16(SI) + read_imm8s()? & 0xFFFF)?
  10. },
  11. 128 | 136 | 144 | 152 | 160 | 168 | 176 | 184 => {
  12. get_seg_prefix_ds(read_reg16(BX) + read_reg16(SI) + read_imm16()? & 0xFFFF)?
  13. },
  14. 1 | 9 | 17 | 25 | 33 | 41 | 49 | 57 => {
  15. get_seg_prefix_ds(read_reg16(BX) + read_reg16(DI) & 0xFFFF)?
  16. },
  17. 65 | 73 | 81 | 89 | 97 | 105 | 113 | 121 => {
  18. get_seg_prefix_ds(read_reg16(BX) + read_reg16(DI) + read_imm8s()? & 0xFFFF)?
  19. },
  20. 129 | 137 | 145 | 153 | 161 | 169 | 177 | 185 => {
  21. get_seg_prefix_ds(read_reg16(BX) + read_reg16(DI) + read_imm16()? & 0xFFFF)?
  22. },
  23. 2 | 10 | 18 | 26 | 34 | 42 | 50 | 58 => {
  24. get_seg_prefix_ss(read_reg16(BP) + read_reg16(SI) & 0xFFFF)?
  25. },
  26. 66 | 74 | 82 | 90 | 98 | 106 | 114 | 122 => {
  27. get_seg_prefix_ss(read_reg16(BP) + read_reg16(SI) + read_imm8s()? & 0xFFFF)?
  28. },
  29. 130 | 138 | 146 | 154 | 162 | 170 | 178 | 186 => {
  30. get_seg_prefix_ss(read_reg16(BP) + read_reg16(SI) + read_imm16()? & 0xFFFF)?
  31. },
  32. 3 | 11 | 19 | 27 | 35 | 43 | 51 | 59 => {
  33. get_seg_prefix_ss(read_reg16(BP) + read_reg16(DI) & 0xFFFF)?
  34. },
  35. 67 | 75 | 83 | 91 | 99 | 107 | 115 | 123 => {
  36. get_seg_prefix_ss(read_reg16(BP) + read_reg16(DI) + read_imm8s()? & 0xFFFF)?
  37. },
  38. 131 | 139 | 147 | 155 | 163 | 171 | 179 | 187 => {
  39. get_seg_prefix_ss(read_reg16(BP) + read_reg16(DI) + read_imm16()? & 0xFFFF)?
  40. },
  41. 4 | 12 | 20 | 28 | 36 | 44 | 52 | 60 => get_seg_prefix_ds(read_reg16(SI) & 0xFFFF)?,
  42. 68 | 76 | 84 | 92 | 100 | 108 | 116 | 124 => {
  43. get_seg_prefix_ds(read_reg16(SI) + read_imm8s()? & 0xFFFF)?
  44. },
  45. 132 | 140 | 148 | 156 | 164 | 172 | 180 | 188 => {
  46. get_seg_prefix_ds(read_reg16(SI) + read_imm16()? & 0xFFFF)?
  47. },
  48. 5 | 13 | 21 | 29 | 37 | 45 | 53 | 61 => get_seg_prefix_ds(read_reg16(DI) & 0xFFFF)?,
  49. 69 | 77 | 85 | 93 | 101 | 109 | 117 | 125 => {
  50. get_seg_prefix_ds(read_reg16(DI) + read_imm8s()? & 0xFFFF)?
  51. },
  52. 133 | 141 | 149 | 157 | 165 | 173 | 181 | 189 => {
  53. get_seg_prefix_ds(read_reg16(DI) + read_imm16()? & 0xFFFF)?
  54. },
  55. 6 | 14 | 22 | 30 | 38 | 46 | 54 | 62 => get_seg_prefix_ds(read_imm16()?)?,
  56. 70 | 78 | 86 | 94 | 102 | 110 | 118 | 126 => {
  57. get_seg_prefix_ss(read_reg16(BP) + read_imm8s()? & 0xFFFF)?
  58. },
  59. 134 | 142 | 150 | 158 | 166 | 174 | 182 | 190 => {
  60. get_seg_prefix_ss(read_reg16(BP) + read_imm16()? & 0xFFFF)?
  61. },
  62. 7 | 15 | 23 | 31 | 39 | 47 | 55 | 63 => get_seg_prefix_ds(read_reg16(BX) & 0xFFFF)?,
  63. 71 | 79 | 87 | 95 | 103 | 111 | 119 | 127 => {
  64. get_seg_prefix_ds(read_reg16(BX) + read_imm8s()? & 0xFFFF)?
  65. },
  66. 135 | 143 | 151 | 159 | 167 | 175 | 183 | 191 => {
  67. get_seg_prefix_ds(read_reg16(BX) + read_imm16()? & 0xFFFF)?
  68. },
  69. _ => {
  70. dbg_assert!(false);
  71. 0
  72. },
  73. })
  74. }
  75. pub unsafe fn resolve_modrm32_(modrm_byte: i32) -> OrPageFault<i32> {
  76. let r = (modrm_byte & 7) as u8;
  77. dbg_assert!(modrm_byte < 192);
  78. Ok(if r as i32 == 4 {
  79. if modrm_byte < 64 {
  80. resolve_sib(false)?
  81. }
  82. else {
  83. resolve_sib(true)? + if modrm_byte < 128 { read_imm8s()? } else { read_imm32s()? }
  84. }
  85. }
  86. else if r as i32 == 5 {
  87. if modrm_byte < 64 {
  88. get_seg_prefix_ds(read_imm32s()?)?
  89. }
  90. else {
  91. get_seg_prefix_ss(
  92. read_reg32(EBP) + if modrm_byte < 128 { read_imm8s()? } else { read_imm32s()? },
  93. )?
  94. }
  95. }
  96. else if modrm_byte < 64 {
  97. get_seg_prefix_ds(read_reg32(r as i32))?
  98. }
  99. else {
  100. get_seg_prefix_ds(
  101. read_reg32(r as i32) + if modrm_byte < 128 { read_imm8s()? } else { read_imm32s()? },
  102. )?
  103. })
  104. }
  105. unsafe fn resolve_sib(mod_0: bool) -> OrPageFault<i32> {
  106. let s;
  107. let sib_byte = read_imm8()? as u8;
  108. let r = (sib_byte as i32 & 7) as u8;
  109. let m = (sib_byte as i32 >> 3 & 7) as u8;
  110. let base;
  111. let seg;
  112. if r as i32 == 4 {
  113. base = read_reg32(ESP);
  114. seg = SS
  115. }
  116. else if r as i32 == 5 {
  117. if mod_0 {
  118. base = read_reg32(EBP);
  119. seg = SS
  120. }
  121. else {
  122. base = read_imm32s()?;
  123. seg = DS
  124. }
  125. }
  126. else {
  127. base = read_reg32(r as i32);
  128. seg = DS
  129. }
  130. let offset;
  131. if m as i32 == 4 {
  132. offset = 0
  133. }
  134. else {
  135. s = (sib_byte as i32 >> 6 & 3) as u8;
  136. offset = read_reg32(m as i32) << s as i32
  137. }
  138. Ok(get_seg_prefix(seg)? + base + offset)
  139. }
  140. pub unsafe fn resolve_modrm32(modrm_byte: i32) -> OrPageFault<i32> {
  141. Ok(match modrm_byte {
  142. 0 | 8 | 16 | 24 | 32 | 40 | 48 | 56 => get_seg_prefix_ds(read_reg32(EAX))?,
  143. 64 | 72 | 80 | 88 | 96 | 104 | 112 | 120 => {
  144. get_seg_prefix_ds(read_reg32(EAX) + read_imm8s()?)?
  145. },
  146. 128 | 136 | 144 | 152 | 160 | 168 | 176 | 184 => {
  147. get_seg_prefix_ds(read_reg32(EAX) + read_imm32s()?)?
  148. },
  149. 1 | 9 | 17 | 25 | 33 | 41 | 49 | 57 => get_seg_prefix_ds(read_reg32(ECX))?,
  150. 65 | 73 | 81 | 89 | 97 | 105 | 113 | 121 => {
  151. get_seg_prefix_ds(read_reg32(ECX) + read_imm8s()?)?
  152. },
  153. 129 | 137 | 145 | 153 | 161 | 169 | 177 | 185 => {
  154. get_seg_prefix_ds(read_reg32(ECX) + read_imm32s()?)?
  155. },
  156. 2 | 10 | 18 | 26 | 34 | 42 | 50 | 58 => get_seg_prefix_ds(read_reg32(EDX))?,
  157. 66 | 74 | 82 | 90 | 98 | 106 | 114 | 122 => {
  158. get_seg_prefix_ds(read_reg32(EDX) + read_imm8s()?)?
  159. },
  160. 130 | 138 | 146 | 154 | 162 | 170 | 178 | 186 => {
  161. get_seg_prefix_ds(read_reg32(EDX) + read_imm32s()?)?
  162. },
  163. 3 | 11 | 19 | 27 | 35 | 43 | 51 | 59 => get_seg_prefix_ds(read_reg32(EBX))?,
  164. 67 | 75 | 83 | 91 | 99 | 107 | 115 | 123 => {
  165. get_seg_prefix_ds(read_reg32(EBX) + read_imm8s()?)?
  166. },
  167. 131 | 139 | 147 | 155 | 163 | 171 | 179 | 187 => {
  168. get_seg_prefix_ds(read_reg32(EBX) + read_imm32s()?)?
  169. },
  170. 4 | 12 | 20 | 28 | 36 | 44 | 52 | 60 => resolve_sib(false)?,
  171. 68 | 76 | 84 | 92 | 100 | 108 | 116 | 124 => resolve_sib(true)? + read_imm8s()?,
  172. 132 | 140 | 148 | 156 | 164 | 172 | 180 | 188 => resolve_sib(true)? + read_imm32s()?,
  173. 5 | 13 | 21 | 29 | 37 | 45 | 53 | 61 => get_seg_prefix_ds(read_imm32s()?)?,
  174. 69 | 77 | 85 | 93 | 101 | 109 | 117 | 125 => {
  175. get_seg_prefix_ss(read_reg32(EBP) + read_imm8s()?)?
  176. },
  177. 133 | 141 | 149 | 157 | 165 | 173 | 181 | 189 => {
  178. get_seg_prefix_ss(read_reg32(EBP) + read_imm32s()?)?
  179. },
  180. 6 | 14 | 22 | 30 | 38 | 46 | 54 | 62 => get_seg_prefix_ds(read_reg32(ESI))?,
  181. 70 | 78 | 86 | 94 | 102 | 110 | 118 | 126 => {
  182. get_seg_prefix_ds(read_reg32(ESI) + read_imm8s()?)?
  183. },
  184. 134 | 142 | 150 | 158 | 166 | 174 | 182 | 190 => {
  185. get_seg_prefix_ds(read_reg32(ESI) + read_imm32s()?)?
  186. },
  187. 7 | 15 | 23 | 31 | 39 | 47 | 55 | 63 => get_seg_prefix_ds(read_reg32(EDI))?,
  188. 71 | 79 | 87 | 95 | 103 | 111 | 119 | 127 => {
  189. get_seg_prefix_ds(read_reg32(EDI) + read_imm8s()?)?
  190. },
  191. 135 | 143 | 151 | 159 | 167 | 175 | 183 | 191 => {
  192. get_seg_prefix_ds(read_reg32(EDI) + read_imm32s()?)?
  193. },
  194. _ => {
  195. dbg_assert!(false);
  196. 0
  197. },
  198. })
  199. }