Linking Assembly and C/C++

CS 301: Assembly Language Programming Lecture, Dr. Lawlor

Here's how you write an entire function in assembly.  The "global bar" keyword in assembly tells the assembler to make the function name "bar" visible from outside the file.

global bar
bar:
add rdi,1000
mov rax,rdi
ret

(Try this in NetRun now!)

The "Link With:" box (under "Options") tells NetRun to link together two different projects, in this case one in C++ and the other in assembly.  This C++ code calls the assembly here.

extern "C" int bar(int param);

int foo(void) {
return bar(6);
}

(Try this in NetRun now!)

You can call C++ code from assembly almost as easily, by making the C++ code extern "C", using "extern someName" in assembly, and then call the function normally.

Mixed Assembly and C++ at the Command Line

The most portable way to include some assembly functions in your code is to compile the assembly in a separate file, then link it with the C++.  For example, in a file name "foo.S":

section .text
global _foo
_foo:
mov eax,7
ret

(Note the weird underscore in front of the function name--the compiler adds these on Windows and OS X, but not Linux.)

You'd assemble this into "foo.obj" on windows with this command line:

    nasm -f win32 foo.S

Then in a file named "main.cpp", we call foo with an extern "C" prototype:

#include <iostream>
extern "C" int foo(void);

int main() {
std::cout<<"Foo returns "<<foo()<<"\n";
return 0;
}

We compile the C++ and link it to the assembly using the Microsoft Visual C++ compiler like this:

    cl -EHsc main.cpp foo.obj

(You may have to run "vc_vars.bat" to get "cl" into your PATH.)

We now have a functioning C++/Assembly executable!  The same exact command-line trick works on Linux or OS X with gcc.  If you don't like the command line, and few people do (except me!), you can hide the NASM command line inside Visual C++ as I explain here.