Изучаю защищенный режим, etc. Столкнулся со следующей проблемой. У Broken Sword`а в серии статей про PM есть пример перевода. Там идет вычисление линейного адреса "точки входа" в PM для последующего дальнего jmp`а следующим образом: (это всё происходит в 16 битном сегменте) xor EAX,EAX (*)mov AX,PM_CODE shl EAX,4 add EAX,offset ENTRY_POINT где PM_CODE - имя 32 битного сегмента, в котором лежит код для PM. Проблема в следующем: строка (*) ведь создаст релок, тк неизвестно по какому адресу загрузится сегмент PM_CODE. И никак не перегнать объектник в .bin изза этого, тк unilink пишет, что Segment selector relocs (at 0000:00007C0F) are not supported in COM/BIN file (что в принципе понятно). Можно какимто образом обойти эту проблему? Как я понял, в masm`е писать смешанный 16\32 битный код можно только в разных сегментах, да и всё равно придется вычислять линейный адрес для дальнего jmp`а (сегмент кода занимает все 4Гб) ... ЗЫ Сорри за несколько путанные объяснения - ещё плаваю сильно в этих материях ^____^ ЗЫЫ. Вот собственно код весь Код (Text): .386p RM_CODE segment para public 'CODE' use16 assume cs:RM_CODE, ss:RM_STACK org 7C00h @@start: ;Очищаем экран mov ax, 03h int 10h ;открываем линию A20 (чтобы задействовать 32 битную адресацию) in al, 92h or al, 02h out 92h, al ;Вычисляем линейный адрес точки входа в защищенный режим xor eax, eax (*)mov ax, PM_CODE shl eax, 4 ;*16d add eax, offset ENTRY_POINT mov dword ptr ENTRY_OFF, eax ;Вычисляем линейный адрес GDT xor eax, eax (*)mov ax, RM_CODE shl eax, 4 add eax, offset GDT mov dword ptr GDTR+2, EAX ;Загружаем GDTR lgdt fword ptr GDTR ;Запрет маскируемых прерываний cli ;Запрет немаскируемых прерываний in al, 70h or al, 80h out 70h, al ;Переключение в защищенный режим mov eax, cr0 or ax, 1 mov cr0, eax ;Загружаем селектор в CS db 66h db 0EAh ENTRY_OFF dd ? dw 00001000b ;Глобальная таблица дескрипторов GDT: nulldescr db 08h dup(0) codedescr db 0FFh, 0FFh, 00h, 00h, 00h, 10011010b, 11001111b, 00h datadescr db 0FFh, 0FFh, 00h, 00h, 00h, 10010010b, 11001111b, 00h videdescr db 0FFh, 0FFh, 00h, 80h, 0Bh, 10010010b, 11000000b, 00h GDT_size equ $ - GDT GDTR dw GDT_size - 1 dd ? RM_CODE ends RM_STACK segment para stack 'STACK' use16 db 100h dup(?) RM_STACK ends PM_CODE segment para public 'CODE' use32 assume CS:PM_CODE, DS:PM_DATA ENTRY_POINT: mov ax, 00010000b mov ds, ax mov ax, 00011000b mov es, ax xor esi, esi (*)mov si, PM_DATA shl esi, 4 add esi, offset message xor edi, edi mov ecx, mes_len rep movsb jmp $ PM_CODE ends PM_DATA segment para public 'DATA' use32 message db "HelloWorld from PM", 0Ah, 0Dh mes_len equ $ - message PM_DATA ends end @@start
10 минут потратил разбираясь с синтаксисом fasm`a и за минуту переписал тоже самое под него. И это против 2 часов долбания об стену с масмом. А до этого я не понимал зачем чтото кроме масма есть ^____^. И всетаки, как сделать подобное на masm? Код для fasm (несколько упрощено) Код (Text): org 7C00h use16 _start: cli mov ax, cs mov ds, ax mov ss, ax mov sp, _start lgdt fword [GDTR] in al, 92h or al, 2 out 92h, al mov eax, cr0 or al, 1 mov cr0, eax jmp 08h:_protected use32 _protected: mov ax, 10h mov ds, ax mov ss, ax mov ax, 18h mov es, ax mov esi, msg call kputs hlt jmp short $ kputs: pusha loopaz: lodsb test al, al jz quit mov ecx, [cursor] mov byte [es:ecx], al shl dword [cursor], 1 jmp loopaz quit: popa ret cursor dd 0 msg db "Hello world from PM!", 0 ;Ãëîáàëüíàÿ òàáëèöà äåñêðèïòîðîâ GDT: nulldescr db 08h dup(0) codedescr db 0FFh, 0FFh, 00h, 00h, 00h, 10011010b, 11001111b, 00h datadescr db 0FFh, 0FFh, 00h, 00h, 00h, 10010010b, 11001111b, 00h videdescr db 0FFh, 0FFh, 00h, 80h, 0Bh, 10010010b, 11000000b, 00h GDT_size equ $ - GDT GDTR dw GDT_size - 1 dd GDT