Заголовок следует по смещению 0 от начала файла (fasm org 0x0), что
благодаря Михаилу Шеккеру достаточно просто сделать для встроеннного
линкера C--, следующей строчкой (хочу обратить сразу ваше внимание на
то что очень много настраиваемых параметров в C-- вынесены на уровень
деректив и опций трансляции).
Тепепер необходимо обрамить функции API MenuetOS inline функция, такие функции в C-- вставляются непосредственно в код (хотя есть ключ заставляющий генерировать их вызов командой call), превожу как пример вызов функции выхода
из процесса и функцию ожидания события, возращающую значение:
inline fastcall dword WaitEvent(){
#speed
EAX = 10; // wait here for event
$int 0x40
#codesize
}
Любая функция в C-- возращает значение через регистр EAX,AX,AL в зависимости от типа возращаемого значения DWORD, WORD, BYTE, соответственно. Определение fastcall в заголовке функции запрещает компилятору генерировать стандартный frame для размещения локальных переменных и делать любые манипуляции с кодом в начале функции и ее конце. Т.е. приведенная выше функция есть ни что иное как фрагмент в ассемблере
mov eax, 10;
int 0x40;
Поскольку функция inline генерация ret не производится.
#speed - ключ трансляции затсавляющий компилятор генерировать быстрый код, в противном случае передача значения в регистр была бы выполнена через стэк:
push 10 ; Операнд 10 есть байт расширяемый в стеке до dword
pop eax
Все эти нюансы легко расмотреть в формируемом LST файле выглядищим сл. образом:
menuet.h-- 71: EAX = 10; // wait here for event
00000029 B80A000000 mov eax,0Ah
menuet.h-- 72: $int 0x40
0000002E CD40 int 40h
inline fastcall void ExitProcess(){
#speed
EAX = -1; // close this program
$int 0x40
#codesize
}
Я специально оставил не оптимизированый код, что бы это выглядело как у Вилле, хотя гораздо быстрее и короче сделать так:
EAX = 0; // В этом случае компилятор ставит XOR EAX,EAX
EAX-- ;
,или так:
EAX = 0 - 1; // Запись выражения в C-- нестандартная нотация, а последовательность действий с лево на право.
Желательно проверять по листингу реальный размер кода, так
компилятор может вставить за меткой stop, необходимые ему служебные
таблицы потому заголовок приложения, не будет реально
соответствовать длине, потому необходимо держать на контроле
значение метки #stop. Кое-какие опцию могут помочь избавиться от
части кода которую компилятор может поместить за меткой stop.
#align 16
#setdinproc
#align 16
stop:
Данная последовательность заставляет макро-процедуры c--
(динамически вставляемый код при его вызове, для C-- это процедуры
имеющие : перед именем) вставляться в месте указанном #setdinproc.
Но таблицы jmp от case могут так-же расположиться за меткой stop,
пока ничего лучше вот этого я не придумал:
Прилагаю компилятор, которым я генерировал код примера example.c--
Так же стартап код (он необходим для запуска компилятора)
Небольшую библиотечку API функций menuet.h--
Библиотечку MeStdOut.h--
(вывод ноль терминированных строк с форматированием 0dh 0ah)
Прототип приложения MeFar - mefar.com (для запуска обрубите расширение файла)
Исходники MeFar - mefar.c--, fat.h--
Надеюсь Вы оцените всю мощь языка и компилятора, сайт которого находится по адресу www.sheker.narod.ru