проблемы с прерываниями при переходе из защищенного в реальный

Тема в разделе "WASM.ASSEMBLER", создана пользователем NeTxXx, 21 июн 2006.

  1. NeTxXx

    NeTxXx New Member

    Публикаций:
    0
    Регистрация:
    21 июн 2006
    Сообщения:
    11
    вобщем, суть в следующем:

    написал я вторичный загрузчик (в будущем), который грузится из фат-раздела по адресу 01000h и выполняет следующие операции:

    отключает прерывания, сохраняет текущие значения ss,ds,es и др. в память для возврата в реальный режим, создает дескрипторы кода (4Gb), данных (по такому же адресу что и code), стэка (фиксирован), видеопамяти (по адресу 0B8000h, размер 4000) для защищенного режима и 2 дескриптора кода и данных (16 бит, лимит 0FFFFh) для реального, настаивает gdt и загружает ее.

    потом в защищенном режиме выводит пару строк и переходит назад в реальный.

    но проблема вот в чем.. при включении прерываний уже в реальном режиме, система попросту перезагружается (если запускать на реальной машине), а если на vmware (4.05) или Bochs (2.26) то все нормально, т.е. sti включает прерывания и далее выводится строка посредством int10h

    см. строку 221 (на jmp $ не обращайте внимание )) до нее всеравно дело не доходит, это я так ловил где баг)



    я если чесно понятия не имею почему так происходит и поэтому прошу помочь.



    вот код загрузчика:
    Код (Text):
    1.  
    2. 001 format binary
    3. 002 org 0
    4. 003 include 'kboot.inc'
    5. 004 include 'pmode.inc'
    6. 005 include 'routines.inc'
    7. 006
    8. 007 code_selector   =  8
    9. 008 stack_selector  = 16
    10. 009 data_selector   = 24
    11. 010 screen_selector = 32
    12. 011 rcode_selector  = 40
    13. 012 rdata_selector  = 48
    14. 013
    15. 014 use16
    16. 015
    17. 016 start:
    18. 017     ; load segment regs, set stack
    19. 018     cli
    20. 019     mov ax,cs
    21. 020     mov ds,ax
    22. 021     mov es,ax
    23. 022     mov ss,ax
    24. 023     mov sp,stacksize
    25. 024     sti
    26. 025    
    27. 026     ; show hello msg
    28. 027     mov si, szLoaderMsg
    29. 028     call kputzs_bios
    30. 029
    31. 030     ; msg about pmode entering
    32. 031     mov si, szMsgPMEnter
    33. 032     call kputzs_bios
    34. 033    
    35. 034 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    36. 035     ; save real mode descriptors
    37. 036     mov [rmode_ss],ss
    38. 037     mov [rmode_ds],ds
    39. 038     mov [rmode_es],es
    40. 039     mov [rmode_fs],fs
    41. 040     mov [rmode_gs],gs
    42. 041    
    43. 042     ; set real mode return address
    44. 043     mov [rmode_seg],cs
    45. 044     lea ax,[rmode_entry]
    46. 045     mov [rmode_off],ax
    47. 046
    48. 047     mov bx,gdt+8 ; skip zero-descriptor
    49. 048
    50. 049     xor eax,eax
    51. 050     mov edx,eax
    52. 051
    53. 052     push cs
    54. 053     pop ax ; ax = cs = segment address of current code segment
    55. 054
    56. 055     shl eax,4 ; eax = physical address of beginning of code segment
    57. 056
    58. 057            
    59. 058     ; set limit-hi and GDXU bits
    60. 059     ; limit-hi = 0Fh (maximum), G=1 (4 kbyte pages), D=1 (32 bit),
    61. 060     ; X=0 (reserved, must be 0), U=0 (for system purposes)
    62. 061     mov dx,11001111b
    63. 062     shl edx,16 ; move them to edx-hi part
    64. 063     mov dx,0FFFFh ; set limit-low (here - maximum)
    65. 064     ; finaly we have 4Gbyte limit for code descriptor
    66. 065    
    67. 066     ; code segment access rights (P = 1,
    68. 067     ; DPL = 00b, S = 1, type = 100b, A = 0)
    69. 068     mov cl,10011000b
    70. 069
    71. 070     call gdt_set_desc ; build code descriptor
    72. 071
    73. 072     lea dx,[stack_seg_start] ; edx = dx = stack beginning
    74. 073
    75. 074     add eax,edx ; eax - beginning of code segment
    76. 075     ; set limit-hi and GDXU bits
    77. 076     ; limit-hi = 00h (zero), G=1 (4 kbyte pages), D=1 (32 bit),
    78. 077     ; X=0 (reserved, must be 0), U=0 (for system purposes)
    79. 078     mov dx,11001111b
    80. 079     shl edx,16 ; move them to edx-hi part
    81. 080     mov dx,1024 ; set limit-low (stack size)
    82. 081
    83. 082     ; stack segment access rights
    84. 083     ;  (P = 1, DPL = 00b, S = 1,
    85. 084     ;  type = 011b, A = 0).
    86. 085     mov cl,10010110b
    87. 086
    88. 087     call gdt_set_desc ; build stack descriptor
    89. 088
    90. 089     xor eax,eax ; eax = 0
    91. 090     mov ax,ds
    92. 091     shl eax,4 ; ecx = physical address of beginning of data segment
    93. 092     mov dx,11001111b ; set limit-hi and GDXU bits
    94. 093     shl edx,16
    95. 094     mov dx,0FFFFh ; limit - maximum
    96. 095     ; 4GB data segment is ready
    97. 096
    98. 097     ; data segment access rights (P = 1,
    99. 098     ;  DPL = 00b, S = 1, type = 001, A = 0).
    100. 099     mov cl,10010010b
    101. 100
    102. 101     call gdt_set_desc ; build data descriptor
    103. 102
    104. 103     mov eax,0B8000h ; physical address of videomem segment beginning
    105. 104                    
    106. 105     mov edx,4000 ; videomem segment size (80*25*2 = 4000).
    107. 106     mov cl,10010010b ; access rights (like data segment)
    108. 107     call gdt_set_desc ; build video memory segment
    109. 108
    110. 109     ; now set additional real mode selectors
    111. 110     xor eax,eax
    112. 111     mov edx,eax
    113. 112
    114. 113     push cs
    115. 114     pop ax
    116. 115
    117. 116     shl eax,4 ; eax - physical address of code segment
    118. 117
    119. 118     mov edx,0FFFFh
    120. 119     mov cl,10011010b
    121. 120     call gdt_set_desc ; rmode code
    122. 121
    123. 122     mov cl,10010010b
    124. 123     call gdt_set_desc ; rmode data
    125. 124
    126. 125
    127. 126 ; set gdtr:
    128. 127
    129. 128     xor eax,eax ; eax = 0
    130. 129     mov edx,eax ; edx = 0
    131. 130
    132. 131     mov ax,ds
    133. 132     shl eax,4 ; eax = physical address of beginning of data segment
    134. 133     lea dx,[gdt]
    135. 134     add eax,edx ; eax = physical address of gdt
    136. 135     mov [gdt_adr],eax ; save it in gdt address field
    137. 136
    138. 137     mov dx,55 ; gdt limit = 8 * (1 + 6) - 1
    139. 138     mov [gdt_lim],dx ; save it in gdtr limit field
    140. 139
    141. 140     cli ; disable interrupts
    142. 141
    143. 142     lgdt [gdtr] ; load gdtr
    144. 143    
    145. 144     mov [rmode_sp],sp ; save stack pointer at the end
    146. 145
    147. 146 ; go to pmode
    148. 147
    149. 148     mov eax,cr0
    150. 149     or al,1
    151. 150     mov cr0,eax
    152. 151
    153. 152 ; load code selector into cs register
    154. 153 ; using far jump to pmode code
    155. 154
    156. 155     jmp far code_selector:pmode_entry
    157. 156
    158. 157 ;--------------------- now we're in 32 bit PM-------------------------------
    159. 158 use32
    160. 159 pmode_entry:
    161. 160 ; cs - code segment selector
    162. 161     ; load segment registers
    163. 162     mov ax,screen_selector
    164. 163     mov es,ax
    165. 164
    166. 165     mov ax,data_selector
    167. 166     mov ds,ax
    168. 167
    169. 168     mov ax,stack_selector
    170. 169     mov ss,ax
    171. 170     mov sp,0
    172. 171
    173. 172     ; show what we are now in pmode
    174. 173     mov ebx,szMsgPM ; ds:ebx - msg pointer
    175. 174     mov edi,480 ; 3 string in video memory
    176. 175     call kputzs ; print msg from pmode
    177. 176
    178. 177     ; entering rmode
    179. 178     mov ebx,szMsgRMEnter ; ds:ebx - msg pointer
    180. 179     mov edi,640 ; 4 string in video memory
    181. 180     call kputzs ; print msg from pmode
    182. 181
    183. 182     jmp far rcode_selector:rmode_preentry
    184. 183
    185. 184 rmode_preentry:
    186. 185     mov ax,rdata_selector
    187. 186     mov ss,ax
    188. 187     mov ds,ax
    189. 188     mov es,ax
    190. 189     mov fs,ax
    191. 190     mov gs,ax
    192. 191
    193. 192     mov eax,cr0
    194. 193     and al,0FEh
    195. 194     mov cr0,eax
    196. 195
    197. 196     ; far jump to real mode
    198. 197     ; jmp far rmode_seg:rmode_off
    199. 198     db  0eah
    200. 199     rmode_off dw 0
    201. 200     rmode_seg dw 0
    202. 201
    203. 202 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    204. 203 ; ---------------------------- routines ----------------------------------
    205. 204 init_kputzs ; printing routine (uses video memory)
    206. 205 use16
    207. 206 init_gdt_set_desc ; gdt setting routine
    208. 207 init_kputzs_bios ; printing routine (uses int10)
    209. 208 init_set_curpos_bios ; setting cursor routine
    210. 209
    211. 210 ; real mode now
    212. 211 rmode_entry:
    213. 212     ; restore ss,ds,es,gs,fs
    214. 213     mov ss,[rmode_ss]
    215. 214     mov ds,[rmode_ds]
    216. 215     mov es,[rmode_es]
    217. 216     mov gs,[rmode_gs]
    218. 217     ; restore stack pointer
    219. 218     mov sp,[rmode_sp]
    220. 219
    221. 220     ; allow interrupts
    222. 221     sti
    223. 222     jmp $
    224. 223
    225. 224     ; set cursor to the 5th line
    226. 225     mov dx,0500h
    227. 226     call set_curpos_bios
    228. 227
    229. 228     mov si,szMsgRM
    230. 229     call kputzs_bios
    231. 230
    232. 231     jmp $
    233. 232
    234. 233 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    235. 234
    236. 235 ; gdt register image:
    237. 236
    238. 237 gdtr:
    239. 238 gdt_lim     dw  0
    240. 239 gdt_adr     dd  0
    241. 240 ;----------------------------------------------------------------- ---------
    242. 241 gdt:
    243. 242     dd  0,0 ; 0 descriptor
    244. 243     dd  0,0 ; 1 descriptor (code)
    245. 244     dd  0,0 ; 2 descriptor (stack)
    246. 245     dd  0,0 ; 3 descriptor (data)
    247. 246     dd  0,0 ; 4 descriptor (videomem)
    248. 247     dd  0,0 ; 5 descriptor (realm code)
    249. 248     dd  0,0 ; 6 descriptor (realm data)
    250. 249 real:
    251. 250 rmode_sp    dw 0
    252. 251 rmode_ss    dw 0
    253. 252 rmode_ds    dw 0
    254. 253 rmode_es    dw 0
    255. 254 rmode_fs    dw 0
    256. 255 rmode_gs    dw 0
    257. 256
    258. 257 szLoaderMsg db 'HELLO FROM KLOADER!!',13,10,0
    259. 258 szMsgPMEnter    db 'ENTERING PMODE...',13,10,0
    260. 259 szMsgRM     db 'IN 16 BIT UNREAL MODE NOW!',13,10,0
    261. 260
    262. 261
    263. 262 ;----------------------------------------------------------------- ---------
    264. 263
    265. 264 szMsgPM     db 'IN 32 BIT PMODE NOW!',0
    266. 265 szMsgRMEnter    db 'ENTERING RMODE...',0
    267. 266
    268. 267
    269. 268 times 1024  db 0    ; reserved for stack
    270. 269 stack_seg_start:    ; stack beginning
    271.  




    вот код процедуры создания дескрипторов gdt_set_desc:
    Код (Text):
    1.  
    2. 001 ; gdt descriptor setting subroutine
    3. 002
    4. 003 ; creates descriptor
    5. 004 ; DS:BX = descriptor in gdt  
    6. 005 ; EAX = segment address
    7. 006 ; EDX = segment limit
    8. 007 ; CL = access rights byte                      
    9. 008 macro init_gdt_set_desc {
    10. 009 gdt_set_desc:              
    11. 010
    12. 011     push eax ecx edx ; we use eax, ecx, edx
    13. 012
    14. 013
    15. 014     push cx ; temporary save access rights
    16. 015
    17. 016     mov cx,ax ; copy lower part of address to cx,
    18. 017     shl ecx,16 ; and shift it to higher part
    19. 018
    20. 019     ; copy lower part of limit to cx
    21. 020     ;  now ecx contains lower part of
    22. 021     ;  the descriptor
    23. 022     mov cx,dx
    24. 023
    25. 024     mov [bx],ecx ; write lower part of descriptor to gdt
    26. 025
    27. 026     shr eax,16 ; now shift higher part of address to lower (ax)
    28. 027
    29. 028     mov ch,ah ; address bits 24 - 31
    30. 029     shr edx,16 ; working with higher part of limit (limit hi+GDXU)
    31. 030     mov cl,dl ; limit bits 16-19 + GDXU
    32.  
    33. 031     shl ecx,16 ; shift it to higher part of ecx
    34. 032     mov cl,al ; and address bits 16 - 23 - lower byte
    35. 033
    36. 034     pop ax ; restore access rights to ax
    37. 035     ; and copy them into the second byte (of 4 available)
    38. 036     ; of ecx
    39. 037     mov ch,al
    40. 038
    41. 039     ; write the second part of
    42. 040     ; descriptor into gdt
    43. 041     mov [bx+4],ecx
    44. 042
    45. 043     add bx,8 ; move gdt poiner to next descriptor
    46. 044     pop edx ecx eax
    47. 045 ret
    48. 046 }
    49. 047
    50.  


    выкладываю полный исходник+образ дискеты на всякий случай

    буду очень благодарен за помощь

    заранее спасибо

    [​IMG] _744065779__lowexp_b.zip
     
  2. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    Я не вполне уверен, но, возможно, стоит попробовать поточнее восстановить DS после перехода обратно в RealMode. Вот как это сделано у Финогенова:



    ; turn back DOS media

    return: mov ax,data

    mov ds,ax

    mov ax,stk

    mov ss,ax

    mov sp,256

    mov ss,real_ss

    ;interrupt on



    Это пример из стартующего DOS'овского экзешника, те "mov ax,data" - это загрузка константы. Можно попробовать эту команду править (т.е. модифицировать код - значение, которое нужно восстановить - в команде mov ax,<Value_DS>
     
  3. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    NeTxXx

    Господин Хакер, вы по тегах кода слышали?



    Вернее когда их стоит, а когда нестоит применять?
     
  4. NeTxXx

    NeTxXx New Member

    Публикаций:
    0
    Регистрация:
    21 июн 2006
    Сообщения:
    11
    Chingachguk

    хмм.. очень интересная весчь получается.. когда уже

    в реальном режиме записать в ds ноль, халта системы не происходит.. но сообщение не выводится (адрес не тот).. когда пишу в ds реальный адрес, по которому загружается вторичный загрузчик (т.е. значение cs), происходит сброс системы на sti..

    интересно почему так?
     
  5. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    NeTxXx



    Кажется, у Финогенова было сказано примерно следующее: ~"после перехода в RM из PM в теневых полях селекторов остаются прежние значения и это некоторое время позволяет работать с ними..." Ну или что-то в этом роде (дома поточнее посмотрю - понимаю, что написал пургу). Попробуй туда не CS писать, а константу типа 0 (или валидный адрес вбивай прямо в команду его загрузки еще до перехода в PM).
     
  6. PROFi

    PROFi New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2003
    Сообщения:
    690
    Есть проблема - между строками 145 - 146 должен быть код который разрешает использование A20 разряда адреса. Обычно через порты клавиатуры. Если машина на которой ты работаешь - реально совместима с IBM, то это необходимо делать до перехода в зашищенный режим, иначе физические адреса будут вырабатываться неправильно.
     
  7. PROFi

    PROFi New Member

    Публикаций:
    0
    Регистрация:
    13 июл 2003
    Сообщения:
    690
    Воторой момент:

    выводится строка посредством int10h в защищеном режиме не все VideoBIOS поддерживают вывод через int 10, а реальном во многих биосах (материнки) есть ошибки, и потому они зачастую тоже неправильно обрабатывают int 10 даже в реальном режиме, до загрузки DOS например. А потому kputzs_bios: не универсальна.
     
  8. sergh

    sergh New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2005
    Сообщения:
    128
    Адрес:
    rsdn
    Зачем же так жестоко GDT формировать? Неужели нельзя было определить структуру для дескриптора, с нормальными полями, прописать большую часть собержимого дескрипторов (все флаги, все длины) просто в данных, а в коде устанавливать только базовый адрес? Сделать структуру для GDTR, заполнять поле limit автоматически.. Это я к тому что, сейчас проверять твой код, заполняющий GDT очень сложно, я думаю даже тебе. Так что если баг там, то вряд ли его кто-то обнаружит.



    Да, вот мой вариант структур и таблицы, вдруг тебе понравится:


    Код (Text):
    1.  
    2. ; Дескриптор
    3. segment_descriptor struct
    4.     limit_low   dw      0    ; Младшие два байта поля Segment limit
    5.     base_low    dw      0    ; Младшие два байта поля Base Address
    6.     base_high0  db      0    ; Второй байт поля Base Address
    7.     type_and_permit db  0    ; Флаги.
    8.     flags       db      0    ; Ещё одни флаги
    9.     base_high1  db      0    ; Старший байт поля Base Address
    10. segment_descriptor ends
    11.  
    12. ; GDTR
    13. table_register struct
    14.     limit   dw  0    ; Table Limit
    15.     base    dd  0    ; Linear Base Address
    16. table_register ends
    17.  
    18. ; А так это выглядит в области данных:
    19. ; Глобальная таблица дескрипторов
    20. GDT     label   byte
    21.         ; Нулевой дескриптор
    22.         segment_descriptor <>
    23.         ; Дескриптор сегмента кода, размер 4 Gb
    24.         segment_descriptor <0ffffh, 0, 0, 10011010b, 10001111b, 0>
    25.                 ; 10011010b - 1001, C/D - 1, 0, R/W - 1, 0
    26.                 ; 10001111b - G - 1, 000, Limit - 1111
    27.            
    28.         ; Дескриптор сегмента кода, размер 64 Kb
    29. dsc64kb segment_descriptor <0ffffh, 0, 0, 10011010b, 0, 0>
    30.                 ; 10011010b - 1001, C/D - 1, 0, R/W - 1, 0
    31.                 ; 0         - G - 0, 000, Limit - 0
    32.                
    33. ; Данные для загрузки в GDTR
    34. gdtr    table_register <$ - GDT - 1, 0>
    35.  




    dsc64kb нужно чтобы из кода нормально установить базовый адрес дескриптора.
     
  9. sergh

    sergh New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2005
    Сообщения:
    128
    Адрес:
    rsdn
    Да, сообщение выше - это что-то типа брюзжания в обще педагогических целях :) Теперь по делу. Имхо, сама по себе команда sti не может рнять машину, так как она просто устанавливает флаг, машину роняет вызов обработчика прерывания или сам обработчик, или возврат из него. Например таймера, или ещё какой-нибудь.



    Вызов может ронять в двух случаях:

    - если в таблице прерываний кривой адрес. Например, если ты её где-то портишь.

    - если у нас проблемы со стеком

    Сам обработчик может ронять, если у него кривой код. Опять же, для этого нужно испортить либо адрес, либо код.

    Возврат из обработчика может ронять систему, если текущее значение CS не соответствует реальности. Например, мы сменили режим, а CS остался от старого режима. При этом всё более менее работает, но вот при возврате из прерывания и восстановлении адреса из стека, CS будет трактоваться как CS текущего режима. Со всеми вытекающими.



    С CS у тебя вроде всё впорядке, память ты вроде не портишь, остаётся стек. Проверить очень просто - не менять значение SS и SP при переходе между режимами, ни при переходе туда, ни при переходе обратно. Если заработает, значит именно тут собака и порылась. Если нет, нужно думать дальше.
     
  10. NeTxXx

    NeTxXx New Member

    Публикаций:
    0
    Регистрация:
    21 июн 2006
    Сообщения:
    11
    sergh

    Надо же! вы правы Ж) действительно дело в стеке..

    закомментил след. строчки: 168-170,186,213,218

    запустил на реальной тачке.. все ок )

    странно, а что тогда со стеком? может не стоит для него отдельный селектор делать? а если так, то как лучше тогда его оформить (ss)?



    а на счет статических GDT и селекторов: в том то и дело что мне нужно будет создавать их динамически.. позже сделаю побольше всю GDT и тогда можно уже будет штамповать новые селекторы "налету" :)

    в любом случае спасибо за советы.

    PROFi

    на счет A20 я знаю.. просто второпях код постил.. щас все ок..

    а на счет kputzs_bios все норма.. по крайней мере в unreal mode она работает ок.. как и в real
     
  11. NeTxXx

    NeTxXx New Member

    Публикаций:
    0
    Регистрация:
    21 июн 2006
    Сообщения:
    11
    я тут еще раз поэкспериментировал и...

    вот такая весчъ получается:

    когда я не стал создавать отдельный селектор под стек, а записал в ss селектор для ds (это все в pmode вначале - стр.165), а после как и раньше загрузил ss селектором realmode данных (185), то все стало ок..



    но ведь стек растет вниз? а значит когда я загрузил ss селектором для ds ничего плохого не произойдет потом? фактически, ds расположен по адресу 01000h - сюда грузится вторичный загрузчик.
     
  12. sergh

    sergh New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2005
    Сообщения:
    128
    Адрес:
    rsdn
    NeTxXx

    Как лучше оформить - смотря что от него нужно. Если тебе нужно просто unreal mode получить, то лучше вообще его не трогать, так же как и cs кстати. А вот если действительно планируешь в защищённом режиме работать, моежет быть нужен отдельный дескриптор и селектор.



    Что именно плохо со стеком - не знаю, просто методем исключения вычислил :) Попробуй упростить программу - например, для начала, сделать статические дескрипторы :) Убрать лишнее, ну и т.п. Или наоборот, взять простой, но работающий вариант, и постепенно довести его до нужного тебе функционала.
     
  13. sergh

    sergh New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2005
    Сообщения:
    128
    Адрес:
    rsdn
    NeTxXx

    Во-первых, то, какой селектор/дескриптор у стека был в PM не может никак влиять на поведение стека после переключения режимов и перезаписи значения SS. Во всяком случае, я не вижу никаких механизмов влияния. Так что единственное, что приходит в голову - портится сохранянное значение SS и SP. Посмотри ещё раз свой алгоритм формирования GDT, я понимаю, что всё время в одну точку долблю, но просто это самая запутанная часть программы.



    Во-вторях, можно совместить с даными, если размера хватает, ничего плохого не случится. Защищённый режим конечно отличается от реального, но всё-таки не слишком сильно.
     
  14. sergh

    sergh New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2005
    Сообщения:
    128
    Адрес:
    rsdn
    Кстати, а как в итоге выглядит дескриптор стека в оригинальной программе?
     
  15. sergh

    sergh New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2005
    Сообщения:
    128
    Адрес:
    rsdn
    Гм, разобрался вроде с тем как ты дескрипторы генеришь, всё не так страшно. Сделай стеку type 001, а не 011, после этого глядишь и заработает.



    С дескрипторами с типом 011 нужно не так обращаться, почитай документацию внимательно. А лучше их вообще не использовать.
     
  16. NeTxXx

    NeTxXx New Member

    Публикаций:
    0
    Регистрация:
    21 июн 2006
    Сообщения:
    11
    sergh

    все ок. спасибо. от отдельного дескриптора стека я вообще пока отказался. загружаю его дескриптором от сегмента данных.