flat assembler
Message board for the users of flat assembler.

Index > Main > How can I make a function that receives and sends parameters

Author
Thread Post new topic Reply to topic
luisvalencia



Joined: 08 Apr 2005
Posts: 1
luisvalencia 08 Apr 2005, 18:36
How can I do that?

for example that receves 2 float numbers and it returns the sum of those.
Post 08 Apr 2005, 18:36
View user's profile Send private message Reply with quote
Reverend



Joined: 24 Aug 2004
Posts: 408
Location: Poland
Reverend 10 Apr 2005, 10:02
Declare the function like:
Code:
      stdcall SomeKindOfProc,1,2,3

proc  SomeKindOfProc,  .arg1, .arg2, .arg3
      mov     eax,[.arg1]
      add     eax,[arg2.]
      sub     eax,[.arg3]
      return
endp
    

Of course such an example wouldn't work with floats. You'd have to process them witch coprocessor Smile But you must remember that arguments to functions are passed via stack, so you can have only 4 bytes (dword) pushed at once. Below is my macro to push qword values, but then you need to change code a little. Let me show you an example:
Code:
; macro for pushing qwords
macro pushq arg {
 local ARG1, ARG2
 db 0, 0
 dq arg
 load ARG1 dword from $-8
 load ARG2 dword from $-4
 store byte 68h at $-10
 store dword ARG2 at $-9
 store byte 68h at $-5
 store dword ARG1 at $-4
}    

Code:
; first version, pushing dwords
proc  Proc1,  .arg1
      fld     dword [.arg1]
      return
endp

      stdcall Proc1,1.0

; second version, pushing qwords
proc  Proc2,  .arg1, .dont_ever_use_this_var
      fld     qword [.arg1]
      retn    8
endp

      pushq   1.0      
      call    Proc2    

As you see, it's not fully "clean" solution. So I think, that it is better to push floats as dwords or just know, that values to pass are already in coprocessor register (i.e. load them before call). Or you can pass a pointer to float Smile
Code:
      stdcall Proc3, float1

proc  Proc3,  .ptr2float1
      mov     eax,[.ptr2float1]
      fld     qword [eax]
      return
endp

float1 dq 1.0    
Post 10 Apr 2005, 10:02
View user's profile Send private message Visit poster's website Reply with quote
Nikolay Petrov



Joined: 22 Apr 2004
Posts: 101
Location: Bulgaria
Nikolay Petrov 10 Apr 2005, 17:23
Code:
;tree = one+two
fld qword[first];entry first in st
fadd qword[two]; add st with two
fst qword[tree]; store result in tree. if you write fstp ... - you will store result and operation pop    


How to do that in function:
Code:
proc floatadd,arg1,.arg1,arg2,.arg2;result is arg1+arg2
      finit
      fld qword[arg1]
      fadd qword[arg2]
      return
endp

;in program
.........
;tree = one+two
stdcall floatadd,dword[one],dword[one+4],dword[two],dword[two+4]
fstp     qword[tree]; store result in tree    
Post 10 Apr 2005, 17:23
View user's profile Send private message Reply with quote
Yardman



Joined: 12 Apr 2005
Posts: 244
Location: US
Yardman 12 Apr 2005, 00:15
[ Post removed by author. ]


Last edited by Yardman on 04 Apr 2012, 02:05; edited 1 time in total
Post 12 Apr 2005, 00:15
View user's profile Send private message Reply with quote
rob.rice



Joined: 20 Dec 2003
Posts: 54
rob.rice 13 Apr 2005, 02:21
you could also use pointer kept in memory so all your subs would use the same pointers
Post 13 Apr 2005, 02:21
View user's profile Send private message Reply with quote
Vasilev Vjacheslav



Joined: 11 Aug 2004
Posts: 392
Vasilev Vjacheslav 14 Apr 2005, 10:04
my example:

Code:
format pe gui 4.0
entry start

include '%fasminc%\win32a.inc'

MAX_PATH                        = 260

EXCEPTION_MAXIMUM_PARAMETERS    = 15
MAXIMUM_SUPPORTED_EXTENSION     = 512
SIZE_OF_80387_REGISTERS         = 80

macro   m2m dest,src
{
        push    src
        pop     dest
}

struct FLOATING_SAVE_AREA
  .ControlWord          dd ?
  .StatusWord           dd ?
  .TagWord              dd ?
  .ErrorOffset          dd ?
  .ErrorSelector        dd ?
  .DataOffset           dd ?
  .DataSelector         dd ?
  .RegisterArea         rb SIZE_OF_80387_REGISTERS
  .Cr0NpxState          dd ?
ends

struct CONTEXT
  .ContextFlags         dd ?
  .iDr0                 dd ?
  .iDr1                 dd ?
  .iDr2                 dd ?
  .iDr3                 dd ?
  .iDr6                 dd ?
  .iDr7                 dd ?
  .FloatSave            FLOATING_SAVE_AREA
  .regGs                dd ?
  .regFs                dd ?
  .regEs                dd ?
  .regDs                dd ?
  .regEdi               dd ?
  .regEsi               dd ?
  .regEbx               dd ?
  .regEdx               dd ?
  .regEcx               dd ?
  .regEax               dd ?
  .regEbp               dd ?
  .regEip               dd ?
  .regCs                dd ?
  .regFlag              dd ?
  .regEsp               dd ?
  .regSs                dd ?
  .ExtendedRegisters    rb MAXIMUM_SUPPORTED_EXTENSION
ends

struct EXCEPTION_RECORD
  .ExceptionCode                dd ?
  .ExceptionFlags               dd ?
  .pExceptionRecord             dd ?
  .ExceptionAddress             dd ?
  .NumberParameters             dd ?
  .ExceptionInformation         rd EXCEPTION_MAXIMUM_PARAMETERS
ends

struct EXCEPTION_POINTERS
  .pExceptionRecord             dd ?
  .pContextRecord               dd ?
ends

struct struct_seh
  .org_esp         dd ?
  .org_ebp         dd ?
  .save_eip        dd ?
ends

section '.data' data readable writable

  szError       db "Unable to calculate FPU operation! Maybe your processor doesn't support FPU!"
  szNULL        db 0
  szFloat1      dd 2.0
  szFloat2      dd 3.3

  int_pointer   dd ?

section '.udata' readable writable

  seh           struct_seh
  szResult      dq ?

section '.code' code readable executable

  start:
        stdcall _calc,szFloat1,szFloat2,seh,szResult
        or      eax,eax
        jnz     @F

        invoke  MessageBox,NULL,szError,szNULL,MB_OK+MB_ICONHAND
        jmp     exit_prog

  @@:
        fld     dword [eax]
        mov     edx,int_pointer
        frndint
        fistp   dword [edx]

  exit_prog:
        invoke  ExitProcess,NULL

  proc  _calc, lpAddr1,lpAddr2,lpSEH,lpResult
        pushad
        mov     edi,[lpSEH]

        ; init seh
        mov     [edi+struct_seh.save_eip],.safe_place
        mov     [edi+struct_seh.org_ebp],ebp
        push    seh_proc
        push    dword [fs:0]
        mov     [edi+struct_seh.org_esp],esp
        mov     dword [fs:0],esp

        mov     esi,[lpAddr1]
        mov     edi,[lpAddr2]
        mov     eax,[lpResult]

        finit
        fld     dword [esi]
        fld     dword [edi]
        fadd    st0,st1
        fst     dword [eax]
        jmp     .out

  .safe_place:
        xor     eax,eax

  .out:
        mov     dword [esp+28+8],eax

        ; kill seh
        pop     dword [fs:0]
        add     esp,4
        popad
        return
  endp

  proc  seh_proc, pExcept,pFrame,pContext,pDispatch
        mov     esi,[pExcept]  ; EXCEPTION_RECORD
        mov     edi,[pContext] ; CONTEXT

        m2m     [edi+CONTEXT.regEip],[seh.save_eip]
        m2m     [edi+CONTEXT.regEsp],[seh.org_esp]
        m2m     [edi+CONTEXT.regEbp],[seh.org_ebp]
        xor     eax,eax
        return
  endp

section '.idata' import data readable writeable

  library       kernel32,'kernel32.dll',\
                user32,'user32.dll'

  include       '%fasminc%\apia\kernel32.inc'
  include       '%fasminc%\apia\user32.inc'

; eof
    
Post 14 Apr 2005, 10:04
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.