编译VC ++生成的汇编输出?

时间:2010-05-12 01:35:04

标签: visual-c++ assembly x86 masm32

我有一个简单的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运行时库

3 个答案:

答案 0 :(得分:0)

这是与CRT 9组装的更好链接

http://www.masm32.com/board/index.php?topic=9231.0

答案 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;
 }
  1. 右键舔项目并选择“构建自定义”和
    选择masm,如http://www.masm32.com/board/index.php?topic=9231.0
  2. 所述
  3. 在C ++ / OutputFiles下选择Assembly Output / FA
  4. 以32位模式发布模式
  5. Source.asm 文件加载到MSVC中,以便查看。它还行不通。需要做一些改变。
  6. 在C ++ / Optimization下关闭整个程序优化(删除/GL)。这会添加行INCLUDELIB MSVCRT
  7. 在链接器/高级设置中,将最后一个选项“图像具有安全异常处理程序”设置为否(/SAFESEH:NO
  8. 现在你应该有一个Source.asm文件,它将执行与Source.cpp文件相同的操作。将Source.cpp从Release目录复制到Source.cpp所在的目录(因此在构建/清理时不会删除它。)
  9. Source.asm (作为现有文件)添加到源文件,并从构建中删除 Source.cpp
  10. 重建,您应该看到“Hello World”而无需手动更改任何装配线。
  11. 我已经将它用于更复杂的功能。我通常在一个单独的模块上执行它,并在函数名称上使用extern "C"来删除C ++名称修改。