我正在尝试将hello.asm构建到Windows可执行文件中,但是当我使用建议的命令来组装,链接和编译代码时,我会收到错误。无论我使用的是Strawberry Perl的GCC还是MinGW的GCC,都会为同一个YASM / NASM代码提供错误。
以下是痕迹。我在Makefile或.ASM中做错了什么,或者链接过程是错误的。无论哪种方式,我都希望有人帮我解决错误。
无论是使用nasm还是yasm来组装目标文件,我都得到相同的结果。
Strawberry Perl GCC追踪:
C:\> make
nasm -f win32 -l hello.lst hello.asm
gcc -o hello hello.o
ld: cannot find crt1.o: No such file or directory
ld: cannot find -lmingw32
ld: cannot find -lgcc
ld: cannot find -lmoldname
ld: cannot find -lcrtdll
ld: cannot find -luser32
ld: cannot find -lkernel32
ld: cannot find -ladvapi32
ld: cannot find -lshell32
ld: cannot find -lmingw32
ld: cannot find -lgcc
ld: cannot find -lmoldname
ld: cannot find -lcrtdll
make: *** [hello] Error 1
MinGW海湾合作委员会追踪:
$ make
gcc -o hello hello.o
c:/mingw/bin/../lib/gcc/mingw32/4.5.2/../../../libmingw32.a(main.o):main.c:(.text+0x104): undefined reference to `WinMain@16'
collect2: ld returned 1 exit status
make: *** [hello] Error 1
规格:
答案 0 :(得分:4)
将main()
函数替换为标签_WinMain@16
,如下所示:
section .text
extern _foo
;--------------------------------------------------
; main()
; 在 Win32 環境下, _WinMain@16 為程式進入點
;--------------------------------------------------
global _WinMain@16
_WinMain@16:
; foo(2,3)
; 呼叫時, 參數為堆疊順序 (先進後出)
push DWORD 3 ; b=3
push DWORD 2 ; a=2
call _foo
; 堆疊復原
pop eax
pop eax
ret
#include <stdio.h>
void foo(int a, int b) {
printf("%d + %d = %d\n", a, b, a+b);
}
all:
rm -f *.o
gcc -c foo.c
nasm -f win32 -o main.o main.asm
gcc -o main.exe main.o foo.o
答案 1 :(得分:1)
几个部分的解决方案:
发生了一件奇怪的事情:当我手动输入gcc ...
来构建可执行文件时,我得到的链接错误很少。但是当我使用make
运行完全相同的命令时,我遇到了各种链接错误。事实证明Free Pascal的make.exe正在影响正确的make.exe。您可以通过在PATH中提升正确的目录或卸载有问题的应用程序来解决此问题。我没有太多使用Pascal,所以我卸载它并突然gcc开始更好地工作。
Windows NASM / YASM程序集要求在函数名前加下划线(_
)。为了使汇编代码保持多平台,省略代码中的下划线,并使用Makefile选项告诉nasm / yasm在Windows中构建时使用下划线作为前缀。
使用手动ld
调用以在Windows中将这些内容链接在一起构建不起作用。用gcc
代替奇怪的“未定义的printf”链接错误,因为GCC以某种方式知道如何对此进行排序。
很难正确退出程序,特别是以多平台的方式。一种方法是将eax
设置为零,然后返回。
答案 2 :(得分:0)
对于一个简单的Windows控制台你好: hello.asm
extern printf, ExitProcess
SECTION .data
szHello db "Hello there!", 0
SECTION .text
StartHello:
push szHello
call printf
add esp, 4
push 0
call ExitProcess
生成文件:
hello: hello.obj
GoLink.exe /console /entry StartHello hello.obj kernel32.dll msvcrt.dll
hello.obj: hello.asm
nasm -f win32 hello.asm -o hello.obj