vm86 виртуальный режим

Тема в разделе "WASM.OS.DEVEL", создана пользователем Pavia, 25 мар 2008.

  1. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    Уже месяц пишу. Так долго потому что пишу по выходным.
    Обработчик эмулирует запрeщенные команды. Код пишется из расчета 486 процессора. Пока не все добавил
    Ничего непонимаю. Тестирую на Borchs,
    Почемуто процессор выходит в защищенный режим на EIP=0.

    Обработчик #GP

    Код (Text):
    1. test DWord [esp+12],20000h          // Проверяем VM флаг
    2. jz @err                             // ошибка исключение
    3. // Привелегированные инструкции.
    4. push eax
    5. push ebx
    6.  
    7. mov ax, DS_DESCR
    8. mov ds,ax
    9. mov es,ax
    10.  
    11. xor eax, eax
    12. mov eax,DWord [esp+8+8]          //cs
    13. shl eax,4
    14. add eax,DWord [esp+4+8]          //eip
    15.  
    16.  
    17. xor ebx, ebx
    18. mov ebx,[esp+5*4+8]              // Old SS
    19. shl ebx,4
    20. add ebx, [esp+4*4+8]             // Old ESP
    21.  
    22.  
    23. cmp byte [eax],0FAh               //CLI
    24. jne @a1
    25. //and word [esp+3*4+8], not 200h   //1 000 000 000b=200h
    26. inc DWord [esp+4+8]              // EIP +1
    27. jmp @_end
    28. @a1:
    29.  
    30. cmp byte [eax],0FBh               //STI
    31. jne @a2
    32. or word [esp+3*4+8], 200h        //1 000 000 000b=200h
    33. inc DWord [esp+4+8]              // EIP +1
    34. jmp @_end
    35. @a2:
    36.  
    37. cmp byte [eax],9Ch               //PUSHF
    38. jne @a3
    39. add word [esp+4*4+8],-2          // Old ESP
    40. mov ax, word [esp+3*4+8]         // Old EFLAGS
    41. mov word [ebx-2], ax
    42. inc DWord [esp+4+8]              // EIP +1
    43. jmp @_end
    44. @a3:
    45.  
    46. cmp byte [eax],9Dh               //POPF
    47. jne @a4
    48. mov ax,word [ebx]
    49. mov word [esp+3*4+8],ax          // Old EFLAGS
    50. add word [esp+4*4+8],+2          // Old ESP
    51. inc DWord [esp+4+8]              // EIP +1
    52. jmp @_end
    53. @a4:
    54.  
    55.  
    56. cmp byte [eax],0CDh               //INT xx
    57. jne @a5
    58. add eax,2
    59.  
    60. mov Word [ebx+6], ax             // IP
    61. shr eax,16
    62. shl eax,12
    63. mov Word [ebx+4], ax             // CS
    64.  
    65.  
    66. mov ax, Word [esp+3*4+8]         //FLAGS
    67. mov Word [ebx+2], ax
    68.  
    69. add word [esp+4*4+8],-6          // Old ESP
    70.  
    71.  
    72. xor eax, eax
    73. mov eax,DWord [esp+8+8]          //cs
    74. shl eax,4
    75. add eax,DWord [esp+4+8]          //eip
    76. xor ebx,ebx
    77. mov bl, [eax+1]
    78. shl ebx, 2
    79.  
    80. mov ax,[ebx+2]
    81. mov Word [esp+8+8], ax            //Old CS
    82. mov ax,[ebx]
    83. mov Word [esp+4+8], ax            //Old EIP
    84.  
    85. jmp @_end
    86. @a5:
    87.  
    88. cmp byte [eax],0CFh               //IRET
    89. jne @a6
    90. mov ax,word [ebx+4]                // FLAGS
    91. mov word [esp+3*4+8],ax          // Old EFLAGS
    92.  
    93. mov ax,word [ebx+2]              // CS
    94. mov Word [esp+8+8], ax           //Old CS
    95.  
    96. mov ax,word [ebx]              // IP
    97. mov Word [esp+4+8], ax           //Old EIP
    98.  
    99. add word [esp+4*4+8],6           // Old ESP
    100. jmp @_end
    101. @a6:
    102.  
    103. cmp byte [eax],0ECh               //IN AL,DX
    104. jne @a7
    105. IN AL,DX
    106. mov Byte [esp+4], al
    107. inc DWord [esp+4+8]              // EIP +1
    108. jmp @_end
    109. @a7:
    110.  
    111. cmp byte [eax],0EDh               //IN AX,DX  
    112. jne @a8
    113. IN AX,DX
    114. mov Word [esp+4], ax
    115. inc DWord [esp+4+8]              // EIP +1
    116. jmp @_end
    117. @a8:
    118.  
    119. cmp word [eax],0ED66h               //IN EAX,DX  
    120. jne @a9
    121. IN EAX,DX
    122. mov DWord [esp+4], eax
    123. add DWord [esp+4+8],2              // EIP +2
    124. jmp @_end
    125. @a9:
    126.  
    127. cmp byte [eax],6Ch               //INSB  
    128. jne @a10
    129. INSB
    130. mov Byte [esp+4], al
    131. inc DWord [esp+4+8]              // EIP +1
    132. jmp @_end
    133. @a10:
    134.  
    135. cmp byte [eax],6Dh               //INSW  
    136. jne @a11
    137. INSW
    138. mov Word [esp+4], ax
    139. inc DWord [esp+4+8]              // EIP +1
    140. jmp @_end
    141. @a11:
    142.  
    143. cmp word [eax],6D66h              //INSD  
    144. jne @a12
    145. INSD
    146. mov DWord [esp+4], eax
    147. add DWord [esp+4+8],2             // EIP +2
    148. jmp @_end
    149. @a12:
    150.  
    151. cmp byte [eax],0EEh               //OUT DX, AL
    152. jne @a13
    153. mov eax,[esp+4]
    154. OUT DX, AL
    155. inc DWord [esp+4+8]              // EIP +1
    156. jmp @_end
    157. @a13:
    158.  
    159. cmp byte [eax],0EFh               //OUT DX, AX  
    160. jne @a14
    161. mov eax,[esp+4]
    162. OUT DX, AX
    163. inc DWord [esp+4+8]              // EIP +1
    164. jmp @_end
    165. @a14:
    166.  
    167. cmp word [eax],0EF66h               //OUT DX, EAX
    168. jne @a15
    169. mov eax,[esp+4]
    170. OUT DX, EAX
    171. add DWord [esp+4+8],2              // EIP +2
    172. jmp @_end
    173. @a15:
    174.  
    175. cmp byte [eax],6Eh               //OUTSB  
    176. jne @a16
    177. mov eax,[esp+4]
    178. OUTSB
    179. inc DWord [esp+4+8]              // EIP +1
    180. jmp @_end
    181. @a16:
    182.  
    183. cmp byte [eax],6Fh               //OUTSW  
    184. jne @a17
    185. mov eax,[esp+4]
    186. OUTSW
    187. inc DWord [esp+4+8]              // EIP +1
    188. jmp @_end
    189. @a17:
    190.  
    191. cmp word [eax],6F66h              //OUTSD  
    192. jne @a18
    193. mov eax,[esp+4]
    194. OUTSD
    195. add DWord [esp+4+8],2             // EIP +2
    196. jmp @_end
    197. @a18:
    198.  
    199. @_end:
    200.  
    201. pop ebx
    202. pop eax
    203. add esp,4
    204. IRETD
    205. @err:
    206. MOV  AX,0Dh
    207. CALL DebugPRint;
    208. IRETD
    Походу срыв стека, но както внезапно. Т.е идет все хорошо, а потм бац и все падает.
     
  2. diamond

    diamond New Member

    Публикаций:
    0
    Регистрация:
    21 май 2004
    Сообщения:
    507
    Адрес:
    Russia
    Вот здесь
    Код (Text):
    1. cmp byte [eax],0CDh               //INT xx
    2. jne @a5
    3. add eax,2
    4.  
    5. mov Word [ebx+6], ax             // IP
    6. shr eax,16
    7. shl eax,12
    8. mov Word [ebx+4], ax             // CS
    9.  
    10.  
    11. mov ax, Word [esp+3*4+8]         //FLAGS
    12. mov Word [ebx+2], ax
    знак в трёх местах при [ebx+A] случайно не перепутан?
     
  3. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    да, похоже надо -
     
  4. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    diamond
    ДА ошибочка, но проблему не решает.
     
  5. diamond

    diamond New Member

    Публикаций:
    0
    Регистрация:
    21 май 2004
    Сообщения:
    507
    Адрес:
    Russia
    В принципе код ещё не учитывает того, что insb, который вводит байт по адресу es:di, в V86-режиме и в защищённом режиме пишет в общем случае в разные области памяти (база es может быть разной) и аналогично для прочих команд этой серии, но по логике на eip это никак влиять не должно...
    Попробуй в TSS создать I/O permission map, забитую нулями - так #GP не будет генерироваться для команд работы с портами, что позволит выяснить, какая часть эмуляции глючит.
    Кстати, а образ для Bochs выложить можешь?
     
  6. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    Вообщем както странно. Вызываю прерывание реального режима int 10h
    В итоге поподаю на Hlt смущает адресс инструкции 0000:0004

    Вызываю int 12h прерывание выполняется удачно.
    Даже не знаю почему так. =( Может EFLAGS надо лучши обрабатывать?

    diamond , можно попробовать. Хотя в int 10h там out dx,al используют.
     
  7. diamond

    diamond New Member

    Публикаций:
    0
    Регистрация:
    21 май 2004
    Сообщения:
    507
    Адрес:
    Russia
    Pavia
    А ты учитываешь, что обработчик прерывания имеет право выходить не по IRET, а по RETF 2? Причём retf не генерирует #GP, так что если перед вызовом прерывания в V86-стек не кладётся правильный адрес возврата, то скорее всего в 0000:0000 и вернётся, а там до исключения недалеко.
    Я, правда, не в курсе, использует ли это Bochs'овский int 10h, но в int 13h такое практикуется на каждом шагу.
     
  8. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    при правильной эмуляции INT не нужно думать, как будет происходить возврат
     
  9. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    diamond
    Разрешил все порты эффект тот же. Походу стек срывается непонимаю почему. И далее проц делает неправельные возвраты.
    А все понял.
     
  10. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    Pavia
    немного не по теме, но все же
    у тебя INT неправильно эмулируется
    семантика INT реального режима подразумевает сброс IF, TF и AC после сохранения FLAGS
    т. е
    Код (Text):
    1. ...
    2. mov Word [esp+4+8], ax            //Old EIP
    3. and DWord [esp + 3 * 3 + 8], 0FFFBFCFFh
    4. jmp @_end
    5. @a5:
     
  11. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    Pavia
    выложи образ кода и конфиг bochs
     
  12. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    rei3er
    Все понял да int неправельно эмулировался

    Код (Text):
    1. add eax,2
    2. mov Word [ebx+6], ax             // IP
    3. shr eax,16
    4. shl eax,12
    5. mov Word [ebx+4], ax             // CS
    Это бред.

    Заменил на
    Код (Text):
    1. mov ax,Word [esp+4+8]          //old eip
    2. add ax,2
    3. mov Word [ebx-6], ax             // IP
    4. mov ax,Word [esp+8+8]          //Old cs
    5. mov Word [ebx-4], ax             // CS
    Вопрос как правельно если сегмент 64битный и регистр к примеру ip и sp выходит за гроницу то что делать?
     
  13. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    rei3er
    Только Push сначало, а потом сброс флагов. Чтобы можно было востановить. А тут вопрос AC он же 18бит, а в стек кладуться только биты с 0 по 15 в чем подвох?
     
  14. rei3er

    rei3er maxim

    Публикаций:
    0
    Регистрация:
    15 янв 2007
    Сообщения:
    917
    Адрес:
    minsk
    кладутся то 16 бит, а вот после сохранения сбрасывается AC в EFLAGS
    по крайней мере так написано в спецификации на INT реального режима
    IP переполняется и становится равным >= 0
    при детекте переполнения SP генерируется #SS