有這么一個簡單的assembly Win 32程式:
.386
.model flat, stdcall
option casemap :none
EXTERN printf :PROC ; declare printf
.data
HelloWorld db "Hello Wolrd!:-)", 0
.code
start:
sub esp, 4
push offset HelloWorld
call printf
add esp, 4
ret
end start
我可以通過以下方式成功編譯它:
ml.exe /c HelloWorld.asm
但是鏈接它有問題。當我使用:
link HelloWorld.obj libcmt.lib
我收到一個錯誤:
unresolved external symbol _main called in _mainCRTStartup
為了成功鏈接程式以運行它,我要更改/更正什么?
聚苯乙烯
請不要告訴我只使用nasm. 我想從我的 MSVC 中使用ml& link。
uj5u.com熱心網友回復:
通過一些小的調整,現在可以正確構建。
.386
.model flat, c
option casemap :none
includelib libcmt.lib
includelib legacy_stdio_definitions.lib
EXTERN printf :PROC ; declare printf
.data
HelloWorld db "Hello World!:-)", 0
.code
main PROC
push offset HelloWorld
call printf
add esp, 4
ret
main ENDP
END
主要編輯是
- .model flat, c將程序的呼叫約定設定為 C。
如果您決定保持.model flat,stdcall它將需要這些更改。
代替
EXTERN printf :PROC
main PROC
和
printf PROTO NEAR C,:DWORD
main PROC NEAR C
包括libcmt.lib和legacy_stdio_definitions.lib,它們將本機 C 運行時啟動靜態鏈接到您的代碼中。
將入口點從start更改為main。C 運行時庫 (CRT) libcmt.lib 中有一個入口點 (_mainCRTStartup),它執行一些初始化任務,然后將控制權交給應用程式main的入口點。您可以更改默認入口點,但通常您希望 CRT 入口點自動為您進行初始化的便利性。
洗掉了第一個sub esp,4,因此剩余的一次推送由 add esp,4 平衡,因此當 ret 運行時,ESP 指向回傳地址。
要構建,請打開 Windows 命令提示符并運行:
"C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Auxiliary\Build\vcvars32.bat"
設定初始化為:'x86'的 MSVC 環境
接下來,運行這些 MASM 命令
ml.exe /c /coff HelloWorld.asm
link.exe /SUBSYSTEM:console HelloWorld.obj
程式顯示
你好,世界!:-)
uj5u.com熱心網友回復:
您的錯誤訊息說它找不到匯出的符號(即函式)“_main”。我希望將您的 start 函式重命名為 _main 會使其編譯。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/328586.html
上一篇:為什么要使用“ret”而不是“call”來呼叫方法?
下一篇:IDA專業人士了解反匯編細節
