У новичков бывает. Одну ошибку исправил вторую добавил. Вот оно и не работает. А кажется что все варианты проверил. Больше знаешь меньше ошибок. И учиться надо постепенно.
Для того чтобы ошибок было меньше, надо правильно оформлять код.
Набросал код. Вот так вот надо оформлять и писать код.
Код:
; Будем делать COM файл.
.486p ; Выбираем режим совместимости 486. 32 битные регистры появились в 386, данная директива их разрешает
.model tiny, PASCAL ; Простая модель памяти, а именно код, данные, стек в одном сегменте
; Выбираем в качестве соглашения о вызове функций формат PASCAL
CSEG SEGMENT USE16 ; Создаем новый сегмен с именем CSEG. Устанавливаем выравнивание по параграфу. По умолчанию Формат кода 16 битный
ASSUME CS:CSEG,DS:CSEG,ES:CSEG ; Сообщаем компилятору о том физический сегменты CS,DS,ES связан с логическим CSEG
; Теперь для смещение для меток будут отсчитываться от CSEG
org 100h ; Нужно для ДОС чтобы линкер правильно сформировал смещения
; Ко всем меткам прибавляется +100h
; Основной код
main PROC
CALL OpenA20
CALL GoToPM
CALL mainPM
CALL GoToRM
RET
main ENDP
; Основной код для защищённого режима
mainPM PROC
PUSH ESI
MOV EAX, '1234'
MOV ESI, 100000h
MOV DWord PTR [ESI], EAX
POP ESI
RET
mainPM ENDP
; Переход в защищенный режим.
; запрещает прерывания включаем защищенный режим.
; Настраиваем сегментые регистры DS,ES,FS,GS
; Не трогаем регистры SS, CS
GoToPM PROC
PUSH BX
CALL InitGDTR
CALL DisableInt
;{ON_PM:}
MOV EAX,CR0
OR AL,1
MOV CR0,EAX
MOV BX, 10h ; Устанавливаем селектор сегмента 10h; T=GDT index=2 RPL=0
MOV DS,BX
MOV ES,BX
MOV FS,BX
MOV GS,BX
; SS не трогаем
; CS не трогаем
POP BX
RET
GoToPM ENDP
; Переход в реальный режим.
; Настраиваем сегментые регистры DS,ES,FS,GS
; разрешаем прерывания.
GoToRM PROC
PUSh BX
;{OFF_PM:}
MOV EAX,CR0
AND AL,0FEh
MOV CR0,EAX
XOR BX,BX
MOV FS,BX
MOV GS,BX
MOV BX,CS
MOV DS,BX
MOV ES,BX
CALL EnableInt
POP BX
RET
GoToRM ENDP
; Настраиваем GDTR;
; Входные параметры:
; Глобальные переменные GDT, GDTR
InitGDTR PROC
PUSH ES
PUSH EBX
XOR EAX, EAX
XOR EBX, EBX
MOV AX, DS
MOV BX, OFFSET GDT
SHL EAX,4
ADD EAX,EBX
PUSH DS
POP ES
MOV DWord PTR ES:[GDTR+2],EAX
LGDT QWord PTR ES:[GDTR]
POP EBX
POP ES
RET
InitGDTR ENDP
; Запрещаем маскируемые и немаскируемые прерывания
DisableInt PROC
CLI
MOV AL, 8Fh
OUT 70h, AL
IN AL, 71h
RET
DisableInt ENDP
; Разрешаем немаскируемые и маскируемые прерывания
EnableInt PROC
MOV AL, 0Fh
OUT 70h, AL
IN AL, 71h
STI
RET
EnableInt ENDP
; Открываем, разрешаем 20 линию адреса
OpenA20 PROC
IN AL,92h
OR AL,2
OUT 92h,AL
RET
OpenA20 ENDP
ALIGN 16 ; GDT, GDTR должны быть выровнены на границе 16 байт.
GDT db 000h, 000h, 000h, 000h, 00h, 000h, 000h, 000h
db 0FFh, 0FFh, 000h, 000h, 000h, 09Ah, 08Fh, 000h ; Кодовый сегмент с разрешенным выполнение и чтением. Формат команд 16 бит!
db 0FFh, 0FFh, 000h, 000h, 000h, 092h, 0CFh, 000h
db 0FFh, 0FFh, 000h, 000h, 000h, 092h, 0CFh, 000h
GDTR dw 8*4-1 ;Лимит
dd 0 ;Смещение
dw 0 ;Резерв
CSEG ENDS
end main ; Указываем точку входа в программу