Steven
Steven

Reputation: 576

Accessing functions in an ASM file from a C++ program?

Over here I asked about translating an ASM file to C, and from the responses it looked like there was no reasonable way to do it. Fine. So one of the responses suggested I just make use of the functions as-is and be done with it. Sounds good.

But how?

Holy crap I've tried everything I can think of! I'm using a Microchip brand MCU (PIC18F4480) and a Microchip brand IDE (MPLAB IDE) and the ASM files are Microchip authored... so you'd think I'd find some way of making use of them! So far no luck at all.

I don't know anything about ASM (Assembly). I code in C++ and frankly that's not going to change. There has got to be a way to access the functions in the Microchip ASM files without rewriting all my code in a new language.

If anyone wants to take a look, the ASM files and application notes are here.

Upvotes: 0

Views: 3051

Answers (3)

Chris Becke
Chris Becke

Reputation: 36016

The usual method is to use a build environment and tools that has an assembler as well as a C/C++ compiler. Compilers (and assemblers) take source files and produce an intermediate object file format. On Microsoft Windows, with Microsoft Tools, these would be .obj files.

A linker is then used to link the .obj files - which were potentially produced by a wide variety of languages - fortran, cobol, c++, c, objective-c, assembly etc, into a single application binary.

Object files are basically a collection of exported symbols, labeling little chunks of bytes, and unresolved symbols, labeling chunks of bytes that need to be patched during linking to point to something in a different object file.

Now, the usual problem - on the platforms Ive experienced which are not close to yours, are, c++ compilers are not made with any kind of cross language binary compatibility in mind. C compilers on the other hand, are. So c++ compilers make highly mangled symbols that incorporate all sorts of information about parameter and return types into the symbol names. This mechanism is what makes operator overloading possible.

Anyway, the crux is,

  • You need to build the asm files. If you dont have an assembler, you're outa luck. And it probably needs to come from the same vendor as your c/c++ toolset
  • You need to tell your c++ program the names of the external symbols. In a c compatible way. This is what header files are typically used for.

So create a header file to hold function declarations for the pid code and place Something like this in them:

extern "C" void PidMain(void);

Now, #include that header file in your c++ program, and ensure that the object files produced by the assembler are included in your environments link step and you should be golden.

There might be some kind of calling convention involved. Some environments have different standards as to the order things are pushed onto the stack, and/or who is responsible for stack cleanup. Most ms windows toolsets support at least a __pascal and __cdecl calling convention, so the declration would look like

extern "C" void __pascal PidMain(void);

I have no specific knowledge if there are multiple calling conventions in your specific environment. So I don't know how helpful this has been. Good luck I guess.

Upvotes: 2

Martin v. Löwis
Martin v. Löwis

Reputation: 127447

Looking at PIDInt.asm, it should be fairly straight-forward to call the functions from C/C++. First, you declare extern variables for everything listed in VARIABLE DEFINITIONS:

extern unsigned char error0, error1; /* etc */

Then, you declare extern functions for all the things that have a "Function:" comment, taking no arguments and returning no result:

extern void Proportional(); // extern "C" for C++

To call one of them, you fill the input variables, call the function, and read the output variables.

Upvotes: 6

unwind
unwind

Reputation: 399703

I would expect you to need to somehow build an object (.o) file from the assembly code, and then link your C++ file with that object file. You are likely going to need to declare those functions as extern "C" to call them from C++.

Not sure about the details here, there might be issues with calling conventions between C++ and assembly, especially for a microcontroller such as the PIC.

Are you really using a full C++ feature set, i.e. objects, virtual functions, overloading, and so on, for a microcontroller? That's ... not bad, but I thought most PIC development was still in plain C (and assembly, of course).

Upvotes: 5

Related Questions