|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Июл 31, 2003 12:09:51 · Поправил: Безпощадный даос Вот, возник вопрос, как сделать чтобы для кода в 32бит сегменте смещение отсчитывается оттуда же, откуда идет смещение в 16бит сегменте,т.е. чтобы в примере ниже смещение в 32бит коде отсчитывалось не от start32: а от Start16:
seg16 segment use16
start16: commands 16bit code
assume cs:seg16
...
seg16 ends
seg32 segment use32
start32: commands 32bit code
mov eax,offset start32
....
seg32 endsИзврат :) нужен чтобы из 32-бит кода вызывать процедуры, написанные на исполнение как в 16-бит режиме, так и в 32-бит режиме (например такого блока, который одинаков как в 16 так и 32 бит коде :)
in al,20h mov ah,al in al,0A0h xchg ax,dx ; в 32бит команда выглядит как xchg eax,edx out 0A0h,al ;все равно нам надо только dh и dl :) mov al,ah out 20h,al ret |
|
|
Дата: Июл 31, 2003 13:48:31 Это возможно в PM(типа protected mode), если в дескрипторах этих сегментов указать разрядность кода. Под чистый дос и винду это невозможно. |
|
|
Дата: Июл 31, 2003 14:30:12 А что тебе мешает вызывать их так, как они есть? |
|
|
Дата: Июл 31, 2003 17:56:42 Мешает то, что Tasm отказывается скомпилить смещение в code32 начиная от начала 16бит кода (16бит сегмента). Мне не нужно указывать про дескрипторы и т.д. я сам знаю. Мне нужен способ, чтобы компилятор скомпилил :) Что 16bit сегмент и 32bit Сегмент фактически начинались с одного адреса start32:=offset end_seg16. |
|
|
Дата: Июл 31, 2003 18:54:24 Попробуй тогда на FASM перенести, там просто указываешь USE16 или USE32, в зависимости, какой код нужен. |
|
|
Дата: Июл 31, 2003 19:06:15 С тасмом такие вещи делаются слишком сложно. На том же насме многие вещи гораздо проще. Может помочь старинный прикол с относительной адресацией: расположить 16-битный сегмент после 32-х битного, вычислить относительные смещения нужных процедур от его начала, а в 32-битном сегменте адресовать их как конец 32-битного сегмента плюс смещение процедуры. Разумеется, макросами. Или ещё как-нибудь, в общем, на тасме для таких вещей через задницу - это штатный способ. ;) |
|
|
Дата: Авг 2, 2003 01:47:57 MrAssembler Эту проблему решить можно в tasm если заменить инструкции на _Метка: db ?? db ?? и т.д. Я как-то раз создавал свой заголовок MZ-PE (ну не нравился мне тот что создает tlink32) и обойти этот момент получилось только так. |
|
|
Дата: Авг 2, 2003 01:51:54 · Поправил: Безпощадный даос MrAssembler Да еще посмотри на эти моменты, особенно на ife @32Bit
IRQINTMasterBase = 008h
IRQINTSlaveBase = 070h
IRQMasterMask = 098h
IRQSlaveMask = 0CCh
EndIRQMaster MACRO
mov al,20h
out 20h,al
ENDM
EndIRQSlave MACRO
mov al,20h
out 0A0h,al
ENDM
;--------------------------------------------------------------------- ---
; ICW1
;--------------------------------------------------------------------- ---
ICW1 = 00010000b ; 1 говорит о начале инициализации запись ICW1 в 20h
IC4 = 00000001b ; 1 говорит о наличие ICW4
SMODE= 00000010b ; 1 Одиночный режим ICW3 не нужен
CMODE= 00000000b ; 0 Каскадный режим
Level= 00001000b ; Запуск IRQ уровнем < В AT используется запуск фронтом
Edge = 00000000b ; Запуск фронтом < функция перенесена на порты 4D0-1
INT4 = 00000000b ; Вектор прерывания 4 байта (в AT)
INT8 = 00000100b ; 8 байтов
iICW1Master = ICW1 OR IC4 OR CMODE OR Edge
iICW1Slave = ICW1 OR IC4 OR CMODE OR Edge
;--------------------------------------------------------------------- ---
; ICW2
;--------------------------------------------------------------------- ---
iICW2Master = IRQINTMasterBase
iICW2Slave = IRQINTSlaveBase
;--------------------------------------------------------------------- ---
; ICW3
;--------------------------------------------------------------------- ---
iICW3Master = 4 ; Аппаратно закреплено, что второй контроллер
iICW3Slave = 2 ; подсоединен к первому на вход IRQ2
;--------------------------------------------------------------------- ---
; ICW4
;--------------------------------------------------------------------- ---
intel8086 = 00000001b ; Микропроцессор 8088/8086
intel8085 = 00000000b ; 8080/8085
AEOI = 00000010b ; Автоматическое окончание прерывания
EOI = 00000000b ; Обычное
Master = 00000100b ; Обязательно необходимо сочетать с BUF = 1
Slave = 00000000b ;
BUF = 00001000b ;
SFNM = 00010000b ; Спец полновложенный режим
iICW4Master = intel8086
iICW4Slave = intel8086
;--------------------------------------------------------------------- ---
; OCW1
;--------------------------------------------------------------------- ---
OCW1Master = IRQMasterMask
OCW1Slave = IRQMasterMask
.code
InitIRQ: call IIRQLabel3
IRQdata db iICW1Master,iICW2Master,iICW3Master,iICW4Master,OCW1Master
db iICW1Slave ,iICW2Slave ,iICW3Slave ,iICW4Slave ,OCW1Slave
IIRQLabel3:
ife @32Bit
pop si
mov dx,20h
else
pop esi
xor edx,edx
mov dl,020h
endif
call IIRQLabel1
mov dl,0A0h
IIRQLabel1: outsb
ife @32Bit
inc dx
else
inc edx
endif
outsb
outsb
outsb
outsb
retn |
|
|
Дата: Авг 4, 2003 11:47:04 В общем, поковырялся я так и так, действительно, вызов можно сделать только через извращения с ссылками. PS.Пасиб, но как программировать контроллер прерываний я знаю :) Кстати - процедура посылки icw1,2,3,4 я уже сделал - аналогично :) через повторный call и outsb'ы :). "Все придумано до нас" (с) |
|
|
Дата: Авг 4, 2003 12:10:11 MrAssembler Не нужно никаких извратов, в тасме есть замечательная директива GROUP. Можно поместить 16и и 32х битные сегменты в одну группу и тогда тасм будет считать смещения относительно начала группы. Правда из общих процедур не получится делать вызовы и переходы можно делать только короткие. А что это ты такое страшное пишешь? |
|
|
Дата: Авг 4, 2003 18:03:52 Гы, вот я облажался :) Я ж GROUP использовал раньше, правда не в таком ключе :). Но сейчас попробовал - компилится правильно, хотя геморрой все равно кое-где остается: seg16 segment byte use16 start16: commands 16bit code assume cs:seg16 ... seg16 ends seg32 segment byte use32 Assume сs:dgroup,ds:seg16,es:seg16,fs:seg16,gs:seg16,ss:seg16 start32: mov eax,offset start16 ;commands 32bit code mov eax,offset start32 .... seg32 ends DGROUP GROUP Seg16,Seg32 В команде mov eax,offset start16 получается смещение 0 (правильно), а вот mov eax,offset start32 оказывается число ну совершенно маленькое и непонятно откуда взявшееся. Если выставить mov eax,offset ds:start32, тогда выдает смещение от начала Seg16 (правильно) >:O |
|
|
Дата: Авг 5, 2003 08:24:53 Попытайся написать assume ds:dgroup. Может тогда не придется в каждом offset'е добавлять ds. |
|
|
Дата: Авг 5, 2003 09:19:08 .386p seg16 segment use16 assume cs:dgroup org 0 start16: mov ax,offset start16 mov ax,SMALL offset start32 call SMALL start32 ret ;commands 16bit code seg16 ends seg32 segment byte use32 assume cs:dgroup,ds:dgroup,es:dgroup,ss:dgroup assume fs:dgroup,gs:dgroup start32: mov eax,offset start16 ;commands 32bit code mov eax,offset start32 call start16 ret seg32 ends dgroup GROUP seg16,seg32 end start16 Все работает, все смещается правильно :) Ура! |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.071 |