Пример перехода в защищенный режим
Кому не сложно накидайте примерчик пожалуйста. Должна быть COM программа без всяких там сегментов данных, кода и т.д. Адрес по которому грузиться прога заранее не известен.Нашел несколько примеров но там сегмент в который грузиться программа известен заранее =(
Код:
org 100h
.start32:
mov ax,3
int 10h
; Загрузим значение в GDTR
xor ax,ax
mov ax,cs
mov ds,ax
shl eax,4
add [addr],eax
add [jadr],eax
; add [adr],ax
lgdt fword [gdtr32]
in al, 0x92;включаем A20
or al, 2
out 0x92, al
cli ;запрещаем прерывания
mov al,8Fh;запрещаем NMI
out 70h,al
in al,71h
; Запретим прерывания
cli
; Перейдём в защищённый режим
mov eax, cr0
or eax, 1
mov cr0, eax
; Перейдём на 32-битный код
mov ax,8
mov ds,ax
xchg bx,bx
dw 0xEA66
jadr dd start32
dw 08
; Таблица дескрипторов сегментов для 32-битного ядра
align 16
gdt32:
dq 0 ;пустой
db 0FFh,0FFh,0,0,0,9Ah,0CFh,0 ;код
db 0FFh,0FFh,0,0,0,92h,0CFh,0;данные
db 0FFh,0FFh,0,80h,0Bh,92h,40h,0 ;видеосегмент
gdtr32:
dw $ - gdt32 - 1
addr dd gdt32
; 32-битный код
use32
start32:
mov ax,018h
mov ds,ax
xor esi,esi
mov al,'@'
mov ah,0Ah
@@:
mov [ds:esi],word ax
inc esi
inc esi
inc al
cmp esi,200h
je @f
jmp @b
@@:
jmp $
.start32:
mov ax,3
int 10h
; Загрузим значение в GDTR
xor ax,ax
mov ax,cs
mov ds,ax
shl eax,4
add [addr],eax
add [jadr],eax
; add [adr],ax
lgdt fword [gdtr32]
in al, 0x92;включаем A20
or al, 2
out 0x92, al
cli ;запрещаем прерывания
mov al,8Fh;запрещаем NMI
out 70h,al
in al,71h
; Запретим прерывания
cli
; Перейдём в защищённый режим
mov eax, cr0
or eax, 1
mov cr0, eax
; Перейдём на 32-битный код
mov ax,8
mov ds,ax
xchg bx,bx
dw 0xEA66
jadr dd start32
dw 08
; Таблица дескрипторов сегментов для 32-битного ядра
align 16
gdt32:
dq 0 ;пустой
db 0FFh,0FFh,0,0,0,9Ah,0CFh,0 ;код
db 0FFh,0FFh,0,0,0,92h,0CFh,0;данные
db 0FFh,0FFh,0,80h,0Bh,92h,40h,0 ;видеосегмент
gdtr32:
dw $ - gdt32 - 1
addr dd gdt32
; 32-битный код
use32
start32:
mov ax,018h
mov ds,ax
xor esi,esi
mov al,'@'
mov ah,0Ah
@@:
mov [ds:esi],word ax
inc esi
inc esi
inc al
cmp esi,200h
je @f
jmp @b
@@:
jmp $
Я тебе еще в пред. теме хотел написать, что для COM-файла, загружаемого по произвольному адресу, не получится использовать FLAT-сегменты (сегменты с нулевой базой) при использовании позиционно зависимого кода. Самый простой выход - использовать сначала сегменты с той же базой, что и у COM-файла при его запуске в RM, а потом перемещать код по известному адресу и переходить на FLAT-адресацию. Экзешники для PM также можно релоцировать. Например, прикрепляешь к COM-файлу PE-файл, содержащий таблицу релокации, размещаешь его по относительно произвольному адресу, выполняешь релокацию, а потом его запускаешь.
Цитата: kailot2
Я же заюзал Flat-адресацию
Первая же команда в 32-битном коде, использующая абсолютную адресацию для твоих меток, будет ошибочной.
Код:
@@:
mov [ds:esi],word ax
inc esi
inc esi
inc al
cmp esi,200h
je @f
jmp @b
mov [ds:esi],word ax
inc esi
inc esi
inc al
cmp esi,200h
je @f
jmp @b
Flat assembler это
Цитата: kailot2
оно работает! Выводит все ASCII символы! а там есть такая команда которая использует метки
В обеих командах перехода используется относительная адресация. Примеры команд с абсолютной адресацией: mov eax,[var], jmp 8:@f
Цитата: kailot2
Flat assembler это
Ести это fasm, то в 16-разрядном коде можно делать так: jmp fword 8:start32
dw 0xEA66 мозг не насиловал бы
Код:
mov ax,10h ;здесь пихаем селекторы. Зачастую (! не забываем про порядковый номер в
mov es,ax ;таблице) селектор сегмент кода - 08h. данных - 10h, видеосегмент - 18h
mov ds,ax
mov fs,ax
mov ss,ax
mov esp,50000h;стек
mov ax,18h
mov gs,ax
mov esi,hi_string ;покажем, что мы удачно перешли
add esi,ebp
call print
jmp $
;ESI - адрес строки
print:
pushad
xor ebx,ebx
mov ah,07h;атрибут
puts:
mov al,[esi+ebx]
mov [gs:(ebx*2)],ax
inc ebx
test al,al
jnz puts
popad
ret
hi_string db 'Welcome to PM, dude',0
mov es,ax ;таблице) селектор сегмент кода - 08h. данных - 10h, видеосегмент - 18h
mov ds,ax
mov fs,ax
mov ss,ax
mov esp,50000h;стек
mov ax,18h
mov gs,ax
mov esi,hi_string ;покажем, что мы удачно перешли
add esi,ebp
call print
jmp $
;ESI - адрес строки
print:
pushad
xor ebx,ebx
mov ah,07h;атрибут
puts:
mov al,[esi+ebx]
mov [gs:(ebx*2)],ax
inc ebx
test al,al
jnz puts
popad
ret
hi_string db 'Welcome to PM, dude',0
Phantom-84 Спасибо огромное за помощь!
Цитата: kailot2
jmp fword 8:start32 не прокатывает иначе бы я себе всякими
dw 0xEA66 мозг не насиловал бы
dw 0xEA66 мозг не насиловал бы
У меня почему-то прокатывает.
Цитата: kailot2
Я разобрался с переходом в этот чертов PM.теперь можно и релоки делать, и по известному адресу грузить =)
Если по известному, то с релоками пока можно не заморачиваться. Используй директиву org и перемещай код, лежащий после нее, по указанному адресу.