modrm19.s 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. # modrm19.s -- derive the complete 16-bit ModR/M effective-address table by
  2. # EXECUTION, not from memory. 24 cases: 8 r/m values x 3 mod values.
  3. #
  4. # For each case: clear 0x0000..0x4FFF, store 0xBEEF through the encoding under
  5. # test, then scan for the word and emit its offset as 2 raw bytes.
  6. # BX=0x1000 DI=0x2000 SI=0x0030 BP=0x0040, so every candidate is distinct.
  7. #
  8. # mod=00 : no displacement follows
  9. # mod=01 : disp8 = 0x44
  10. # mod=10 : disp16 = 0x1234
  11. #
  12. # The three "mod=11" cases are register-to-register and are not addressed here.
  13. # Output: 24 groups of "lo hi 0x20", then 0x0A 0x0A.
  14. .code16
  15. .text
  16. .globl _start
  17. _start:
  18. cli
  19. xorw %ax, %ax
  20. movw %ax, %es
  21. movw $0x1000, %bx
  22. movw $0x2000, %di
  23. movw $0x0030, %si
  24. movw $0x0040, %bp
  25. # ---- mod = 00, r/m = 000..111 -------------------------------
  26. call clr
  27. movw $0xBEEF, %ax
  28. .byte 0x26, 0x89, 0x00 # 00 000
  29. call rep_
  30. call clr
  31. movw $0xBEEF, %ax
  32. .byte 0x26, 0x89, 0x01 # 00 001
  33. call rep_
  34. call clr
  35. movw $0xBEEF, %ax
  36. .byte 0x26, 0x89, 0x02 # 00 010
  37. call rep_
  38. call clr
  39. movw $0xBEEF, %ax
  40. .byte 0x26, 0x89, 0x03 # 00 011
  41. call rep_
  42. call clr
  43. movw $0xBEEF, %ax
  44. .byte 0x26, 0x89, 0x04 # 00 100
  45. call rep_
  46. call clr
  47. movw $0xBEEF, %ax
  48. .byte 0x26, 0x89, 0x05 # 00 101
  49. call rep_
  50. call clr
  51. movw $0xBEEF, %ax
  52. .byte 0x26, 0x89, 0x06, 0x34, 0x12 # 00 110 direct
  53. call rep_
  54. call clr
  55. movw $0xBEEF, %ax
  56. .byte 0x26, 0x89, 0x07 # 00 111
  57. call rep_
  58. # ---- mod = 01, disp8 = 0x44 --------------------------------
  59. call clr
  60. movw $0xBEEF, %ax
  61. .byte 0x26, 0x89, 0x40, 0x44 # 01 000
  62. call rep_
  63. call clr
  64. movw $0xBEEF, %ax
  65. .byte 0x26, 0x89, 0x41, 0x44 # 01 001
  66. call rep_
  67. call clr
  68. movw $0xBEEF, %ax
  69. .byte 0x26, 0x89, 0x42, 0x44 # 01 010
  70. call rep_
  71. call clr
  72. movw $0xBEEF, %ax
  73. .byte 0x26, 0x89, 0x43, 0x44 # 01 011
  74. call rep_
  75. call clr
  76. movw $0xBEEF, %ax
  77. .byte 0x26, 0x89, 0x44, 0x44 # 01 100
  78. call rep_
  79. call clr
  80. movw $0xBEEF, %ax
  81. .byte 0x26, 0x89, 0x45, 0x44 # 01 101
  82. call rep_
  83. call clr
  84. movw $0xBEEF, %ax
  85. .byte 0x26, 0x89, 0x46, 0x44 # 01 110
  86. call rep_
  87. call clr
  88. movw $0xBEEF, %ax
  89. .byte 0x26, 0x89, 0x47, 0x44 # 01 111
  90. call rep_
  91. # ---- mod = 10, disp16 = 0x1234 ------------------------------
  92. call clr
  93. movw $0xBEEF, %ax
  94. .byte 0x26, 0x89, 0x80, 0x34, 0x12 # 10 000
  95. call rep_
  96. call clr
  97. movw $0xBEEF, %ax
  98. .byte 0x26, 0x89, 0x81, 0x34, 0x12 # 10 001
  99. call rep_
  100. call clr
  101. movw $0xBEEF, %ax
  102. .byte 0x26, 0x89, 0x82, 0x34, 0x12 # 10 010
  103. call rep_
  104. call clr
  105. movw $0xBEEF, %ax
  106. .byte 0x26, 0x89, 0x83, 0x34, 0x12 # 10 011
  107. call rep_
  108. call clr
  109. movw $0xBEEF, %ax
  110. .byte 0x26, 0x89, 0x84, 0x34, 0x12 # 10 100
  111. call rep_
  112. call clr
  113. movw $0xBEEF, %ax
  114. .byte 0x26, 0x89, 0x85, 0x34, 0x12 # 10 101
  115. call rep_
  116. call clr
  117. movw $0xBEEF, %ax
  118. .byte 0x26, 0x89, 0x86, 0x34, 0x12 # 10 110
  119. call rep_
  120. call clr
  121. movw $0xBEEF, %ax
  122. .byte 0x26, 0x89, 0x87, 0x34, 0x12 # 10 111
  123. call rep_
  124. movw $0x3F8, %dx
  125. movb $10, %al
  126. outb %al, %dx
  127. hlt
  128. # clr -- clear 0000:0000..0000:4FFF
  129. clr:
  130. pushw %di
  131. pushw %cx
  132. pushw %ax
  133. xorw %ax, %ax
  134. movw $0x0000, %di
  135. movw $0x2800, %cx
  136. rep stosw
  137. popw %ax
  138. popw %cx
  139. popw %di
  140. ret
  141. # rep_ -- emit the address of the word just stored
  142. rep_:
  143. pushw %ax
  144. pushw %bx
  145. pushw %cx
  146. pushw %dx
  147. pushw %si
  148. pushw %di
  149. xorw %si, %si
  150. scan:
  151. cmpw $0x3600, %si
  152. jae none
  153. movw %es:(%si), %dx
  154. cmpw $0xBEEF, %dx
  155. je found
  156. incw %si
  157. jmp scan
  158. found:
  159. movw %si, %ax
  160. call putb
  161. movb %ah, %al
  162. call putb
  163. jmp done
  164. none:
  165. movw $0xFF, %ax
  166. call putb
  167. movw $0xFF, %ax
  168. call putb
  169. done:
  170. movw $0x3F8, %dx
  171. movb $' ', %al
  172. outb %al, %dx
  173. popw %di
  174. popw %si
  175. popw %dx
  176. popw %cx
  177. popw %bx
  178. popw %ax
  179. ret
  180. putb:
  181. pushw %dx
  182. movw $0x3F8, %dx
  183. outb %al, %dx
  184. popw %dx
  185. ret