Assembly 运行用NASM编写的Win32应用程序会导致';此应用程序无法在您的pc上运行';错误

Assembly 运行用NASM编写的Win32应用程序会导致';此应用程序无法在您的pc上运行';错误,assembly,x86,mingw,nasm,ld,Assembly,X86,Mingw,Nasm,Ld,我开始学习Windows上的x86汇编。我正在学习32位x86汇编。我使用nasm和ld来编译我的程序。我使用mingw32 makemakefile作为构建系统。我假设ld包含在MinGW中,但我不确定这一点。我只知道它已经在我的电脑上了 我想编译一个非常简单的程序,只是为了确保一切正常,当然不是。在运行我的可执行文件时,出现一个巨大的蓝色框,上面写着“此应用程序无法在你的电脑上运行”,在关闭通知后,访问被拒绝字样打印到我的终端上 这是我的节目: global _main _main:

我开始学习Windows上的x86汇编。我正在学习32位x86汇编。我使用
nasm
ld
来编译我的程序。我使用
mingw32 make
makefile作为构建系统。我假设
ld
包含在MinGW中,但我不确定这一点。我只知道它已经在我的电脑上了

我想编译一个非常简单的程序,只是为了确保一切正常,当然不是。在运行我的可执行文件时,出现一个巨大的蓝色框,上面写着“此应用程序无法在你的电脑上运行”,在关闭通知后,
访问被拒绝
字样打印到我的终端上

这是我的节目:

global _main

_main:
  mov eax, 1
  ret
这是我的makefile:

main: learn.asm
    nasm -f win32 learn.asm -o learn.o
    ld learn.o -o learn.exe

有人能帮我解决这个问题吗?

最初您的问题是关于使用
\u start
作为切入点。链接的方式不包括C运行时

对于某些版本的Windows,如果在某些情况下没有
.rdata
(只读数据)部分,则在与MinGW LD链接时,您可能会收到错误
此应用程序无法在pc上运行。一种情况似乎是具有
.idata
节()的可执行文件未被标头引用,并且不包含
.rdata
节。当MinGW-LD链接器在不使用C运行时的情况下从代码创建可执行文件时,就会出现这种情况。要解决此问题,请添加至少包含一个字节数据的
.rdata
部分。这应该起作用:

global _start

section .rdata
db 0

section .text
_start:
    mov eax, 1
    ret 
您还需要将代码放入
.text
部分,否则可能会遇到其他问题。然后,您可以组装并链接到:

nasm -fwin32 learn.asm -o learn.obj
ld -o learn.obj -o learn.exe
nasm -fwin32 learn.asm -o learn.obj
gcc -m32 learn.obj -o learn.exe
如果您想使用
\u main
并打算使用C运行时,则不需要创建
.rdata
部分,但是您可以组合并链接:

nasm -fwin32 learn.asm -o learn.obj
ld -o learn.obj -o learn.exe
nasm -fwin32 learn.asm -o learn.obj
gcc -m32 learn.obj -o learn.exe

我的链接建议 或者,您可以使用不同于LD的链接器。尤其应该从您使用的代码生成一个可执行文件。您可以通过以下方式创建带有
\u start
入口点的Win32 console应用程序:

nasm -fwin32 learn.asm -o learn.obj
golink /console /entry _start learn.obj
GoLink将生成一个具有适当标题和部分的可执行文件,Windows在运行该文件时不需要添加
.rdata
部分

如果已安装MSVC/C++,还可以使用:


你确定它不只是撞车吗?你需要终止程序。在windows上,我相信您可以简单地
ret
。您可以提供代码作为答案吗?只需在
mov eax之后粘贴
ret
,1
@Jester不起作用:(您的环境是否有
file
命令?如果运行
file learn.exe
,它会说什么?背景似乎是“.idata”部分(顺便说一句,不需要命名为“.idata”):如果OP使用的是
ld
,则不使用启动代码,因此入口点是
\u main
(或者
\u start
,如果函数是以这种方式命名的)。因为程序必须调用操作系统(至少对于
退出
ing),并且是唯一可靠的(且允许的)调用Windows内核的可能性是使用DLL,程序必须使用DLL。在Windows和Linux中都不允许从入口点使用
ret
返回代码。@MartinRosenau:如果主线程返回时带有
ret
当且仅当主线程是唯一活动的线程时,Win32进程可以终止。如果Windows loader曾经创建过多个线程,那么
ret
可能不会导致进程退出。不过,为了避免这个问题,一般的经验法则是调用ExitProcess。我自己不喜欢这样使用
ret
。有趣的是,我观察到很多Windows版本都会拒绝如果导入部分没有列出DLL文件,则无法加载可执行文件。Windows Vista或Windows 7(我不确定)如果EXE文件不包含任何导入,则什么也不做:代码不会执行,但程序会立即返回。您可以通过编写无休止的循环或导致异常的代码来验证这一点。我可以想象Windows 10打印问题中报告的错误消息,而不是“静默”不做任何操作。