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

 WASM Phorum —› WASM.ASSEMBLER —› Смешанный 16 и 32 bit сегменты

Посл.отвђт Сообщен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