|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Июл 10, 2004 18:27:01 Доброе время суток! Я сейчас занимаюсь разработкой своей ОС на FASM. Ёё основой будет являться таблица системных функций с типом вызова fastcall. Для удобства я написал макросы invoke и proc, но с макросом proc проблемы. Вот исходники макросов:
rAX equ 0
rBX equ 1
rCX equ 2
rDX equ 3
rSI equ 4
rDI equ 5
macro invoke16 function, [arg]
{
register equ rAX
forward
if ~ arg eq
if register <= rDI
if register = rAX
mov ax,arg
end if
if register = rBX
mov bx,arg
end if
if register = rCX
mov cx,arg
end if
if register = rDX
mov dx,arg
end if
if register = rSI
mov si,arg
end if
if register = rDI
mov di,arg
end if
else
Display "Too many params."
% INVOKE ERROR %
end if
register equ register + 1
end if
common
call far [function]
}
macro proc16 name, [arg]
{
rg equ rAX
common
name:
forward
if ~ arg eq
if rg = rAX
arg equ ax
end if
if rg = rBX
arg equ bx
end if
if register = rCX
arg equ cx
end if
if register = rDX
arg equ dx
end if
if register = rSI
arg equ si
end if
if register = rDI
arg equ di
end if
if rg > rDI
Display "Too many params procedure."
% PROC ERROR %
end if
rg equ rg + 1
end if
common
}
Подскажите, как сделать нормальный макрос proc? |
|
|
Дата: Июл 10, 2004 20:25:02 XDEV86 fastcall и макросы штука не совместимая: proc16 func,p1,p2,p2 invoke16 func,dx,ax,[bx+si] invoke генерирует следующий код: mov ax,dx mov bx,ax mov cx,[bx+si] call func Макросами такое разрулить почти не реально. |
|
|
Дата: Июл 10, 2004 20:42:56 А я уж боялся, что меня опередили :-) Можно так:
B equ eax
BB equ ecx
BBB equ ebx
;количество букв В определяет номер параметра и его регистр
macro proc32 name,[arg]
{
common
name:
co fix B
forward
arg equ co
co fix co#B
};proc32
;endm
macro return32
{
ret
};return32
;endm
|
|
|
Дата: Июл 10, 2004 20:44:27 Да чуть не забыл, equ и fix обрабатываются в не зависимости от if - end if |
|
|
Дата: Июл 10, 2004 20:44:52 Да чуть не забыл, equ и fix обрабатываются в не зависимости от if - end if |
|
|
Дата: Июл 11, 2004 08:59:29 · Поправил: S_T_A_S_ Ещё один вариант, без invoke :) macro PROC name, [reg]
{ forward local arg
common
label name dword
macro name arg _%
forward if arg eq
'argument missed'
else
mov reg, arg
end if
common call [name] %_ }
_% fix {
%_ fix }
PROC foo, eax, ebx
PROC bar, ecx, edx, esi, edi, ebp
foo 0,2
bar 1,2,3,4,5 mov eax, 0
mov ebx, 2
call near [dword ds:XX]
mov ecx, 1
mov edx, 2
mov esi, 3
mov edi, 4
mov ebp, 5
call near [dword ds:XX] |
|
|
Дата: Июл 11, 2004 12:03:26 OK, большое спасибо! |
|
|
Дата: Июл 11, 2004 12:51:55 Мда, неудобно получается с fastcall'ом. Пробовал юзать stdcall, но моя ось будет работать в UnReal Mode, поэтому stdcall нужен 16-ти разрядный. 32-x разрядная версия не работает, а как сделать 16-ти что-то не очень понятно! Как можно реализовать stdcall 16? Подскажите, PLZ! Макрос (32bit):
macro proc name,[arg] ; define procedure
{ common
if used name
name:
all@args fix arg
virtual at bp+8
if ~ arg eq
reverse
first@args fix arg
forward
local ..arg
..arg dw ?
arg equ ..arg
common
end if
..ret = $ - (bp+4)
end virtual
local ..data,..size
if defined ..size
virtual at bp - ..size
else
if ..ret
push bp
mov bp,sp
end if
end if
..data:
macro enter size,level
_% if size eq & level eq
rb (2 - ($-..data) and 11b) and 11b
if defined ..size
..size = $ - ..data
end virtual
else
..size = $ - ..data
end if
if ..ret | defined ..size
push bp
mov bp,sp
if ..size
sub sp,..size
end if
end if
else
enter size,level
end if %_
macro return
_% if ..ret | defined ..size
leave
end if
if ..ret
retn ..ret
else
retn
end if %_ }
macro rstargs [arg]
{ restore arg }
macro endp ; end procedure definition
{ purge return
purge enter
macro rstargs#first@args _% %_
rstargs all@args
purge rstargs#first@args
end if }
macro stdcall proc,[arg] ; call procedure
{ reverse
push word arg
common
call proc }
macro invoke type,proc,[arg] ; invoke procedure (indirect)
{ common
if ~ arg eq
reverse
pushd arg
common
call type [proc]
else
call type [proc]
end if }
Тестовая функция: proc kprint,msg,len mov ax,msg mov cx,len call PrintString return endp При компиляции вылезает ошибка: mov ax,..arg?00001FA |
|
|
Дата: Июл 11, 2004 13:49:08 XDEV86 Для того чтобы загрузить в регистр значение, а не адрес, нужно делать так: mov ax,[msg]. ПО поводу макросов - вроде бы только 2 ошибки: virtual at bp+4 и rb (2 - ($-..data) and 1b) and 1b |
|
|
Дата: Июл 11, 2004 14:02:22 Спасибо. |
|
|
Дата: Июл 11, 2004 15:45:47 Млин, не работает :( Надо StdCall 16 (никаких eax,ebx и т.д, только ax,bx,bp,sp...)! |
|
|
Дата: Июл 11, 2004 17:02:21 XDEV86 В чём проблема-то, какая разница между eax & ax? На board.flatassembler.net ещё посмотрите, может поможет: http://board.flatassembler.net/viewtopic.php?t=1151&highlight= http://board.flatassembler.net/viewtopic.php?t=317&highlight= |
|
|
Дата: Июл 11, 2004 19:28:57 OK, Thanks! |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.051 |