0

I would like to compile a simple C project that has some externals functions defined in a ASM file. My main file is a C++ that calls some "extern "C"" functions that are defined in a assembly file.

When I run task "g++ build active file", I receive some warnings about the "extern" and some errors about functions defined in asm file telling "reference to my_funcions not defined".

My C++ file contains a "extern" like this:

[...]
extern "C" {
    // Subrutines en ASM
    void posCurScreenP1();
    void moveCursorP1();
    void openP1();
    void getMoveP1();
    void movContinuoP1();
    void openContinuousP1();
    void printChar_C(char c);
    int clearscreen_C();
    int printMenu_C();
    int gotoxy_C(int row_num, int col_num);
    char getch_C();
    int printBoard_C(int tries);
    void continue_C();
}
[...]

and my asm file contains this:

.586
.MODEL FLAT, C
; Funcions definides en C
printChar_C PROTO C, value:SDWORD
printInt_C PROTO C, value:SDWORD
clearscreen_C PROTO C
clearArea_C PROTO C, value:SDWORD, value1: SDWORD
printMenu_C PROTO C
gotoxy_C PROTO C, value:SDWORD, value1: SDWORD
getch_C PROTO C
printBoard_C PROTO C, value: DWORD
initialPosition_C PROTO C
.code   
[...]

Sure I'm doing some things wrong. Could you help me?

Thanks.

  • Please copy&paste the exact error messages or warnings to your question. Which compiler do you use? – Bodo Apr 03 '19 at 13:19
  • That asm source file looks like MASM syntax, I think. Definitely not GNU assembler directives or anything, so if you tried to build the asm with `g++` then yeah it will definitely fail. But without a [mcve], we don't know how you tried to build this or what errors you got. – Peter Cordes Apr 03 '19 at 14:14
  • The question is tagged with Visual Studio, but asks about g++. For Visual Studio, it may take a default to assemble .asm files in a project, but to avoid issues, I create an empty project, then "add existing files" to the project, and then for each .asm file, I click on properties, to include the file in the build, and add custom build steps to invoke the assmbler (ML.EXE or ML64.EXE). Command line for "x.asm" is "ml64 /c /Zi /Fo$(OutDir)\x.obj x.asm" (/Zi only for debug build). Output is "$(OutDir)\x.obj" . – rcgldr Apr 03 '19 at 16:49
  • No, it is tagged with "visual studio code" – Daniel Ruiz Molina Apr 04 '19 at 10:32

1 Answers1

2

hmm

so.c

extern "C" int fun ( void );
int x;
int main()
{
    x=fun();
    return x;
}

fun.c

int fun ( void )
{
    return(5);
}

build

gcc fun.c -O2 -c -o fun.o
g++ -O2 so.cpp fun.o -o so

No errors

00000000004003e0 <main>:
  4003e0:   48 83 ec 08             sub    $0x8,%rsp
  4003e4:   e8 17 01 00 00          callq  400500 <fun>
  4003e9:   89 05 45 0c 20 00       mov    %eax,0x200c45(%rip)        # 601034 <x>
  4003ef:   48 83 c4 08             add    $0x8,%rsp
  4003f3:   c3                      retq   


0000000000400500 <fun>:
  400500:   b8 05 00 00 00          mov    $0x5,%eax
  400505:   c3                      retq   

okay so

morefun.s

.globl fun
fun:
    mov $0x5,%eax
    retq

build

as morefun.s -o morefun.o
g++ -O2 so.cpp morefun.o -o so

no errors,

examine

00000000004003e0 <main>:
  4003e0:   48 83 ec 08             sub    $0x8,%rsp
  4003e4:   e8 0d 01 00 00          callq  4004f6 <fun>
  4003e9:   89 05 45 0c 20 00       mov    %eax,0x200c45(%rip)        # 601034 <x>
  4003ef:   48 83 c4 08             add    $0x8,%rsp
  4003f3:   c3                      retq   

0000000004004f6 <fun>:
  4004f6:   b8 05 00 00 00          mov    $0x5,%eax
  4004fb:   c3                      retq   

Still looks good, no problem adding assembly to a C++ project by making it look like a C function.

Other path

int fun ( void )
{
    return(5);
}

gnu and most other sane compilers compile to asm then call the assembler so you can just see how they do it and repeat that

gcc -O2 -S fun.c -o fun.s
as fun.s -o fun.o

cat fun.s

    .file   "fun.c"
    .section    .text.unlikely,"ax",@progbits
.LCOLDB0:
    .text
.LHOTB0:
    .p2align 4,,15
    .globl  fun
    .type   fun, @function
fun:
.LFB0:
    .cfi_startproc
    movl    $5, %eax
    ret
    .cfi_endproc
.LFE0:
    .size   fun, .-fun
    .section    .text.unlikely
.LCOLDE0:
    .text
.LHOTE0:
    .ident  "GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.11) 5.4.0 20160609"
    .section    .note.GNU-stack,"",@progbits

or use save-temps.

gcc -O2 -c -save-temps fun.c -o fun.o

to see the asm generated by the compiler

It is generally more painful to try to use compiled assembly as a starting point as is, cutting and pasting sure but there is a lot of overhead and the machine generated labels that you would want to clean up rather than start from scratch. (I prefer to disassemble and work from that than to use the compiler output directly)

old_timer
  • 69,149
  • 8
  • 89
  • 168
  • I have copied your simple sample and I have tried to compile it from Visual Studio Code. When I run my "gcc build active file" tasks, I receive this error: – Daniel Ruiz Molina Apr 08 '19 at 12:39