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

 WASM Phorum —› WASM.ASSEMBLER —› FASM и fastcall

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