Hi there,

i'm new to masm32 and have a little problem,

I'd like to make code pieces in masm, compile it
and then would link these into my delphi app.
(Don't like to make dll :) )

I assemble these without the /coff option coz
delphi works only with OMF and i made the proc
public, and after creating *.obj in this matter
delphi 'likes' that file.
But it doesn't import or found the proc.
At deklaration of the proc in delphi it says it
cant find the external, but the *.obj is acceptet
when assembling it without /coff.

;######## the asm code ############

.386
.model flat,stdcall

PUBLIC FindSub

.code
GetVal PROC
mov eax, 30
ret
GetVal ENDP

END

;###### the makeit ###########

ml /c /Cp test.asm


;########### in delphi ############
{$L test.obj}
procedure GetVal; external;


Can someone help me with this?
Posted on 2001-07-19 11:43:56 by Cio
I'm not too familier with Delphi, but I do know that it is based on pascal. Therefore I would assume the default calling convention is pascal :tongue: !

I notice that you've declared in your code that your function is using the stdcall, and not pascal calling convention. It may be a simple case of changing the code in either Delphi to reflect the stdcall nature of your function, or chainging your function to pascal (which I believe MASM supports).

I could however be entirely wrong!

----------------------------------------------------------------------------
extra:

Your code defines FindSub as public, not your function!

Try:


.code

GetVal PROC STDCALL PUBLIC
mov eax, 30
ret
GetVal ENDP


Obviously change the "STDCALL" to "PASCAL" in the above
example, to change the calling convention.

I'm still unsure of how to arrange the external definition in
the Delphi code though.
----------------------------------------------------------------------------

Mirno
Posted on 2001-07-19 12:18:46 by Mirno
Cio,

Changing

.model flat, stdcall
PUBLIC FindSub

to

.model flat, pascal
PUBLIC GetVal

will do the job.

Jones.
Posted on 2001-07-19 13:56:34 by sjhenry
Thanks for your help,

but it doesnt really works complete.
A little success was when i'm using the langtype pascal,
but with these are 2 new problems.

1.) It accepts only 1 Proc. Even when i create more than one
proc, label or whatever in delphi was only the first (by name)
recognized and for all others i got the same error as before. :(
but the really funny its that delphi linked all others from obj
to the exe wich i can see in disassembly but only accepts 1 name,
dunno whats my failure is ...

2.) If i must use the pascal calling convention (wich i wont) then these
could easy crash when u have a proc with args (see below).
This is coz the original 'pascal calling convention' wich is used
by masm is deklared as push the args from left to right on the stack
when calling instead of 'stdcall' there is a push from right ti left,
BUT delphi i.e. calls with some args in some registers ...


;####### delphi #######
//Deklaration
{$L test.obj}
function FindSub(i,j:dword):integer; external;

//Call
i:=FindSub(i,i);


;####### masm #######
.386
.model flat, pascal

PUBLIC FindSub

.code
FindSub PROC i:DWORD, j:DWORD
mov eax, i
mov eax, j
mov eax, 31
ret
FindSub ENDP



;####### disassembled #######
the disassembled call from delphi
mov edx, ebx ;var i !!! not pushed but delivered trough seg ebx
mov eax, ebx ;var i
call sub_426570 ;FindSub
mov ebx, eax ;function result

;disassemble asm function FindSub
00426570 push ebp
00426571 mov ebp, esp
00426573 mov eax, ;wants the arg on stack
00426576 mov eax,
00426579 mov eax, 1Fh
0042657E leave
0042657F retn 8 ;and clear the 2 args from stack
Posted on 2001-07-20 12:14:39 by Cio
Cio,

Borland compilers use another mothod of calling
convention. That's called fast call using register. The main point here is
Borland compiler expect first parameter in eax, second in edx, third one in ebx and rest in stack.
Now you have to change your code appropriately
inside your FindSub PROC.

In FindSub procedure, the param "i" will be in eax
inside FindSub procedure and param "j" will be in edx inside
FindSub procedure.

Also you can call some Delpi module from MASM using the following macro assuming you can
translate it into MASM syntax.



%macro fastcall 2-9 ;Borland FastCall: use registers, no cleanup
%define _j %1
%assign __pnum 1
%rep %0-4
%rotate -1
%if __pnum = 1
mov eax, %1
%elif __pnum = 2
mov edx, %1
%elif __pnum = 3
mov ebx, %1
%else
push %1
%endif
%assign __pnum __pnum+1
%endrep
call _j
%endmacro
Posted on 2001-07-20 12:33:56 by sjhenry
You can also declare your procedure in Delphi as a 'Pascal', e.g:
Procedure GetVal (Arg:LongWord);Pascal;external;
{$L your.OBJ}
This will make Delphi to expect all parameters in the stack.
You must also preserve most of the registers, since when Optimizations are turned ON (by default), Delphi stores most of addresses in registers and doesn't care about your proc.....
Posted on 2001-07-21 14:44:43 by ivogelov