Info Guide
#06
03 декабря 2004 |
|
For Coderz - Описание модульной структуры программ.
Описание модульной структуры программ. Модули представляют собой файлы,в кото- рых содержится части кода и вся необходи- мая информация для их применения.Код моду- ля является релоцируемым,поскольку настра- ивается на любой адрес. Также имеется воз- можность связи модуля с другими модулями,в которых могут содержаться необходимые фун- кции и константы. Библиотека ещё довольно сырая, но уже проверена в работе.Написан линковщик,кото- рый, впрочем,нуждается еще в основательной оптимизации, но свои функции выполняет. Формат заголовка модуля: Смещение Длина Назначение +0 8 Имя модуля +8 2 Длина модуля в байтах, включая заголовок +10 1 Версия модуля +11 1 Флаги модуля (бит 0 - отладочная версия) +12 2 Смещение таблицы экспортируемых точек +14 2 Смещение таблицы импортируемых точек +16 2 Смещение кода +18 6 Свободная область Заголовок занимает 24 байта. Следом за ним идёт таблица настройки адресов. Она имеет формат: +0 2 Смещение точки от начала кода (Point_offset) +2 2 Смещение значения от начала кода (Value_offset) + флаги. Если старший байт Value_offset >= #f0, то здесь имеется ссылка на экспортируемую точку.Младший байт Value_offset определяет номер этой точки. В другом случае после загрузки модуля в память происходит наст- ройка кода по всем точкам, т.е. по адресу (CodeAddress+(Point_offset & #3fff)) зано- сится значение (CodeAddress+Value_offset) в соответствии с двумя старшими битами Point_offset. 0 в соответствующем бите разрешает загрузку младшего или старшего байта (CodeAddress + Value_offset) в код. Маркер конца таблицы - #ffff. Таблица экспортируемых точек имеет фор- мат: +0 N Символьное имя точки в формате ASCIIZ +N 1 Флаг точки. Каждый бит отвечает за тип точки +N+1 2 Смещение точки в коде или её значение (для констант) Маркер конца таблицы - #ff. Символьное имя может содержать в себе дополнительную информацию о типах параметров и возвращае- мом значении, а также о формате передачи параметров в функцию: PointName[@<InputParams>][#<OutputParams>] [%CallType],0 InputParams & OutputParams перечисляют регистры,в которых хранятся соответственно входные и выходные параметры: a=A, b=B, c=C, d=D, e=E, h=H, l=L, B=BC, D=DE, H=HL, X=IX, Y=IY, mN= память в стеке N байт. CallType - формат передачи параметров: F<Fastcall> - передача параметров в регис- трах, C<C language> - параметры в стеке, стек очищает вызывающая процедура, а P<Pascal language> - параметры в стеке, стек очищает вызываемая процедура. Например: Search@HD#a%F Здесь входные параметры передаются в регистрах HL & DE, выходной параметр - в регистре А. Таблица импортируемых точек представля- ет собой последовательность ASCIIZ строк, завершающюся маркером #ff. Присутствие всех трех таблиц в модуле обязательно.Они могут быть и пустыми,в та- ком случае от таблицы остается только мар- кер завершения таблицы. Линковщик предназначен для склеивания двух объектных файлов в один. Для склеива- ния большего количества файлов нужно при- менять линковщик последовательно для пар файлов. Последовательность действий линковщика: 1) Загрузка обоих файлов в память, при этом они разделяются на ведущий и ведомый. Ведущий модуль рассматривается первым в некоторых функциях. 2) Составление единой таблицы экспорти- руемых точек. Если обнаруживаются повторы (оба модуля экспортируют точки с одинако- выми именами), то выдается сообщение об ошибке и процесс прекращается.При добавле- нии в таблицу имен от ведомого файла про- исходит их коррекия (если они не являются константами) на длину кода ведущего файла. 3) Просмотр каждого имени из таблицы им- портируемых точек на предмет его наличия в таблице экспортируемых точек. Если есть совпадения,то происходит коррекция таблицы настройки - перенаправление ссылок с внеш- них точек на внутренние точки. В противном случае происходит добавление имени в новую таблицу импортируемых точек.Поиск в табли- це экспортируемых точек происходит с учё- том описательных тегов (@,#,%). 4) Оптимизация таблицы экспортируемых точек, т.к. там могут содержаться повторы. 5) Заполнение структур заголовка. 6) Слияние таблиц в одну область памяти. 7) Сохранение полученного модуля на диск. Пример ассемблерного файла,использующе- го библиотеку. ;***************************************** ;* ;* MEM.H MEMORY MANAGEMENT FUNCTIONS ;* ;* Copyright (C) Vitamin/CAIG/2001 2004 ;* ;***************************************** INCLUDE "MODULE",197 ;файл с библиотекой INCLUDE "MACRO",196 ;прочие файлы INCLUDE "ERRNO",193 DEFINE _DEBUG_ ;определение отладочной ;версии модуля ;настройка адресов рабочих областей. ;адрес_кода, ;адрес_таблицы_релокации, ;адрес_таблицы_экспорта, ;адрес_таблицы_импорта __MODULE #8000,#9000,#A000,#B000 __VERSION 0 ;версия модуля __MODULESTART ;начало модуля __EXTERN "InitMemDrv",InitMemDrv ;импортируемые точки __EXTERN "Page",Page __EXTERN "MemPortMask",MemPortMask __EXTERN "MemMap",MemMap __EXTERN "LoMemMap",LoMemMap __EXTERN "MemMapSize",MemMapSize __EXTERN "CurrentPage",CurrentPage __EXTERN "PagesAvailable",PagesAvailable __EXTERN "CurrentPID",CurrentPID __EXTERN "SetErr",SetErr ;========================================= ;----------------------------------------- __PUBLIC "MEMINIT#a%F",FUNC ;объявление точки MEMINIT CALL_ InitMemDrv LD_ (PagesAvailable),A INC A JR Z,MI_2 LD E,0 SRA A RR E RRA RR E LD D,A LD_ (MemMapSize),DE ADD HL,DE LD DE,-64 ADD HL,DE LD_ (LoMemMap),HL LD A,16 LD_ (MemPortMask),A LD_ HL,MemMap LD D,H,E,L INC E LD_ BC,(MemMapSize) DEC BC LD (HL),-1 LDIR XOR A JP_ SetErr MI_2 LD A,ENOMEM JP_ SetErr ;----------------------------------------- __PUBLIC "GetPage#a%F",FUNC GetPage ;A - Current page LD_ A,(CurrentPage) RET ;----------------------------------------- __PUBLIC "GetPages#a%F",FUNC GetPages LD_ A,(PagesAvailable) RET ;BLOCK MEMORY FUNCS ;MEMORY MAP CONSISTS OF ELEMENTS, EACH OF ;THEM MAY BE THE NEXT: ; 255- FREE ; 254- TEMPORARY BUSY (USED FOR ;GETMEM FUNC) ; OTHER- BUSY BY PROCESS (PID IS DATA) ;----------------------------------------- __PUBLIC "GetMem@bD#H%F",FUNC GetMem LD A,B ;B-QUANTITY AND A ;DE-START BLOCK ;(USE ONLY IN LOMEM CALLS) JR Z,GM_ERR ;HL->ADRESS SETS ERR CP 64 JR NC,GM_ERR IF ?_DEBUG_ DI ELSE CALL_ _MemSpinLock ENDIF _IsHiMem JR NC,GM_HMA LD_ HL,MemMap ADD HL,DE GM_LMC CALL_ _IsValidLogic JR C,GM_ERR CALL_ GM_GPAGE JR C,GM_LMC,GM_REL GM_HMA CALL_ _GetCurrentPageMapData CALL_ GM_GPAGE JR NC,GM_REL LD_ HL,(LoMemMap) CALL_ GM_GPAGE JR NC,GM_REL GM_ERR LD HL,0,A,ENOMEM JR GM_REL+1 GM_REL XOR A IF ?_DEBUG_ EI ELSE CALL_ _MemSpinUnlock ENDIF JP_ SetErr GM_GPAGE LD C,B GM_L4 LD E,64 GM_L3 BIT 7,(HL) JR Z,GM_L1 DEC B JR NZ,GM_L5 LD_ A,(CurrentPID) GM_L2 LD (HL),A DEC HL,C JR NZ,GM_L2 INC HL JP_ _LogicToPhisic GM_L1 LD B,C GM_L5 INC HL DEC E JR NZ,GM_L3 LD HL,0 RET ;----------------------------------------- __PUBLIC "FreeMem@H#a%F",FUNC ;Out: A=0- OK =-1- ERROR ;Sets Err FreeMem ;HL- ADDRESS LD A,H CP 128 LD A,EFAULT JPC_ SetErr IF ?_DEBUG_ DI ELSE CALL_ _MemSpinLock ENDIF LD A,H CP 192 JR C,FM_LMA SUB 192 LD L,A LD_ A,(CurrentPage) CALL_ _AddPageMapData LD B,64 JR FM_L2 FM_LMA SUB 128 LD E,A,D,0 LD_ HL,(LoMemMap) ADD HL,DE SUB 64 NEG LD B,A FM_L2 LD_ A,(CurrentPID) FM_L1 CP (HL) JR NZ,FM_RET LD (HL),-1 INC HL DJNZ FM_L1 FM_RET IF ?_DEBUG_ EI ELSE CALL_ _MemSpinUnlock ENDIF XOR A JP_ SetErr ;----------------------------------------- __PUBLIC "ReleaseMem%F",FUNC ReleaseMem IF ?_DEBUG_ DI ELSE CALL_ _MemSpinLock ENDIF LD_ HL,MemMap LD_ DE,(MemMapSize) INC D LD_ A,(CurrentPID) RM_L2 CP (HL) JR NZ,RM_L1 LD (HL),-1 RM_L1 INC HL DEC E JR NZ,RM_L2 DEC D JR NZ,RM_L2 IF ?_DEBUG_ EI RET ELSE JP_ _MemSpinUnlock ENDIF ;----------------------------------------- __PUBLIC "MemTotal#B%F",FUNC MemTotal ;BC->BLOCKS LD_ A,(PagesAvailable) INC A LD BC,0 RRA RR C RRA RR C RET ;----------------------------------------- __PUBLIC "MemAvail#B%F",FUNC MemAvail ;BC->BLOCKS LD A,-1 JR MemProcUsage ;----------------------------------------- __PUBLIC "MemUsage#B%F",FUNC MemUsage LD_ A,(CurrentPID) ;----------------------------------------- __PUBLIC "MemProcUsage@a#B%F",FUNC MemProcUsage ;A- PID ;BC->BLOCKS LD_ HL,MemMap LD B,L,C,L LD_ DE,(MemMapSize) INC D MPU_L2 CP (HL) JR NZ,MPU_L1 INC BC MPU_L1 INC HL DEC E JR NZ,MPU_L2 DEC D JR NZ,MPU_L2 RET ;========================================= _MemSpinLock RET _MemSpinUnlock RET _GetCurrentPageMapData LD_ A,(CurrentPage) _GetPageMapData LD_ HL,MemMap __PUBLIC "_AddPageMapData",FUNC _AddPageMapData LD E,0 RRA RR E RRA RR E ADD A,H LD H,A,A,E ADD A,L LD L,A RET _LogicToPhisic LDH_ A,MemMap SUB H NEG LD H,A,A,L AND 192 RLA RL H RLA RL H LD A,L AND 63 LD L,A LD_ A,(PagesAvailable) CP H LD A,128 JR Z,LTP1,C,LTP1 LD A,H CALL_ Page LD A,192 LTP1 ADD A,L LD H,A,L,0 RET _IsValidLogic ;HL-BLOCK POINTER IN TABLE PUSH DE,HL LD_ DE,MemMap AND A SBC HL,DE JR C,IVLR LD_ DE,(MemMapSize) SBC HL,DE CCF IVLR POP HL,DE RET __MODULEEND ;окончание модуля __COMPILE "mem" ;создание служебного кода ;и списывание файла на диск __MAKEHEADER "mem",1 ;создание вспомогательного файла После компиляции в 1 странице создается файл с именем "mem" следующего содержания: ;Header file for modules construction. ;(C) Vitamin/CAIG/2001 all rights reserved MACRO MEMINIT_ CALL_ MEMINIT ENDM MACRO GetPage_ CALL_ GetPage ENDM MACRO GetPages_ CALL_ GetPages ENDM MACRO GetMem_ LD B,
Другие статьи номера:
Похожие статьи:
В этот день... 21 ноября