c++assemblymasmmasm64

Facing fatal error while linking cpp code with assembly code


I am trying to assemble a small piece of assembly code using MASM and then link it with a C++ program. Here is the assembly code:

    .code

    option casemap:none

    public asmFunc

asmFunc PROC
    ret ;
asmFunc ENDP
        END

And here is the cpp code:

#include <stdio.h>


extern "C" {
    void asmFunc(void);
}

int main() {
    printf("Calling asm main!");
    asmFunc();
    printf("Returned from asm!");
    return 0;
}

Then I successfully assembled the assembly code using ml64 /c first.asm. A .obj file was created.

Then I expected that I can easily link the code using cl first.cpp first.asm but unfortunately I ran into this error:


C:\Users\jarzi\Videos\Programs\c programs\assem1>cl first.cpp first.asm          
Оптимизирующий компилятор Microsoft (R) C/C++ версии 19.00.24215.1 для x64
(C) Корпорация Майкрософт (Microsoft Corporation).  Все права защищены.

cl: командная строка warning D9024: нераспознанный тип исходных файлов "first.asm", использование объектного файла
first.cpp
first.cpp(1): fatal error C1034: stdio.h: не указан путь поиска включаемых файлов


Solution

  • A linker does not link code, it links object files.

    In principle, you need to do the following:

    1. Invoke your assembler to assemble your .asm file into an .obj file
    2. Invoke your compiler to compile your .cpp file into another .obj file
    3. Invoke your linker to link the two .obj files together and produce an executable.

    Now, the cl command of the Microsoft Visual C/C++ compiler mixes the capabilities of both a compiler and a linker, so you may be able to skip one of the above steps, but in order to use it, you need to be aware of the following:

    1. You can use cl to compile .cpp files, but you cannot use it to assemble .asm files. (Source) You have to use ml for that, and then give cl the resulting .obj file.

    2. You better give your source files different names, otherwise your first.cpp will yield first.obj, and then your first.asm will also yield first.obj, so the second first.obj will overwrite the first first.obj, so there will never be two separate .obj files to link.