Skip to main content
Engineering LibreTexts

14.3: Interfacing with a High-Level Language

  • Page ID
    19948
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \) \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)\(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\) \(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\)\(\newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    This section provides information on how a high-level language can call an assembly language function and how an assembly language function can call a high-level language function. This chapter presents examples for both.

    In brief, the answer of how this is accomplished is through the standard calling convention. As such, no additional or special code is needed when interfacing with a high-level language. The compiler or assembler will need to be informed about the external routines in order to avoid error messages about not being able to find the source code for the non-local routines.

    The general process for linking for multiple files was described in Chapter 5, Tool Chain. The process of using multiple source files was described in Chapter 14, Multiple Source Files. It does not matter if the object files are from a high-level language or from an assembly language source.

    Example, C++ Main / Assembly Function

    When calling any functions that are in a separate source file, the compiler must be informed that the function or functions source code are external to the current source file. This is performed with an extern statement in C or C++. Other languages will have a similar syntax. For a high-level language, the extern statement will include the function prototype which will allow the compiler to verify the function parameters and associated types.

    The following is a simple example using a C++ main with an assembly language function.

    #include <iostream>
    using namespace std;
    extern "C" void stats(int[], int, int *, int *);
    
    int main() 
    { 
        int lst[] = {1, -2, 3, -4, 5, 7, 9, 11}; 
        int len = 8;
        int sum, ave; 
        stats(lst, len, &sum, &ave);
    
        cout << "Stats:" << endl;
        cout << "  Sum = " << sum << endl;
        cout << "  Ave = " << ave << endl;
    
        return 0; 
    } 
    

    At this point, the compiler does not know the external function is written in assembly (nor does it matter).

    The C compiler is pre-installed on Ubuntu. However, the C++ compiler is not installed by default.

    A C version of the same program is also presented for completeness.

    #include<stdio.h>
    extern void stats(int[], int, int *, int *);
    
    int main() 
    { 
        int lst[] = {1, -2, 3, -4, 5, 7, 9, 11}; 
        int len = 8;
        int sum, ave;    
        stats(lst, len, &sum, &ave);    
        printf ("Stats:\n");
        printf ("  Sum = %d \n", sum);
        printf ("  Ave = %d \n", ave);
        return 0; 
    } 

    The stats() function referenced here should be used unchanged from the previous example.

    Compile, Assemble, and Link

    As noted in the Functions Chapter, the C++ compiler should be used. For example, assuming that the C++ main is named main.cpp, and the assembly source file is named stats.asm, the commands to compile, assemble, link, and execute as follows:

           g++ -g -Wall -c main.cpp
           yasm -g dwarf2 -f elf64 stats.asm -l stats.lst
           g++ -g -o main main.o stats.o
    

    Note, Ubuntu 18 will require the no-pie option on the g++ command as shown:

           g++ -g -no-pie -o main main.o stats.o

    The file names can be changed as desired. Upon execution, the output would be as follows:

           ./main
           Stats:
             Sum = 30 
             Ave = 3 

    If a C main is used, and assuming that the C main is named main.c, and the assembly source file is named stats.asm, the commands to compile, assemble, link, and execute as follows:

           gcc -g -Wall -c main.c
           yasm -g dwarf2 -f elf64 stats.asm -l stats.lst
           gcc -g -o main main.o stats.o
    

    Note, Ubuntu 18 will require the no-pie option on the gcc command as shown:

           gcc -g -no-pie -o main main.o stats.o 

    The C compiler, gcc, or the C++ compiler, g++, is used to perform the linking as it is aware of the appropriate locations for the various C/C++ libraries.


    This page titled 14.3: Interfacing with a High-Level Language is shared under a CC BY-NC-SA license and was authored, remixed, and/or curated by Ed Jorgensen.

    • Was this article helpful?