I've tried a couple of "simple" but seemingly incomplete examples on the net
re how to incorporate STAND-ALONE asm files into C Builder projects but have singularly failed to get anything to work.
I'd welcome some help to get something working...ideally...a function that takes a parameter doubles it and spits it back...for e.g. a button to ShowMessage().
In the Build configuration Window...I saw Tasm there but no option to choose masm.
I'd also like to know...if I build masm obj files outside of C++ Builder (my preference)....how would I best link these in C++ Builder.
Any help much appreciated.
Hi bobl,
how about showing your code? You'll get better and more precise answers.
Gunther
i would think the simplest way is to create an OBJ file from the masm source, then link it with your program
does C++ Builder give you that kind of capability ?
Hi Bobl,
Welcome to the forum :icon14:
The standard way of doing this is to assemble the asm source and keep the obj file. Then you just declare the exported functions in your C or C++ code and add the obj file to the linker commandline.
Example:
#include <stdio.h>
#include <stdlib.h>
int MasmProggie(int, int);
int main(int argc, char* argv[])
{
int i=123; //just for fun
printf("Arg count=%d\n", argc);
printf("The product of argct and i: %d\n", MasmProggie(i, argc));
return 0;
}
Assembler:
include \masm32\include\masm32rt.inc
MasmProggie PROTO C :SDWORD, :SDWORD
.code
MasmProggie proc C x:SDWORD, y:SDWORD
mov eax, x
mul y
ret ; return value already in eax
MasmProggie endp
end
Gunther
That was fast! and yes that's a fair request...
I don't have my own code at the moment because I'm struggling to get the examples here working
i.e.
http://www.cpp-home.com/tutorials/291_1.htm
; MyCode.asm
.586p
model flat
locals
.DATA
.CODE
PUBLIC C MySubroutine
MySubroutine PROC C Arg1:DWORD, Arg2:DWORD
fld Arg1
fmul Arg2
ret
ENDP
END
I'm saying in my form module...
#include myasm.asm
extern "C" float MySubroutine(float Arg1,float Arg2);
and then in my form button routine
float Result = MySubroutine(FirstNumber,SecondNumber);
At first I got some linker fixup error and then the assembler complained about the first line i.e. the comment?
Does that help?
Dave...thank's for the suggestion.
I'd like to do things that way too. I can't believe BDS 2006 won't compile obj files but I'm afraid I don't know how.
Having said that...in searching today I came across a page of some book on google books that said Delphi doesn't like masm asm so I don't know. When I looked at the build configuration for my project...I could see Tasm there but no masm option.
jj2007
Thank you very much for the example code...
At the moment I've only used the IDE's build and run facility which insulates you from the nitty gritty of the linker
and I mostly use Powerbasic which again doesn't really expose you to the linker.
Does all that extern stuff become redundant?
I haven't tried this for ages but do remember getting a lot of help from this forum.
Quote#include myasm.asm
i think that's where the problem lies
it won't eat that asm code very well
you may need to put the OBJ in a static LIB
then, create a .h include file and link with the library :t
i should mention - i am not a C guy, nor am i a C++ Builder guy, either - lol
perhaps some of the other members have more experience with it, like Vortex
Yes
I don't feel at all confident including asm files.
I read somewhere that you just
create a file.asm
add it to your project using shift/f11
include a .h file that contains the asm procedure's declaration
and the thing builds at push of a button
It's not working for me so either I'm doing something wrong or it's not true.
Although I've tried a few examples today...I have got anything working and am all out of examples hence this post.
>Welcome to the forum :icon14:
Thank you very much!
I'm not new but haven't stopped by for ages although my skill level is as if I'm a newbie!
The last time Dave helped me a lot.
I am very interested in asm but don't get the time I'd like to study it.
>i am not a C guy, nor am i a C++ Builder guy,
That doesn't matter Dave...you're comments are always helpful and always get me there that much quicker.
that method probably works if your asm file uses TASM syntax
but, if you want to use MASM syntax, i think you'll have to link an OBJ or LIB
Hi Dave,
Quote from: dedndave on April 26, 2013, 05:13:29 AM
that method probably works if your asm file uses TASM syntax
but, if you want to use MASM syntax, i think you'll have to link an OBJ or LIB
TASM uses MASM syntax. The other point would be, if he would use TASM's IDEAL Mode syntax, but that's not the case.
Gunther
bobl,
you maybe search for an compiler (or IDE) specific forum to get the right tips, even people here happily mix C and C++ :P. Actual I would formulate your question in this way: does your linker support OMF or COFF object files and if so, how to add these to the link process.
Hi bobl,
QuoteActual I would formulate your question in this way: does your linker support OMF or COFF object files and if so, how to add these to the link process.
qWord is right. You would like to check Agner Fog's Object file converter :
http://agner.org/optimize/
I think that doesn't help our new member not very much.
I've checked your link from post #4. That tutorial isn't complete and doesn't explain very much. I know that Alex (Antariy) has some experiences with Borland's Builder. I've only an old machine in the basement with BC 4.0 installed. My proposal is: try to compile your program at the command line; an assembly language programmer has to master the command line.
Quote from: bobl on April 26, 2013, 04:42:57 AM
extern "C" float MySubroutine(float Arg1,float Arg2);
That source line is okay, because it avoids the name mangling and name decoration which is usual in C++.
Quote from: bobl on April 26, 2013, 04:42:57 AM
float Result = MySubroutine(FirstNumber,SecondNumber);
The function call is also okay. Delete now the the including #include myasm.asm. Try this line at the command line:
tasm /m2/q myasm.asm
The m2 switch allows 2 passes and the q switch suppresses OBJ records which are not needed for linking. The result should be myasm.obj.
Compile now your C++ source with bcc32.exe (or whatever EXE the Builder package provides) with the following command line:
bcc32 -c mysource.cpp
The -c switch is, compile, do not link. The result should be a mysource.obj.
Now link all together to the running EXE with the following command line:
tlink /3 mysource.obj myasm.obj, mysource.exe
The /3 switch ensures 32-bit linking.
A last advice: Since TASM is no longer supported, you should check the alternatives. There are a lot available: masm, jWasm, solasm, nasm, yasm etc. I hope that helps a bit.
Gunther
The problem is using the old Borland C++ builder, it needs a compatible OMF format object module that can be linked into the main application. Alternately the OMF module needs to be built into a library. I have not looked at TASM for about 15 years so i am not up to date with it but if you insist on using the old Borland builder, you will need to use an old copy of TASM or something that is compatible with it.
Dave, Gunther, qWord, Vortex, Hutch
Thank you for a great response.
Your example and suggestions have certainly given me some avenues to explore.
I'm determined to crack this and will post back when I've got something.
In the meantime...thank you all!
BTW
my Builder 2006 comes with Tasm from 1996...patched to 2002.
On the same wiki page it looks like the only Tasm compatible alternative (ideal mode) is Lazy Assembler from 2007.
Both look old.
I've just found out how to turn the command line on in the IDE...Here's the linker line for an empty vcl project
i.e. just the default blank form
Linker command line
-aa -Tpe -Gn -v -L"c:\program files\borland\bds\4.0\lib\debug";"c:\program files\borland\bds\4.0\lib";"c:\program files\borland\bds\4.0\lib\obj"
"c:\program files\borland\bds\4.0\lib\psdk";"c:\program files\borland\bds\4.0\Include\Indy9";"c:\program files\borland\bds\4.0\Lib\Indy9"
"C:\Documents and Settings\me\My Documents\Borland Studio Projects\bpl" -x -L"C:\Documents and Settings\me\My Documents\Borland Studio Projects"
-GA"C:\Documents and Settings\me\My Documents\Borland Studio Projects\vfs22.tmp"="C:\Documents and Settings\me\My Documents\Borland Studio
Projects\Project1.res" -GA"C:\Documents and Settings\me\My Documents\Borland Studio Projects\vfs23.tmp"="C:\Documents and Settings\me\My
Documents\Borland Studio Projects\Unit1.dfm" c0w32.obj vcl.bpi rtl.bpi vclx.bpi dbrtl.bpi vcldb.bpi adortl.bpi dbxcds.bpi dbexpress.bpi vclib.bpi
ibxpress.bpi xmlrtl.bpi vclactnband.bpi inet.bpi IntrawebDB_80_100.bpi Intraweb_80_100.bpi vclie.bpi inetdbbde.bpi inetdbxpress.bpi indy.bpi
bcbsmp.bpi soaprtl.bpi dsnap.bpi bcbie.bpi bdertl.bpi teeui.bpi teedb.bpi tee.bpi vcldbx.bpi memmgr.lib sysinit.obj "C:\Documents and Settings\me\My
Documents\Borland Studio Projects\Debug_Build\Project1.obj" "C:\Documents and Settings\me\My Documents\Borland Studio
Projects\Debug_Build\Unit1.obj","C:\Documents and Settings\me\My Documents\Borland Studio Projects\Debug_Build\Project1.exe","C:\Documents and
Settings\me\My Documents\Borland Studio Projects\Debug_Build\Project1.map",import32.lib cp32mti.lib,, "C:\Documents and Settings\me\My
Documents\Borland Studio Projects\vfs22.tmp"
At least it's a start.
Hi bobl,
Quote from: bobl on April 26, 2013, 04:50:06 PM
BTW
my Builder 2006 comes with Tasm from 1996...patched to 2002.
On the same wiki page it looks like the only Tasm compatible alternative (ideal mode) is Lazy Assembler from 2007.
Both look old.
that's the point. We've since 2002 a lot of development of the available instruction sets, which the TASM
don't know. You could, of course, hack in the new instructions via DB; it'll work, but it's very awkward. On the other hand, there are productive C and C++ compilers around (VC, gcc), which will that simple sources translate uncomplaining. You should think about that point and change the used tools.
Gunther
>it needs a compatible OMF format object module
I had to try and used the first example here i.e.
http://masm32.com/board/index.php?topic=1273.0
making it an obj file...and then including the obj into a vcl project using shift/F11.
As Hutch predicted I got...
[Linker Error] Error: 'C:\MY_DELPHI\MY_CBUILDER2006\PROJ3\MYASM.OBJ' contains invalid OMF record, type 0x4c (possibly COFF)
>We've since 2002 a lot of development of the available instruction sets
I don't doubt it and hadn't appreciated BCB's "out-of-dateness" re asm until yesterday.
Given it's from 2005...perhaps I should've have.
Thanks for the suggestions Gunther
Like Vortex suggested, Agner's objconv is an excellent tool to get OMF files from COFF :t.
getting warmer...
my tasm_bat.bat file to produce myasm.obj
@cls
@echo off
@echo ok tasm-ing...
cd C:\my_delphi\my_cbuilder2006\proj3
SET MY_PATH=C:\Program Files\Borland\BDS\4.0\Bin\
"%MY_PATH%\tasm32" /m2/q myasm.asm
cd \
produced the following output and an myasm.obj
ok tasm-ing...
Turbo Assembler Version 5.3 Copyright (c) 1988, 2000 Inprise Corporation
Assembling file: myasm.asm
Error messages: None
Warning messages: None
Passes: 1
[C:\]
I did a shift/F11 and "added" myasm.obj to the project
After adding it but before trying to use it...in Dave's terms...the linker seemed to "eat" it ok.
However I'm now getting this error
[Linker Error] Error: Unresolved external '_MySubroutine' referenced from C:\MY_DELPHI\MY_CBUILDER2006\PROJ3\DEBUG_BUILD\UNIT1.OBJ
after adding lines to the vcl code below to use the asm function.
Any ideas 'cos it's certainly looking more promising than it did.
#include "Unit1.h"
//#include "myasm.obj" <<=============not sure about this
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
extern "C" float MySubroutine(float Arg1,float Arg2);
void __fastcall TForm1::Button1Click(TObject *Sender)
{
float Result = MySubroutine(1,2);
ShowMessage(FloatToStr(Result));
}
The above was posted without seeing this...
>Like Vortex suggested, Agner's objconv is an excellent tool to get OMF files from COFF
Jibz, Vortex I missed that completely. Thank you very much both for suggesting it and drawing it to my attention.
I don't like the idea of being confined to Tasm and that looks like a lifeline.
I'm just looking at objconv now but suspect I'll have the same problem as I'm having at the moment
i.e. some kind of declaration omission.
Here's the assembler program
; MyCode.asm
.586p
model flat
locals
.DATA
.CODE
PUBLIC C MySubroutine
MySubroutine PROC C Arg1:DWORD, Arg2:DWORD
fld Arg1
fmul Arg2
ret
ENDP
END
Here's my assembling batch file
@cls
@echo off
@echo ok tasm-ing...
cd C:\my_delphi\my_cbuilder2006\proj3
SET MY_PATH=C:\Program Files\Borland\BDS\4.0\Bin\
"%MY_PATH%\tasm32" /m2/q myasm.asm
cd \
Here's the calling code in unit1.cpp
extern "C" float MySubroutine(DWORD Arg1,DWORD Arg2);
void __fastcall TForm1::Button1Click(TObject *Sender)
{
float res = 4;
res = MySubroutine(1,2);
ShowMessage(FloatToStr(res));
}
Here's the linker "line" after I've added myasm.obj using shift/F11
You can see on the last-but-one line that myasm.OBJ is in there like a 'goodun'
Linker command line
-aa -Tpe -Gn -v -L"c:\program files\borland\bds\4.0\lib\debug";C:\my_delphi\my_cbuilder2006\proj3;"c:\program files\borland\bds\4.0\lib";"c:\program
files\borland\bds\4.0\lib\obj";"c:\program files\borland\bds\4.0\lib\psdk";"c:\program files\borland\bds\4.0\Include\Indy9";"c:\program
files\borland\bds\4.0\Lib\Indy9";"C:\Documents and Settings\me\My Documents\Borland Studio Projects\bpl" -j -x -LC:\my_delphi\my_cbuilder2006\proj3
-GA"C:\my_delphi\my_cbuilder2006\proj3\vfs46.tmp"="C:\my_delphi\my_cbuilder2006\proj3\Project1.res"
-GA"C:\my_delphi\my_cbuilder2006\proj3\vfs47.tmp"="C:\my_delphi\my_cbuilder2006\proj3\Unit1.dfm" c0w32.obj vcl.bpi rtl.bpi vclx.bpi dbrtl.bpi
vcldb.bpi adortl.bpi dbxcds.bpi dbexpress.bpi vclib.bpi ibxpress.bpi xmlrtl.bpi vclactnband.bpi inet.bpi IntrawebDB_80_100.bpi Intraweb_80_100.bpi
vclie.bpi inetdbbde.bpi inetdbxpress.bpi indy.bpi bcbsmp.bpi soaprtl.bpi dsnap.bpi bcbie.bpi bdertl.bpi teeui.bpi teedb.bpi tee.bpi vcldbx.bpi
memmgr.lib sysinit.obj C:\my_delphi\my_cbuilder2006\proj3\Debug_Build\Project1.obj C:\my_delphi\my_cbuilder2006\proj3\Debug_Build\Unit1.obj
C:\my_delphi\my_cbuilder2006\proj3\myasm.OBJ,C:\my_delphi\my_cbuilder2006\proj3\Debug_Build\Project1.exe,C:\my_delphi\my_cbuilder2006\proj3\Debug_Build\Project1.map,import32.lib
cp32mti.lib,, C:\my_delphi\my_cbuilder2006\proj3\vfs46.tmp
and it all compiles and runs fine as long as I comment out the line in the calling code...res = MySubroutine(1,2);
Once I comment that in I get error
[Linker Error] Error: Unresolved external '_MySubroutine' referenced from C:\MY_DELPHI\MY_CBUILDER2006\PROJ3\DEBUG_BUILD\UNIT1.OBJ
I'm missing something but don't know what.
it seems to have "decorated" the symbol with an underscore
it's probably that way in the OBJ
there are ways to make it not decorate, or you can just call it with the decorated name
extern "C" float _MySubroutine(DWORD Arg1,DWORD Arg2);
void __fastcall TForm1::Button1Click(TObject *Sender)
{
float res = 4;
res = _MySubroutine(1,2);
ShowMessage(FloatToStr(res));
}
i may have it backwards - lol
it isn't decorating it and it expects it to be
It was certainly worth a try...I tried it with one and two underscores but get the same error.
You probably just have to add option -mx when assembling your Myasm.asm with tasm.
Don't know whether this is helpful - here is a minimalistic example how to call the sub from C and C++. Works with Pelles C and VC++ 2010 Express...
C++
#include <stdio.h>
#include <tchar.h>
extern "C" float MySubroutine(float Arg1,float Arg2);
int _tmain(int argc, _TCHAR* argv[])
{
fprintf(stderr, "Res=%f\n", MySubroutine(20.0, 5.0));
return 0;
}
Masm:
.586p
.model flat
MySubroutine PROTO C Arg1:DWORD, Arg2:DWORD
.CODE
MySubroutine PROC C Arg1:DWORD, Arg2:DWORD
fld Arg1
fmul Arg2
ret
MySubroutine ENDP
END
Note that C++ and Masm agree that DOUBLE and REAL4 aka "float" are basically the same, as long as you use fld and fmul instead of fild and fimul :icon_mrgreen:
Japeth
-mx is spot on. It works great now! That's a real relief. Thank you very much indeed.
jj2007
Double good news...As a result of your prompt re Vortex's advice (that I'd previously missed)
I revisited the first example here
http://masm32.com/board/index.php?topic=1273.0
i.e. that BCB2006 wouldn't eat in reply 16 and obj_conv'd it with....
@cls
@echo off
@echo ok objconv-ing...
cd C:\my_delphi\my_cbuilder2006\proj3
SET MY_PATH=C:\Documents and Settings\me\My Documents\Downloads\objconv\
"%MY_PATH%\objconv" -fomf -nu mymasm.obj myomfdmasm.obj
cd \
Now the linker does eat it.
I didn't try calling it because I wasn't sure how so your example showing how to call such procedures is just the job.
Again...thank you very much indeed.
What a great forum this is!
Hi bobl,
Another option to convert OMF to COFF is to use MS link.exe :
\masm32\bin\link -edit objectfile.obj
objectfile.obj : warning LNK4033: converting object format from OMF to COFF
you can also use masm to create an OMF, using /omf switch
Vortex, Dave
I'm sure there's safety in numbers re this sort of conversion so...thanks for the alternatives.
They're very much appreciated and give me more chance of being able to use Masm in it's own environment
for development which is my preference.
jj2007
I just removed the tasm.obj file, replaced it with the objconv'd assembled version of your example above and...
it worked flawlessly. Looks like were "in business". Thank for your help. It's very much appreciated.
Great to see it worked :t
I'd like to try the masm /omf switch, above, when assembling .asm files.
I looked in the
ml.exe-options-command line tools- masm32 help file of c:\masm32\help
but don't see it there...only coff.
Additionally I used the
Project-Assemble asm file option of the masm32 editor to assemble the file
and don't know what the command line for this looks like.
Could someone please outline what I should be using.
Thank you in anticipation.