Предыдущая тема :: Следующая тема |
Автор |
Сообщение |
castasat
Зарегистрирован: 15.03.2005 Сообщения: 8 Откуда: Москва
|
Добавлено: Вт Мар 15 2005 21:06 Заголовок сообщения: masm32 for Object-oriented programming |
|
|
У меня есть идея-сабж.
Предлагаю в данной теме обсуждать мысли всем заинтересованным.
В языках высокого уровня практически все функции по реализации OOP возлагаются на препроцессор и компилятор (интерпретатор).
Мне же хотелось бы, чтобы реализация была чисто "асмовой" плюс макросы.
Мною был избран masm потому, что под него уже существует подобный проект (авторы - NaN и Exagone), однако, их подход, несмотря на то, что кое-в-чем мне помог, показался мне несколько нестройным.
Далее в сообщениях я постараюсь изложить свои наработки. |
|
Вернуться к началу |
|
|
castasat
Зарегистрирован: 15.03.2005 Сообщения: 8 Откуда: Москва
|
Добавлено: Вт Мар 15 2005 21:20 Заголовок сообщения: объект, класс и интерфейс |
|
|
В объектно-ориентированном программировании важным понятием является объект.
В простейшем случае, объект - это набор полей (то что можно назвать переменными объекта и его состояниями) и методов или функций-членов объекта.
Схожие объекты можно объединить в класс объектов и описать такой класс на языке программирования, а затем создавать в программе экземпляры класса - объекты, каждый со своими значениями полей, но у одного класса набор полей и методов одинаков.
Итак, самое простое - иметь некоторые переменные и некоторые функции "рядом" и все это считать объектом. Но в masm все имена функций и переменных по сути являются просто метками и должны быть уникальными. Если в разных классах должны быть функции с одним именем, но разной реализацией, мы наступим на грабли. Обойти проблему можно задавая имена функций в виде: ИмяКласса_ИмяМетода.
Но, при таком подходе все функции, по сути, статические, и могут быть вызваны откуда угодно (в пределах файла), да и функция "не знает" к какому объекту она относится. Если ей надо работать с каким-то объектом, ей надо обязательно его указать в качестве аргумента. |
|
Вернуться к началу |
|
|
castasat
Зарегистрирован: 15.03.2005 Сообщения: 8 Откуда: Москва
|
Добавлено: Вт Мар 15 2005 21:44 Заголовок сообщения: структура класса, таблица виртуальных методов и интерфейс |
|
|
Для того, чтобы жестче объединить как-то поля и методы в класс (и задать его имя, которое далее может использоваться как тип данных) можно воспользоваться подходом в той или иной мере реализуемым языками высокого уровня.
Создается структура с именем класса. Структура - это данные, поэтому мы не можем поместить туда методы непосредственно, но можем поместить указатели на методы. Таблица указателей на методы называется таблицей виртуальных методов.
Совокупность методов объекта, через которые с ним могут взаимодействовать другие объекты - это интерфейс объекта.
В саму структуру можно также поместить поля класса (или указатели на них).
После этого всего можно вызывать виртуальные мутоды класса, как
ИмяСтруктурыКласса.ИмяМетода, где ИмяМетода - это указатель на функцию ИмяКласса_ИмяМетода. Статические методы можно вызывать как и раньше непосредственно ИмяКласса_ИмяМетода.
Методы в таблице виртуальные, поскольку всегда можно переопределить функцию, на которую указывает указатель в таблице, правда имя этой функции должно быть отличным, например, ИмяКласса_ИмяФункции_2
Тут уже можно думать о наследовании, как это сделали NaN и Exagone, но все равно не хватает некой гибкости, например, я пока не знаю, как перегружать методы. |
|
Вернуться к началу |
|
|
Wladimir
Зарегистрирован: 02.03.2005 Сообщения: 150 Откуда: Ставропольский край
|
Добавлено: Вт Мар 15 2005 22:33 Заголовок сообщения: |
|
|
Идея вовсе не новая. Самая толковая книга, которую читал на эту тему - тов. Зубкова (инициалы не помню) - Язык Ассемблер или что-то в этом роде. Рекомендую посмотреть. Если интересно, могу глянуть название и автора точно.
Со сходной идеей здесь носится некий "критикан" (см. тему Простой вопрос по Си). Думаю, впрочем, что кроме общих фраз ты от него вряд ли что услышишь. |
|
Вернуться к началу |
|
|
Wladimir
Зарегистрирован: 02.03.2005 Сообщения: 150 Откуда: Ставропольский край
|
Добавлено: Вт Мар 15 2005 22:51 Заголовок сообщения: |
|
|
Кстати говоря: C++ первоначально были, грубо говоря, дополнительным препроцессором к C (front-end).
И тогда и сейчас на низком уровне любая программа - ассемблер, а все языки высокого уровня - макроассемблеры.
А так это - просто изобретать геморрой себе на голову. Прежде, чем тратить время, задай себе вопрос: а на хрен тебе это нужно? И лучше займись тем, на чём можно заработать деньги - .Net выучи или MFC. |
|
Вернуться к началу |
|
|
castasat
Зарегистрирован: 15.03.2005 Сообщения: 8 Откуда: Москва
|
Добавлено: Чт Мар 17 2005 19:55 Заголовок сообщения: Re |
|
|
2 Wladimir:
Спасибо за ваш ответ. Зубкова я тоже читал - он очень понятно и с примерами рассказывает о том, как объявлять структуры, инициализировать их и затем обращаться к их элементам. Более полную информацию можно найти, если тщательно изучить msm32help или, кто пользуется tasm - его руководство.
Насчет того зачем это нужно - мне просто очень нравится, когда программы если не написаны, то хотя бы могут быть написаны "изящно". Ассемблер при грамотном использовании - вне конкуренции. С другой стороны, мне также нравятся положительные черты JAVA.
Я вполне понимаю, что мне очень многие будут рекомендовать в таком случае просто использовать C++, но хочется пойти дальше и создать что-то похожее на пакеты вроде java.lang, java.io, java.awt на асме. Так сказать, перевести ассемблер на более высокую ступень.
Занимаюсь всем этим я не за деньги, так как это скорее хобби - моя специальность далека от программирования (я биолог). |
|
Вернуться к началу |
|
|
castasat
Зарегистрирован: 15.03.2005 Сообщения: 8 Откуда: Москва
|
Добавлено: Чт Мар 17 2005 20:33 Заголовок сообщения: инклуды |
|
|
Продолжая разговор об ООП на masm, можно предложить создавать файлы-инклуды, в которые помещать "лишнюю" но нужную информацию, например, повторяющиеся части, макросы, константы и т.д.
Для избежания повторного включения файла, используем стандартный подход - определяем в файле уникальную переменную, и проверяем, была ли она определена ранее. Далее пользоваться директивами условного ассемблирования - если уже определена, то не ассемблировать, иначе - наоборот.
Для примера, вот листинг небольшого файла model.inc с комментариями:
Код: |
; MODEL.INC
; This file must be included at the beginning of any other .asm file
IFNDEF _MODEL_ ; include once
_MODEL_ EQU 1 ; = #define
.LIST ; allow listing generating
.586 ; use pentium unstructions there possible
.model flat, stdcall ; model flat, stdcall (Win32)
option expr32 ; use 32-bit instructions and addressing there
; possible
option casemap:none ; case sensitive labels
ENDIF
|
|
|
Вернуться к началу |
|
|
Wladimir
Зарегистрирован: 02.03.2005 Сообщения: 150 Откуда: Ставропольский край
|
Добавлено: Пт Мар 18 2005 21:45 Заголовок сообщения: |
|
|
Кстати, а Кладовскую библиотеку KOL Вы смотрели? (bonanzas.rinet.ru)
У него там каждая функция в двух вариантах: на паскале и ассемблере (фиг его знает, зачем - у великих свои причуды). И тоже как бы ООП-ная.
Возможно, найдёте что-либо интересное. |
|
Вернуться к началу |
|
|
castasat
Зарегистрирован: 15.03.2005 Сообщения: 8 Откуда: Москва
|
Добавлено: Сб Мар 19 2005 14:02 Заголовок сообщения: Re |
|
|
Нет, этой библиотеки я раньше не видел - спасибо. Возможно, это окажется полезным, а может быть, подскажет какие-нибудь интересные решения. Чувствуется серьезный подход.
Что касается дублирования функций на ассемблере и паскале, могу предположить, что это понадобилось автору для написания более быстрых или более компактных программ. Да и разобраться в тонкостях работы программы тоже помогает.
Очень интересным показался проект GOODWELL |
|
Вернуться к началу |
|
|
Wladimir
Зарегистрирован: 02.03.2005 Сообщения: 150 Откуда: Ставропольский край
|
Добавлено: Вс Мар 20 2005 20:45 Заголовок сообщения: |
|
|
[quote]Чувствуется серьезный подход.[/quote]
Для delьphячьего сообщества он - практически локальный мессия, что неудивительно.
Для сообщества фанатов игры Elite - автор её новосибирского клона.
[quote]Что касается дублирования функций на ассемблере и паскале, могу предположить, что это понадобилось автору для написания более быстрых или более компактных программ. Да и разобраться в тонкостях работы программы тоже помогает.[/quote]
Возможно также сыграло свою роль то, что Delьphi/C++Buider при компиляции могут выдавать промежуточный ассемблерный листинг модуля. :)
P.S. Извиняюсь, что мои посты не по теме ООП-asmа: как Вы понимаете, я скорее сторонник C++. |
|
Вернуться к началу |
|
|
castasat
Зарегистрирован: 15.03.2005 Сообщения: 8 Откуда: Москва
|
Добавлено: Пн Мар 21 2005 23:41 Заголовок сообщения: импорт библиотек |
|
|
Привожу листинг файла lib.inc Он содержит записи об импортируемых библиотеках и прототипы некоторых функций, из этих библиотек. Также сюда можно помещать записи о часто используемых константах.
Код: |
IFNDEF _LIB_
_LIB_ EQU 1
; ##############################################
; Подключение файлов библиотек
includelib d:\masm32\lib\kernel32.lib
; ##############################################
; константы подключаемых библиотек
NULL EQU 0
; ##############################################
; Прототипы используемых функций подключаемых библиотек
GetProcessHeap PROTO
HeapAlloc PROTO :DWORD, :DWORD, :DWORD
HeapFree PROTO :DWORD, :DWORD, :DWORD
Sleep PROTO :DWORD
ExitProcess PROTO :DWORD
; ##############################################
ENDIF
|
|
|
Вернуться к началу |
|
|
castasat
Зарегистрирован: 15.03.2005 Сообщения: 8 Откуда: Москва
|
Добавлено: Пн Мар 21 2005 23:49 Заголовок сообщения: макросы |
|
|
Теперь перейдем к более важным вещам. Будем включать в файл oop.inc различные макросы для реализации той или иной части "объектности" кода.
Код: |
; OOP.INC
; This file must be included in any .asm file using Asm Model for OOP (ASMOP)
IFNDEF _OOP_
_OOP_ EQU 1
; объявление структур происходит вне секций констант, данных или кода
; инициализация структур происходит в данных: имя, тип <значения через запятую> или в коде
; в коде размеры источника, приемника и данных должны совпадать
; #####################################################
; определение прототипов функций (0-9 параметров)
proto0 TYPEDEF PROTO :DWORD
proto1 TYPEDEF PROTO :DWORD, :DWORD
proto2 TYPEDEF PROTO :DWORD, :DWORD, :DWORD
proto3 TYPEDEF PROTO :DWORD, :DWORD, :DWORD, :DWORD
proto4 TYPEDEF PROTO :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
proto5 TYPEDEF PROTO :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
proto6 TYPEDEF PROTO :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD,
\ :DWORD
proto7 TYPEDEF PROTO :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD,
\ :DWORD, :DWORD
proto8 TYPEDEF PROTO :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD,
\ :DWORD, :DWORD, :DWORD
proto9 TYPEDEF PROTO :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD,
\ :DWORD, :DWORD, :DWORD, :DWORD
; определение типов - указателей на функции (0-9 параметров)
ptr0 TYPEDEF PTR proto0
ptr1 TYPEDEF PTR proto1
ptr2 TYPEDEF PTR proto2
ptr3 TYPEDEF PTR proto3
ptr4 TYPEDEF PTR proto4
ptr5 TYPEDEF PTR proto5
ptr6 TYPEDEF PTR proto6
ptr7 TYPEDEF PTR proto7
ptr8 TYPEDEF PTR proto8
ptr9 TYPEDEF PTR proto9
; #####################################################
; макрос определения класса
CLASS MACRO ClassName:REQ
LOCAL sz ; локальная переменная в стеке
Class TEXTEQU <ClassName>
sz CATSTR Class, <_init PROTO lpTHIS:DWORD>
sz
ENDM
; #####################################################
; Создать новый экземпляр класса (возврящает хэндл объекта в EAX)
NEW MACRO objType:REQ
LOCAL sz
sz CATSTR <&objType>,<_init> ; функция-конструктор
sz PROTO :DWORD
invoke GetProcessHeap
invoke HeapAlloc, eax, NULL, SIZEOF objType
push eax
invoke sz, eax ; вызвать конструктор
pop eax
ENDM
; #####################################################
; уничтожить экземпляр класса (передается хэндл объекта)
DESTROY MACRO pName
mov eax, pName
push eax
call dword ptr [eax]
push eax
invoke GetProcessHeap
invoke HeapFree, eax, NULL, pName
pop eax
ENDM
; #####################################################
; установить в регистр указатель на объект
SET_OBJECT MACRO reg:REQ, Objtype:REQ, lpTHIS:REQ
mov reg, lpTHIS
assume reg:PTR Objtype
ENDM
; #####################################################
; сбросить из регистра указатель на объект
RELEASE_OBJECT MACRO reg:REQ
assume reg:nothing
ENDM
; #####################################################
ENDIF
|
|
|
Вернуться к началу |
|
|
|