Winapi 函数调用后无法从程序集中的main返回

Winapi 函数调用后无法从程序集中的main返回,winapi,assembly,x86,return,fasm,Winapi,Assembly,X86,Return,Fasm,我正在使用fasm学习汇编,在函数调用后从main返回时遇到问题。有了一个空的程序,我可以让它正常工作 format PE console entry start include 'win32a.inc' section '.text' code executable start: push ebp mov ebp, esp leave ret section '.rdata' data readable format_str db '%d', 10, 0 section '.id

我正在使用fasm学习汇编,在函数调用后从main返回时遇到问题。有了一个空的程序,我可以让它正常工作

format PE console
entry start

include 'win32a.inc'

section '.text' code executable

start:
push ebp
mov ebp, esp

leave
ret


section '.rdata' data readable
format_str db '%d', 10, 0

section '.idata' data readable import
library msvcrt, 'msvcrt.dll'
import msvcrt, printf, 'printf'
但是如果我像这样添加一个函数调用(本例中为printf)

程序将成功打印,但无法退出程序并崩溃


函数调用中发生了什么导致我的return语句失败?我如何纠正它?

进程中的初始线程基本上如下所示:

call LdrLoadAllTheThings ; Might call TLS callbacks etc
call pe_entrypoint ; Your function
push somenumber
call ExitThread ; Exit this thread and possibly the process
__declspec(noreturn) void __cdecl mainCRTStartup()
{
  int code;
  char*argv;
  int argc = parse(GetCommandLine(), &argv);
  call_constructors();
  code = main(argc, argv); // Your main function
  call_destructors_and_atexit_callbacks();
  ExitProcess(code); // End this thread and all other threads
}
一个进程将在所有线程退出后结束,对于非常简单的程序来说,只要有人调用
CreateThread
或线程池函数之一,该进程就不会在您刚刚返回时结束,只要有其他线程在工作/等待,它就会一直存在。在旧版本的Windows上,控制台程序通常可以直接返回,但正如您所发现的,它只起作用,因为调用的函数没有创建新线程(依赖于内部实现细节)。在GUI程序中,它甚至不太可能工作,也不太容易调试,因为在单击标准UI元素时,像
PlaySound
之类的东西可能会创建线程

如果使用Microsoft toolchain构建C/C++应用程序并链接到其运行时库,则主函数不是真正的入口点,真正的入口点是mainCRTStartup,它基本上是这样工作的:

call LdrLoadAllTheThings ; Might call TLS callbacks etc
call pe_entrypoint ; Your function
push somenumber
call ExitThread ; Exit this thread and possibly the process
__declspec(noreturn) void __cdecl mainCRTStartup()
{
  int code;
  char*argv;
  int argc = parse(GetCommandLine(), &argv);
  call_constructors();
  code = main(argc, argv); // Your main function
  call_destructors_and_atexit_callbacks();
  ExitProcess(code); // End this thread and all other threads
}

什么操作系统?您是如何编译/链接的?请全部邮寄。还有,调试器会说什么?注:一般来说,如果你打算使用C库函数,你应该命名你的入口点
main
。我是在Windows10上编译的。由于您的请求,我添加了代码的其他部分,特别是如果您告诉它
entry start
:)那么,退出代码7是因为您没有明确设置一个,并且
printf
返回打印的字符数,大概是7。这不是一个错误或崩溃本身。如果您愿意,可以在返回前将eax设置为零。@Jester-不,您错了。第一个版本可以工作,因为windows 10没有在这里创建额外的工作线程(没有使用DLL)。在第二个版本中-
msvcrt.dll
已加载,windows 10将为加载它创建额外的工作线程<代码>退出流程必须调用