News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Declaring and using own user functions.

Started by etow, February 20, 2008, 06:45:52 PM

Previous topic - Next topic

etow

Hi

I know how to write procedures but how do I write my own functions and return that returns values?
I believe they are similar to procedures but I am not sure how to declare them as?
Do I use a macro?

Please help.

Tedd

There's no separation between procedures and functions in asm - they're both the same!
To return a value just place it in eax before you ret. That's it - so simple :wink
(Technically you can use any register or mechanism, but eax is conventional - and most of the other functions you encounter will do the same.)
Then, whoever calls that function (including yourself) knows the return value was stored in eax and can easily use it.

returnOne proc
    mov eax,1
    ret
returnOne endp

No snowflake in an avalanche feels responsible.

Vortex

Hi etow,

Here is a quick example for you :

.386
.model flat, stdcall
option casemap:none

include     Myfunc.inc

myfunc      PROTO :DWORD,:DWORD

.data
format db   'f(x,y)=2*x+4*y+1',13,10
db          'f(4,3)=%d',13,10,0

.data?
buffer db 100 dup(?)

.code

start:

    invoke  myfunc,4,3
    invoke  wsprintf,ADDR buffer,ADDR format,eax
    invoke  StdOut,ADDR buffer
    invoke  ExitProcess,0

myfunc PROC x:DWORD,y:DWORD

    shl     x,1   ; multiply by 2
    shl     y,2   ; multiply by 4
    mov     eax,x
    add     eax,y
    inc     eax
    ret
   
myfunc ENDP

END start

[attachment deleted by admin]

MichaelW

#3
And for floating-point values the convention used by the C Runtime Library (CRT) is to leave the return value in ST(0). This method provides 2 advantages:

Further FPU operations can be performed on the value without having to load it into the FPU.

Since values in the FPU are stored as REAL10, when the time comes to store the value in memory, to display it for example, it can be stored with a single FPU instruction as a REAL10, REAL8, or REAL4.

This example code calculates and displays the square root of pi to 15 decimal places, using first the CRT sqrt function, and then a local sqrt function. The CRT printf function provides a convenient way to display the result. The floating-point values are stored as type REAL8 because this is the most precise floating-point type that the CRT can handle.

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    .data
      pi REAL8 3.1415926535897932 ; pi to 16 decimal places
      r8 REAL8 0.0                ; storage for return value
    .code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
sqrt proc x:REAL8
    fld x
    fsqrt
    ; ---------------------------
    ; Leave return value in ST(0)
    ; ---------------------------
    ret
sqrt endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

    invoke crt_sqrt, pi
    fstp r8
    invoke crt_printf, chr$("%.15f%c"), r8, 10

    invoke sqrt, pi
    fstp r8
    invoke crt_printf, chr$("%.15f%c"), r8, 10

    inkey "Press any key to exit..."
    exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start


In case it's not obvious, invoke can pass floating-point parameters "by value" on the stack, as was done for the r8 parameter of crt_printf.

EDIT: Values stored in the FPU cannot just be stored to memory as real numbers, but as any data type that the FPU can store, and this includes 16, 32, and 64-bit signed integers, and Binary Coded Decimal (BCD) integers.
eschew obfuscation

etow