· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.ASSEMBLER —› Перезагрузка при переходе в защищенный режим.

Посл.отвђт Сообщенiе


Дата: Апр 22, 2004 15:26:58

Доброго времени суток.
Пытаюсь написать что нибудь работающее под защищенный режим. Но не могу в него попасть. :(
Вроде старался все делать по статьям Сломаного Меча.
Помогите определить в чем я ошибся.
И еще вопрос - не у Сворда ни в Абеле не рассчитываеться размер лимита. там просто ставят 0fffffh. Как это сделать? И надо ли это делать? (мне кажеться что надо...)
.386p

RM_STACK segment stack 'STACK' use32
       db       100h dup(?)
RM_STACK       ends

DATA_S segment 'DATA' use32
GDT:  

NULL_descr	db	8 dup	(0)
CODE_descr	db	0FFh,0FFh,00h,00h,00h,10011010b,11001111b,00h
;base 00 00 00 00; limit f ff ff; type: code er; DPL: 0; P:1; G=1; S=1 (data/cod);
DATA_descr	db	0FFh,0FFh,00h,00h,00h,10010010b,11001111b,00h
;base 00 00 00 00; limit f ff ff; type: data rw; DPL: 0; P:1; G=1; S=1 (data/cod);
VIDEO_descr db  0FFh,0FFh,00h,80h,0Bh,10010010b,01000000b,00h
;base 00 0b 80 00; limit 0 ff ff; type: data rw; DPL: 0; P:1; G=0; S=1 (data/cod);
GDT_size	equ	$-GDT

GDTR 		dw GDT_size-1
			dd	?

DATA_S ends



RM_CODE segment para public 'CODE' use32
assume CS:RM_CODE,SS:RM_STACK,DS:DATA_S
start:

;prepare basees of code and data descr
                
mov ax,DATA_S
mov ds,ax
shl eax,4
or dword ptr DATA_descr+2,eax


mov ax,seg PM_CODE
shl eax,4
or dword ptr CODE_descr+2,eax

;write enter point to protected mode
xor EAX,EAX
mov AX,PM_CODE
shl EAX,4
add EAX,offset ENTRY_POINT
mov dword ptr ENTRY_OFF,EAX


xor EAX,EAX
mov AX,DATA_S; 
shl EAX,4; 
add AX,offset GDT

mov dword ptr GDTR+2,EAX
lgdt fword ptr GDTR

cli

in AL,70h
or AL,80h
out 70h,AL


mov EAX,CR0
or AL,1
mov CR0,EAX ;перезагрузка


			db 66h
			db 0EAh
ENTRY_OFF	dd	?
			dw 00001000b

RM_CODE     ends


PM_CODE segment para public 'CODE' use32
assume CS:PM_CODE,DS:DATA_S
ENTRY_POINT:

mov AX,00010000b                
mov DS,AX                       
mov AX,00011000b               
mov ES,AX                       
PM_CODE    	    ends

end start


С уважением. Ворон


Дата: Апр 22, 2004 18:52:33

Raven
Перед инструкциями mov ax,DATA_S и mov ax,seg PM_CODE поставь xor eax,eax , чтобы обнулить регистр eax. Это из-за того, что старшие 16 бит его совсем не обязаны быть нулевыми. К тому же, допустим у тебя вначале 16-31 биты равны нулю. После того как ты сделал shl eax,4 у тебя биты 16-23 уже ненулевые. Так что перед mov ax,seg PM_CODE надо-бы обнулять регистр eax (делать xor eax,eax).

PS: Кстати говоря, совсем необязательно после перехода в защищенный режим делать безусловный переход (я так понял ты его делаешь (db 66h db 0eah ...)). И вообще необязательно инициализировать CS и SS(если конечно не используешь стек). Это в документации так пишут, что делайте безусловный переход. На самом же деле и без него все работает и так даже проще. Его надо делать если нужна инициалазация регистра CS.


Дата: Апр 22, 2004 19:09:12

2Icebp:
Спасибо. Уже исправил. (xor eax,eax)
Про необходимость дальнего джампа - а как без него перейти в сегмент кода для защищенного режима ?

Так или иначе это ничего не решило. Программа упорно перезагружает компьютер... Подскажите пожалуста возможную причину...


Дата: Апр 22, 2004 20:08:45

Raven
Я тут недавно одному человеку писал программу (на FASM-е) для перехода в защищенный режим с комментариями. Посмотри как я обычно делаю переход в защищенный режим и выход из него. Может этот исходник тебе поможет. У тебя перезагружает компьютер по моему мнению (у меня давно как то тоже такое было) из-за того, что ты не выходишь из защищенного режима. Подумай что будет после инструкций mov 00011000b mov es,ax. Я думаю, что после них выполняется какая-то хрень из области памяти после программы, которая приводит к перезагрузке. Если не хочешь выходить в конце из защищенного режима, то можешь сделать так: zavison: jmp zavison. Тогда у тебя вместо перезагрузки комп просто зависнет в защищенном режиме (если это будет так, то я был прав, нажми после этого RESET, так как CTRL-ALT-DEL не поможет).

1403134348__protmode.asm


Дата: Апр 23, 2004 21:40:05

Грусно. Ничем не лечиться.
Сократил программу до запрещения прерываний, перехода в защищенный режим.
Все равно перегружает машину. В чем может быть дело???


Дата: Апр 24, 2004 09:26:57 · Поправил: Black_mirror

RM_CODE segment para public 'CODE' use32 - тут случайно не use16 должно стоять? 


Дата: Апр 24, 2004 11:39:45

Вот моя прога для перехода в РМ с комментариями.
Может тебе это поможет понять что-то.


;программа иллюстрирует работу с 32 и 16 разрядными сегментами кода в РМ

.386p
mypm2 segment use16

begin:
;открыть линию А-20 -для работы с 1МБ+
in al,92h
or al,10b
out 92h,al


xor eax,eax
mov ax,cs
mov ds,ax
mov word ptr CORR,ax ;когда вернёмся из РМ мы используем это для сброса очереди
;команд-иначе не работает
shl eax,4 ;теперь еах содержит физический адрес сегмента кода
mov ecx,eax ;сохраним его


;загрузим регистр GDTR
add eax,offset GDT ;в еах -физ. адрес таблицы ГДТ
mov dword ptr GDTR_+2,eax
mov word ptr GDTR_,31
lgdt fword ptr GDTR_ ;загрузим регистр GDTR

mov eax,ecx
add eax,offset backup ;куда прыгать из 32-битного сегмента кода
mov dword ptr getto,eax



mov eax,ecx
add eax,offset code32 ;смещение 32х битного кода
mov dword ptr goi,eax ;мы прыгнем сюда из 16-битного сегмента


;переключение в PM
cli ;тормозим прерывания
in al,70h
or al,80h
out 70h,al

mov eax,cr0
or eax,1
mov cr0,eax ;мы в РМ!!!!!!!!!!!!!!!!

;ВАЖНО-хотя CS содержит глупости(из RM) проц на это не смотрит.
;он (проц) работает со значением из теневой части CS

;переходим в 32х битную зону
db 066h
db 0eah
goi dd 0 ;здесь мы сохранили адрес code32
dw 10000b ;переход на сегмент с базой в нуле и смещением в code32



code32:

mov eax,011000b ;можно загрузить DS-и поработать с данными
mov ds,ax

db 0eah ;прыгаем в 16-разрядный(=битный)сегмент
getto dd 0 ;это необходимо,т.к. если перейти назад в реал
dw 01000b ;сейчас то ДОС работать не будет-(во всяком случае у меня не работала)
; это связано с тем,что в теневом дескрипторе сегмент будет описан как 32х битный

GDT:
db 8 dup (0)
db 0ffh,0ffh,0,0,0,10011010b,10001111b,0 ;16-bit code
db 0ffh,0ffh,0,0,0,10011010b,11001111b,0 ;32-bit code
db 0ffh,0ffh,0,0,0,10010010b,11001111b,0 ;32-bit data
GDTR_ db 6 dup (0)

backup: ;сейчас мы в 16и битном режиме
mov eax,cr0 ;можно переключаться в реал
and al,0feh
mov cr0,eax

DB 0EAH ;сброс очериди команд-без этого не работает
DW $+4
CORR DW 0

in al,70h ;восстановить работу прерываний
and al,7fh
out 70h,al

sti

mov ah,0 ;подождать нажатия клавиши
int 16h

mov ah,4ch ;...и выйти
int 21h

mypm2 ends

end begin


Дата: Апр 24, 2004 12:16:01

Размер лимита и база.Я тоже долго не мог въехать как считается эти лимит и база,как он записывается-слева направа или наоборот.

Важно(меня во вяком случае это долго путало)-
запись битов.В байте самый маленький бит
(по арифметическому значению)нулевой-крайний правый при традиционной записи (00100011b).Седьмой бит-крайний левый.


Лимит.Если бит гранулярности (бит 8 байта 6)=0 то
лимит равен тому чему он равен ;)(без изменений),если
бит гранулярности =1 то лимит умножаем на 1000H (4K).
Т.е. если бит Г. =0 то лимит от 0 и до 0fffffh (1048575).
Если бит Г. =1 то лимит от 0*1000h и до 0fffffh*1000h(4GB). Запись в дескрипторе интеловская(а какая ж ещё?)-т.е. "не по человечески"-наоборот- лимит в 345567 байт (545dfh) пишем в дескрипторе так-
0dfh,45h,xxh,xxh,xxh,xxh,x5h,xxh
где байт 0dfh в памяти имеет номер Z ,а байт x5h- Z+6.
Вроде бы всё безошибок,хотя проверить не мешает.


Дата: Апр 24, 2004 20:49:58

На мой взгляд, главное при написании первых программ с защищенным режимом - это не полениться написать обработчики исключений. В них нужно вывести номер исключения и crash-адрес с несколькими байтами. Часто бывает, что (например) должно зваться одно исключение, но неверный дескриптор стека составлен и возникает исключение 0D и прога нифига не понятно почему тухнет.

В качестве примера кидаюсь своим исходником (по книге Финогенова) - в ней обрабатывается исключение:
.386p
;
; Common structures
;
descr struc
  lim    dw  0
  base_l dw  0
  base_m db  0
  attr_1 db  0
  attr_2 db  0
  base_h db  0
descr ends
trap  struc
  offs1  dw  0
  sel    dw  16
  rsrv  db  0
  attr_  db  8fh
  offs_h dw  0
trap  ends
intr struc
  ioffs_l  dw  0
  isel    dw  16
  irsrv    db  0
  iattr    db  8eh
  ioffs_h  dw  0
intr ends
data segment use16
gdt_0 label word
; GDT table
code_alias_sel equ 64
gdt_null  descr <0,0,0,0,0,0> ; 0
gdt_data  descr <data_size-1,0,0,92h,0,0> ; 8
gdt_code  descr <code_size-1,0,0,98h,0,0> ; 16
gdt_stack  descr <255,0,0,92h,0,0>        ; 24
gdt_screen descr <4095,8000h,0bh,92h,0,0>  ; 32
gdt_himem  descr <1023,0,10h,92h,80h>      ; 40
gdt_tss_0  descr <103,0,0,89h>            ; 48
gdt_tss_1  descr <103,0,0,89h>            ; 56
gdt_code_alias descr <code_size-1,0,0,92h,0,0> ; 64
gdt_size= $-gdt_null
idt    label  word
trap  <exc_0>
trap  <exc_1>
trap  <exc_2>
trap  <exc_3>
trap  <exc_4>
trap  <exc_5>
trap  <exc_6>
trap  <exc_7>
trap  <exc_8>
trap  <exc_9>
trap  <exc_10>
trap  <exc_11>
trap  <exc_12>
trap  <exc_13>
trap  <exc_14>
trap  <exc_15>
trap  16 dup(<exc_test>)
intr  <new_08>
intr  <new_09>
idt_size=$-idt
pdescr  dq  0
save_sp  dw  0
save_ss  dw  0
save_ds  dw  0
save_es  dw  0
count    db  0
sec      dw  0
place    dw  0
sym      db  24
testt    db  0
kode    db  ?
attr    db  1eh
tabl    db  '0123456789'
TabHex  db '0123456789ABCDEF'
ExitMsg  db  'We are in DOS',13,10
ExitMsgLen equ $-ExitMsg
tss_0    db  104 dup(0)
tss_1    db  104 dup(0)
task1_offs dw  0
task1_sel  dw  56
TrapMsg    db 'trap (xxxx) raising !',0
TrapMsg0  db 'CS:IP-> xxxx bytes. Skip 2 bytes...',0
Trap1Msg  db '#1 trap raising !',0
KeyPressed db 'Key: xxxx',0
TimeMsg    db 'Time: xxxx',0
data_size equ $-gdt_null
data ends
text segment 'code' use16
assume cs:text,ds:data
begin label word
OutTrapMsg proc
  pushad
  ; ax= num trap
  mov  di,offset TrapMsg+6
  call HexWord_String
  push 10*160
  push offset TrapMsg
  call Out_String
  popad
  ret
OutTrapMsg endp
exc_0 proc
  push ebp
  mov  ebp,esp
  pushad
  push gs
  mov  ax,0
  call OutTrapMsg
  mov  ax,code_alias_sel
  mov  gs,ax
  mov  eax,[ebp+4]
  mov  ax,gs:[eax]
  ; ax= CS:EIP->
  mov  di,offset TrapMsg0+8
  call HexWord_String
  push 6*160
  push offset TrapMsg0
  call Out_String
@@Skip:
  add  dword ptr [ebp+4],2 ; change eip
  pop  gs
  popad
  pop  ebp
  db  66h
  iret
exc_0 endp
exc_1 proc
  mov  ax,1
  call OutTrapMsg
  db  66h
  iret
exc_1 endp
exc_2 proc
  mov ax,2
  call OutTrapMsg
  db 66h
  iret
exc_2 endp
exc_3 proc
  mov ax,3
  call OutTrapMsg
  db 66h
  iret
exc_3 endp
exc_4 proc
  mov  ax,4
  call OutTrapMsg
  db 66h
  iret
exc_4 endp
exc_5 proc
  mov ax,5
  call OutTrapMsg
  db 66h
  iret
exc_5 endp
exc_6 proc
  mov ax,6
  call OutTrapMsg
  db 66h
  iret
exc_6 endp
exc_7 proc
  mov ax,7
  call OutTrapMsg
  db 66h
  iret
exc_7 endp
exc_8 proc
  mov ax,8
  call OutTrapMsg
  db 66h
  iret
exc_8 endp
exc_9 proc
  mov ax,9
  call OutTrapMsg
  db 66h
  iret
exc_9 endp
exc_10 proc
  mov ax,10
  call OutTrapMsg
  db 66h
  iret
exc_10 endp
exc_11 proc
  mov ax,11
  call OutTrapMsg
  db 66h
  iret
exc_11 endp
exc_12 proc
  mov ax,12
  call OutTrapMsg
  db 66h
  iret
exc_12 endp
exc_13 proc
  mov ax,13
  call OutTrapMsg
  db 66h
  iret
exc_13 endp
exc_14 proc
  mov ax,14
  call OutTrapMsg
  db 66h
  iret
exc_14 endp
exc_15 proc
  mov ax,15
  call OutTrapMsg
  db 66h
  iret
exc_15 endp
exc_test proc
  mov ax,666
  mov gs:[0],ax
  mov place,800
  db 66h
  iret
exc_test endp
new_08 proc
  inc count
  cmp count,18
  jbe NO_time
  cli
  mov count,0
  inc sec
  mov ax,sec
  ; ax= time
  mov  di,offset TimeMsg+6
  call HexWord_String
  push 12*160
  push offset TimeMsg
  call Out_String
  sti
NO_time:
  mov al,20h
  out 20h,al
  db 66h
  iret
new_08 endp
new_09 proc
  cli
  in  al,60h
  mov kode,al
  xor ah,ah
  ; ax= key
  mov  di,offset KeyPressed+5
  call HexWord_String
  push 14*160
  push offset KeyPressed
  call Out_String
  sti
  in  al,61h
  or  al,80h
  out 61h,al
  and al,7fh
  out 61h,al
  mov al,20h
  out 20h,al
  db  66h
  iret
new_09 endp
main proc
    mov  ax,0003h
    int  10h
    xor  eax,eax
    mov  ax,data
    mov  ds,ax
; save critical registers
    mov  save_ds,ds
    mov  save_es,es
    mov  save_ss,ss
    mov  save_sp,sp

; calculate liner address of data segment
    shl  eax,4
    mov  ebp,eax
    mov  bx,offset gdt_data
    mov  [bx].base_l,ax
    rol  eax,16
    mov  [bx].base_m,al
; and command segment
    xor  eax,eax
    mov  ax,cs
    shl  eax,4
    mov  bx,offset gdt_code
    mov  [bx].base_l,ax
    rol  eax,16
    mov  [bx].base_m,al
; and alias for command segment
    xor  eax,eax
    mov  ax,cs
    shl  eax,4
    mov  bx,offset gdt_code_alias
    mov  [bx].base_l,ax
    rol  eax,16
    mov  [bx].base_m,al
; and stack segment
    xor  eax,eax
    mov  ax,ss
    shl  eax,4
    mov  bx,offset gdt_stack
    mov  [bx].base_l,ax
    rol  eax,16
    mov  [bx].base_m,al
;  tss_0
    mov  eax,ebp
    add  ax,offset tss_0
    mov  bx,offset gdt_tss_0
    mov  [bx].base_l,ax
    rol  eax,16
    mov  [bx].base_m,al
;  tss_1
    mov  eax,ebp
    add  ax,offset tss_1
    mov  bx,offset gdt_tss_1
    mov  [bx].base_l,ax
    rol  eax,16
    mov  [bx].base_m,al
; prepare psevdodescriptor
    mov  dword ptr pdescr+2,ebp
    mov  word ptr pdescr,gdt_size-1
    lgdt pdescr
    push ebp
;
    cli
    mov  word ptr tss_1+4ch,16
    mov  word ptr tss_1+20h,offset himem
    mov  word ptr tss_1+50h,24
    mov  word ptr tss_1+38h,128
    mov  word ptr tss_1+54h,8
    mov  word ptr tss_1+48h,32
;fuck off all interrupts
    cli
    mov  al,8fh
    out  70h,al  ;NMI off
    jmp  $+2    ;stop little bit
    mov  al,05h
    out  71h,al
    mov  ax,40h
    mov  es,ax
    mov  word ptr es:[67h],offset return
    mov  word ptr es:[69h],cs
;change controller regim
    mov dx,20h
    mov al,11h
    out dx,al
    jmp $+2
    inc dx
    mov al,20h
    out dx,al
    jmp $+2 
    mov al,4
    out dx,al
    jmp $+2
    mov al,1
    out dx,al
    mov al,0fch
    out dx,al
    mov dx,0a1h
    mov al,0ffh
    out dx,al    
;load idtr table
    pop  ebp
    mov  word ptr pdescr,idt_size-1
    xor  eax,eax
    mov  ax,offset idt
    add  eax,ebp
    mov  dword ptr pdescr+2,eax
    lidt pdescr    
    mov  al,0d1h
    out  64h,al
    mov  al,0deh
    out  60h,al
; set the processor regim
    mov  eax,cr0  ;get mashine word
    or  eax,1    ;set PE bit
    mov  cr0,eax  ;load mashine word
; load cs:ip
    db      0eah    ;jmp far
    dw      offset continue
    dw      16      ;command selector
continue:
    mov  ax,8
    mov  ds,ax
    mov  ax,24
    mov  ss,ax
    mov  ax,32 
    mov  es,ax
    mov  ax,40 ;massive selector
    mov  gs,ax
; Interrupts
    mov  al,0dh
    out  70h,al
    sti
;
    mov  ax,48
    ltr  ax
;
; Waiting for filler
;
@@MainLoop:
    cmp  kode,130
    jb  @@NoNumKey
    cmp  kode,139
    ja  @@NoNumKey
; Try to make exception #key
    mov  al,kode
    sub  al,130
    cmp  al,0
    jnz  @@NoExept0
    xor  bx,bx
    div  bx
    jmp  @@ExeptsDone
@@NoExept0:

@@ExeptsDone:

@@NoNumKey:
    cmp  kode,57
    jnz  @@MainLoop
; line A20 close
    mov  al,0d1h
    out  64h,al
    mov  al,0ddh
    out  60h,al
;
    mov  al,0feh
    out  64h,al
    hlt
; turn back DOS media
return:
    mov  ax,data
    mov  ds,ax
    mov  ax,stk
    mov  ss,ax
    mov  sp,save_sp
    mov  es,save_es
;interrupt on
    mov  al,0B8h
    out  21h,al
    mov  al,9Dh
    out  0a1h,al
    mov  al,0
    out  70h,al  ;NMI on
    sti
; dos message
    mov  ah,40h
    mov  bx,01
    mov  cx,ExitMsgLen
    mov  dx,offset ExitMsg
    int  21h
Exit:
    mov  ax,4c00h
    int  21h    
main endp
himem proc
  pusha
  mov  ax,32
  mov  es,ax
  mov  ax,40
  mov  gs,ax
  xor  ebx,ebx
  mov  cx,gs:[ebx]
  mov  di,10000
  mov  bx,place
  mov  testt,0
@1:
  mov  ax,cx
  xor  dx,dx
  div  di
  mov  si,ax
  mov  dl,testt
  and  dx,1
  cmp  dx,1
  je  Good
  cmp  ax,0
  je  Ziro
Good:
  mov testt,1
  mov  al,tabl[si]
  mov  ah,13h
  mov  es:[bx],ax
Ziro:
  add  bx,2
  mov  ax,di
  mul  si
  sub  cx,ax
  mov  ax,di
  xor  dx,dx
  mov  si,10
  div  si
  mov  di,ax
  cmp  di,1
  jae  @1
  popa
  iret
  jmp  himem
himem endp
Out_String proc near
  push bp
  cli
  mov  bp,sp
  pushad
  push es
  mov  ax,32
  mov  es,ax
  mov  si,[bp+4]
  mov  di,[bp+6]
  mov  ah,14
  cld
@@OutString:
  lodsb
  test al,al
  jz  @@OutStringDone
  stosw
  jmp  @@OutString
@@OutStringDone:
  pop  es
  popad
  pop  bp
  sti
  retn 4
Out_String endp
HexWord_String proc near
  pusha
  push  es
  push  ds
  pop  es
  cld
  mov  bx,offset TabHex
  mov  cx,4
@@HexWordStr:
  rol  ax,4
  push  ax
  and  al,0Fh
  xlat
  stosb
  pop  ax
  loop  @@HexWordStr
  pop  es
  popa
  retn
HexWord_String endp
Hex_String proc near
  pusha
  push  es
  test  cx,cx
  jz    @@ExitHexStr
  cld
  mov  bx,offset TabHex
  push  ds
  pop  es
@@HexStr:
  lodsb
  mov  ah,al
  shr  al,4
  xlat
  stosb
  mov  al,ah
  and  al,0Fh
  xlat
  stosb
  loop  @@HexStr
@@ExitHexStr:
  pop  es
  popa
  retn
Hex_String endp
code_size= $-begin
    text ends
stk segment  stack 'stack'
    db 256 dup('~')
stk ends
end main


Дата: Апр 24, 2004 21:03:18

[офтоп]
Ухххх!!! :))) надо было приаатачить его %)))
[/офтоп]


Дата: Май 2, 2004 03:10:50 · Поправил: getoff

RM_CODE segment para public 'CODE' use32 - тут случайно не use16 должно стоять?

use32 вызывает по крайней мере 2 типа ошибок в данном коде:
1. При вычислении адресов подставляються части 32х битного адреса
2. при прыганьи на PM код, ты изпользуешь префикс изменения разрядности адреса (db 66h), и потом прыгаешь в защищенном (уже) режиме по 16-битному(теперь) адресу.

совокупность этого приводит к тому, что проц начинает исполнять совершенно левый код, который почти сразуже приведет к исключению -> resetу.


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.062