News:

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

Calling assembler from C++

Started by jj2007, May 27, 2011, 09:32:45 PM

Previous topic - Next topic

jj2007

This is not the first thread on "mixed programming", see here, but I encountered some problems which I'd like to share...

Here is a member of a library: 1)
include \masm32\MasmBasic\MasmBasic.inc
include MultiLib.inc

.code
RecallFile proc C MyFile:DWORD
Print Str$("File size=%i bytes, ", Lof(MyFile))
Recall MyFile, L$() ; load a text file
ret ; return the line count
RecallFile endp


This is called from C++ as follows:
#include "stdafx.h"
#include "stdio.h"
#pragma comment( lib, "D:\\masm32\\RichMasm\\Res\\MultiLib.lib" )

extern "C"
int __cdecl PrintaLine(const char * MsgText);
extern "C"
int __cdecl RecallFile(char * MsgText);

int _tmain(int argc, _TCHAR* argv[])
{
int lc;
char * TheFile="D:\\masm32\\include\\windows.inc";
lc=RecallFile(TheFile);
printf("Lines=%d\n", lc);
return 0;
}


Now the good news is: It works perfectly. The bad news is that it took me a while...

Problem #1: #pragma comment( lib, "D:\masm32\RichMasm\Res\MultiLib.lib" )
This simple statement links the assembler library to C. Or at least it should... but it throws 4 ugly error lines (you have to click on the scroll bar in the VC output window, because M$ C programmers don't know what word wrap is..):
Quotec:\documents and settings\user\documenti\visual studio 2010\projects\jjc\jjc\jjc.cpp(6): warning C4129: 'm' : unrecognized character escape sequence
Solution: What we call a backslash in Assembler is not understood well in C++... after a lot of googling, I found the solution: C needs two of them: "D:\\masm32\\RichMasm\\Res\\MultiLib.lib"
(note that VC wastes 400 MB on my harddisk - how many bytes does it need to check for single slashes in a string that looks like a filename, and issue a little warning...? Especially after the string throws an error??)

Problem #2: #pragma comment( lib, "D:\\masm32\\RichMasm\\Res\\MultiLib.lib" )
Now that worked perfectly, but Olly complained about an access violation somewhere in MasmBasic.lib.
So I reassembled the lib, recompiled the C++ proggie, and bang - Olly says hi again :boohoo:
Guess what? VC Express used the old version. So, assuming there was some cache playing foul, I renamed it. And yes, VC compiles fine, so it was the cache (although it takes ages to compile this handful of lines - that cache can't be very efficient...).
I spent some time trying ways to flush the mysterious VC library cache, no success. But Sherlock Holmes never gives up, so I asked "where the heck could VC find this code??" - and then I remembered I had a test installation on C:...
So what happens is:
- VC links correctly to D:\masm32\RichMasm\Res\MultiLib.lib
- inside that lib, there is a link to \masm32\MasmBasic\MasmBasic.lib
- but VC is so "clever" to look for it in its current drive... which is C: :green (gosh, the Forum lacks some really ugly emoticons!)

Problem #3: The access violation itself. When Recall doesn't find the file, it pops up a box saying no such file. Since this happens in a general runtime error routine, and error strings can become excessively large sometimes, I used a mov byte ptr [edx+400], 0 to avoid problems with MessageBox. And I used that on the string I was passed at that moment. No problem for Assembler, but C gets real angry if you poke around in its strings... ::)

Anyway, I have learnt a lot - in particular, that Assembler is a fantastic language, easy, concise, transparent, compact, intuitive, almost fool-proof, incredibly fast at assembly and runtime, ... :U

P.S.: New C-proof version of MasmBasic is here.
1) The library example is in \masm32\RichMasm\Res\SkelLib.asc; first line after start: is misspelled (libb) to trigger the runtime error, it works better with invoke RecallFile, chr$("MultiLib.inc"). Open the asc file in \masm32\RichMasm\richmasm.exe and hit F6 to build the library.

vanjast

You should be ashamed of yourself  :bg..
Trying to drag our 'church' into such 'ill-repute'  :green2

But otherwise good to know.. you know  :8)

baltoro

You know, Visual Studio really spoils you.
If you do what you have demonstrated above in Visual Studio,...it's alot easier (and, you don't even think about it).
You can just right click on the Project Name in the Solution Explorer,...and the IDE will open up a collection of property pages, where you can just select the 'Additional Dependencies' item,...then, you just click on the little browse button and navigate to your Library or DLL as the case may be, and the value is set correctly on the command line.
The double backslash for directory paths always creates an error for C++ programmers the first time you do it. I never quite understood it. ...I've used the double backslash (unintentionally) a number of times in assembly language (when working on a project where most of the code is in C++),...you'd think it would be more consistent. Strings that specify directory paths only use a single backslash for arguments on the command line,...but, in C++ source code, two backslashes are required.
...Also,...(and this is REALLY annoying),...a double forward-slash in C++ begins a single comment line,...whereas, the semi-colon begins a comment line in assembly language (and, in C++, a semi-colon must always terminate a source code statement,...I can't tell you how many times I've gotten that one totally backwards).
Baltoro

jj2007

Quote from: baltoro on May 28, 2011, 06:24:16 PM
You know, Visual Studio really spoils you.
If you do what you have demonstrated above in Visual Studio,...it's alot easier (and, you don't even think about it).
You can just right click on the Project Name in the Solution Explorer,...and the IDE will open up a collection of property pages, where you can just select the 'Additional Dependencies' item,...then, you just click on the little browse button and navigate to your Library or DLL as the case may be, and the value is set correctly on the command line

You forgot the irony tags :bdg

If I open my source code, I see on top either #pragma comment( lib, "D:\\masm32\\RichMasm\\Res\\MultiLib.lib" ) or, much better, include \masm32\MasmBasic\MasmBasic.inc

If I follow your "spoiled" suggestion, I have to click nine times to get the same infomation - provided I know already where exactly that info is hidden in that pile of, ehm, code called Visual C Express.

By the way, it takes roughly 600 milliseconds to assemble a small proggie in Masm, and less than 400 ms in JWasm. The same in Visual C takes between 10 and 25 seconds - it's Microsoft, Bloat Without the Power...

GregL

QuoteThe same in Visual C takes between 10 and 25 seconds - it's Microsoft, Bloat Without the Power...

No offense jj, but if it's taking that long then something is wrong.

Also let me suggest that if you really don't need C++ then just use C, it makes things a whole lot simpler.


jj2007

#5
Quote from: GregL on May 29, 2011, 01:37:10 AM
QuoteThe same in Visual C takes between 10 and 25 seconds - it's Microsoft, Bloat Without the Power...

No offense jj, but if it's taking that long then something is wrong.

It's not the fastest machine, a laptop with a Celeron M, but still...
>20 secs to load VC after a reboot
17 secs to see my handful of lines of code after clicking on the project
25 secs to see output after pressing Control F5 the first time
>5 secs to see output after pressing Control F5 and having added a space somewhere
>2 secs to see output after pressing Control F5 and having done nothing


Now in contrast the "Power without the Bloat" section:

<2 secs to start the editor (RichMasm) and load the asm code after a reboot
<1 sec to assemble, link, run and see the output the first time after a reboot with JWasm
<1 sec to assemble, link, run and see the output with JWasm the second time, of which 250 ms for assemble & link


QuoteAlso let me suggest that if you really don't need C++ then just use C, it makes things a whole lot simpler.
Will look into that option, thanks Greg.

hutch--

JJ,

I am getting a bit rusty here but from memory you can if you have to mix C and C++ as long as you know what you are doing. With MASM procedures you can use a C module in both directions, call a C module fom MASM or call a MASM module from C. I keep VC2003 with all of the C libraries as well as the SDK libraries set up so that if I need to play with some C code its easy to do. It makes it easy to test out some of the mountain of old C algos floating around on the internet as you can just build a C module and link it into a MASM test piece to test and time it.

It also means that you can build the current version of JWASM without relying on the posted binary. RE: Editor for VC2003, I use my own so there is no reason why you cannot use one of your own origin if the appallingly slow load time of the VCexpress editor pisses you off enough. If you need to play with the much later .NET and similar stuff you would get the current version of VS from Microsoft but from memory Japheth made the comment that the libraries for VS2010 were much slower than the earlier ones. Also note that if you want to use MSVCRT that you need a MSVCRT library from a very old version of VC so that you don't suffer side by side DLL problems. MSVCRT is on everything from patched versions of Win9x up to current where the side by side DLLs must be installed first.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php