我有一个简单的hello world C程序并用/ FA编译。因此,编译器还会生成相应的程序集列表。现在我想使用masm / link从生成的.asm列表中组装可执行文件。
以下命令行产生3个链接器错误:
\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
表示C运行时函数未链接到先前生成的目标文件:
asm_test.obj:错误LNK2001: 未解决的外部符号 @__ security_check_cookie @ 4 asm_test.obj:错误LNK2001: 未解析的外部符号_printf 链接:错误LNK2001:未解决 外部符号_wmainCRTStartup asm_test.exe:致命错误LNK1120:3 未解决的外部因素
以下是生成的装配清单
; 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
我使用的是最新的masm32版本(6.14.8444)。
更新:
根据Cogwheel的建议,我在asm源中包含了INCLUDELIB msvcrt.lib
。程序编译并创建可执行文件,但链接器会生成警告:
msvcrt.lib(crtmanifestrtm.obj):警告LNK4044:无法识别的选项“manifestdependency:type ='win32'name ='Microsoft.VC90.CRT'version ='9.0.21022.8'processorArchitecture ='x86'publicKeyToken ='1fc8b3b9a1e18e3b ““;忽略
当我启动可执行文件时,C运行时会生成以下错误:
运行时错误:R6034应用程序尝试错误地加载C运行时库
答案 0 :(得分:0)
这是与CRT 9组装的更好链接
答案 1 :(得分:0)
删除listing.inc 删除security_check_cookie引用 添加INCLUDELIB MSVCRT ......和Robert est ton oncle!
您还可以添加: EXTERN _getchar:PROC 在ret之前:调用_getchar 这将在程序关闭前等待按键。
Honkjonk。
答案 2 :(得分:0)
我最近这样做了。事实证明你仍然可以在MSVC2012中以32位模式执行此操作,但我认为64位模式是没有希望的。
对于32位模式,这就是你要做的。
创建一个空项目和一个源文件 Source.cpp
#include <stdio.h>
int main() {
printf("hello world\n");
return 0;
}
/GL
)。这会添加行INCLUDELIB MSVCRT
/SAFESEH:NO
)我已经将它用于更复杂的功能。我通常在一个单独的模块上执行它,并在函数名称上使用extern "C"
来删除C ++名称修改。