“在函数调用中未正确保存ESP的值。”即使使用LEAVE

问题描述:

当试图调用在程序集中定义的方法时,我收到错误“ESP的值未正确保存在函数调用中。”,使用Visual Studio 2012.查看其他问题,一个常见因素是提到程序集在每个标签末尾可能没有LEAVE指令。“在函数调用中未正确保存ESP的值。”即使使用LEAVE

我收到了这个错误,但是下面的代码包含了LEAVE指令。

section .bss 
    vs: resb 13 ; 12-byte vendor string + NULL char 
    ns: resb 49 ; 48-byte proc. name + NULL char 

section .text 

global _meta_vendor 
global _meta_procname 

_meta_vendor: 
    push ebp 
    mov ebp, esp 
    mov eax, 0h 
    cpuid 
    mov [vs], ebx 
    mov [vs + 4], edx 
    mov [vs + 8], ecx 
    mov byte [vs + 12], 0h 
    mov eax, vs 
    leave 
    ret 

_meta_procname: 
    push ebp 
    mov ebp, esp 
    mov eax, 80000002h 
    cpuid 

    mov [ns], eax 
    mov [ns + 4], ebx 
    mov [ns + 8], ecx 
    mov [ns + 12], edx 
    mov eax, 80000003h 
    cpuid 
    mov [ns + 16], eax 
    mov [ns + 20], ebx 
    mov [ns + 24], ecx 
    mov [ns + 28], edx 
    mov eax, 80000004h 
    cpuid 
    mov [ns + 32], eax 
    mov [ns + 36], ebx 
    mov [ns + 40], ecx 
    mov [ns + 44], edx 
    mov byte [ns + 48], 0h 
    mov eax, ns 
    leave 
    ret 

对于这些标签函数原型然后在其中包含头文件只有这个:

#include <cstdint> 

extern "C" { 
    char* meta_vendor(); 
    char* meta_procname(); 
} 

任何有识之士,为什么我收到这个错误?

请注意,如果在出现的弹出窗口中单击“继续”,则会出现预期值。

+0

嗯 - 它看起来对我来说,ESP就会通过你的代码被保留。不过,我相信你也需要保留EBX。 – 2013-03-26 18:30:01

+0

@ 500-InternalServerError在开始时添加'push dword ebx'和'pop ebx',最后删除运行时检查消息。谢谢:) – LMS 2013-03-26 18:34:09

+0

生成代码时,Visual C++自己的行为是在每个使用它们的函数中保存和恢复EBX,EBP,ESI和EDI(请参阅http://msdn.microsoft.com/zh-cn/library/984x0h58。 aspx) – Michael 2013-03-26 18:43:48

的问题,通过加入push ebxpop ebx解决作为如下所示:

_meta_vendor: 
    push ebp 
    mov ebp, esp 
    push ebx 

    ; code... 

    pop ebx 
    leave 
    ret