I have a simple hello world C program and compile it with /FA. As a consequence, the compiler also generates the corresponding assembly listing. Now I want to use masm/link to assemble an executable from the generated .asm listing.
The following command line yields 3 linker errors:
\masm32\bin\ml /I"C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include" /c /coff asm_test.asm
\masm32\bin\link /SUBSYSTEM:CONSOLE /LIBPATH:"C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\lib" asm_test.obj
indicating that the C-runtime functions were not linked to the object files produced earlier:
asm_test.obj : error LNK2001: unresolved external symbol @__security_check_cookie@4 asm_test.obj : error LNK2001: unresolved external symbol _printf LINK : error LNK2001: unresolved external symbol _wmainCRTStartup asm_test.exe : fatal error LNK1120: 3 unresolved externals
Here is the generated assembly listing
; Listing generated by Microsoft (R) Optimizing Compiler Version 15.00.30729.01
TITLE c:\asm_test\asm_test\asm_test.cpp
.686P
.XMM
include listing.inc
.model flat
INCLUDELIB OLDNAMES
PUBLIC ??_C@_0O@OBPALAEI@hello?5world?$CB?6?$AA@ ; `string'
EXTRN @__security_check_cookie@4:PROC
EXTRN _printf:PROC
; COMDAT ??_C@_0O@OBPALAEI@hello?5world?$CB?6?$AA@
CONST SEGMENT
??_C@_0O@OBPALAEI@hello?5world?$CB?6?$AA@ DB 'hello world!', 0aH, 00H ; `string'
CONST ENDS
PUBLIC _wmain
; Function compile flags: /Ogtpy
; COMDAT _wmain
_TEXT SEGMENT
_argc$ = 8 ; size = 4
_argv$ = 12 ; size = 4
_wmain PROC ; COMDAT
; File c:\users\octon\desktop\asm_test\asm_test\asm_test.cpp
; Line 21
push OFFSET ??_C@_0O@OBPALAEI@hello?5world?$CB?6?$AA@
call _printf
add esp, 4
; Line 22
xor eax, eax
; Line 23
ret 0
_wmain ENDP
_TEXT ENDS
END
I am using the latest masm32 version (6.14.8444).
Update:
As suggested by Cogwheel, I included an INCLUDELIB msvcrt.lib
in the asm source. The program compiles and an executable is created, but the linker generates a warning:
msvcrt.lib(crtmanifestrtm.obj) : warning LNK4044: unrecognized option "manifestdependency:type='win32' name='Microsoft.VC90.CRT' version='9.0.21022.8' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b'"; ignored
When i start the executable, the C runtime generates the following error:
Runtime error: R6034 An application has made an attempt to load the C runtime library incorrectly
For this go to project settings -> C/C++ -> Output Files -> ASM List Location and fill in file name. Also select "Assembly Output" to "Assembly With Source Code".
Master C and Embedded C Programming- Learn as you go The gcc provides a great feature to get all intermediate outputs from a source code while executing. To get the assembler output we can use the option '-S' for the gcc. This option shows the output after compiling, but before sending to the assembler.
Right-click Project, Build customizations, tick "masm". Right-click the . asm file, Properties, change Item Type to "Microsoft Macro Assembler".
Luckily, gcc does not output binary machine code directly. Instead, it internally writes assembler code, which then is translated by as into binary machine code (actually, gcc creates more intermediate structures). This internal assembler code can be outputted to a file, with some annotation to make it easier to read.
I did this recently. It turns out you can still do this in 32-bit mode in MSVC2012 but I think 64-bit mode is hopeless.
For 32-bit mode here is what you do.
Create an empty project and a source file Source.cpp
#include <stdio.h>
int main() {
printf("hello world\n");
return 0;
}
/GL
). This adds the line INCLUDELIB MSVCRT
/SAFESEH:NO
)I have used this for more complicated functions. I usually do it on a separate module and use extern "C"
on the function name to remove the C++ name mangling.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With