【问题标题】:Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call运行时检查失败 #0 - ESP 的值未在函数调用中正确保存
【发布时间】:2023-03-06 14:55:01
【问题描述】:
#include<stdio.h>
int a[100];
int main(){
    char UserName[100];
    char *n=UserName;
    char *q=NULL;
    char Serial[200];
    q=Serial;
    scanf("%s",UserName);
//this is about 
    __asm{
        pushad
            mov eax,q
            push eax
            mov eax,n
            push eax
            mov EAX,EAX
            mov EAX,EAX
            CALL G1
            LEA EDX,DWORD PTR SS:[ESP+10H]
        jmp End
G1:
        SUB ESP,400H
            XOR ECX,ECX
            PUSH EBX
            PUSH EBP
            MOV EBP,DWORD PTR SS:[ESP+40CH]
        PUSH ESI
            PUSH EDI
            MOV DL,BYTE PTR SS:[EBP]
        TEST DL,DL
            JE L048
            LEA EDI,DWORD PTR SS:[ESP+10H]
        MOV AL,DL
            MOV ESI,EBP
            SUB EDI,EBP
L014:
        MOV BL,AL
            ADD BL,CL
            XOR BL,AL
            SHL AL,1
            OR BL,AL
            MOV AL,BYTE PTR DS:[ESI+1]
        MOV BYTE PTR DS:[EDI+ESI],BL
            INC ECX
            INC ESI
            TEST AL,AL
            JNZ L014
            TEST DL,DL
            JE L048
            MOV EDI,DWORD PTR SS:[ESP+418H]
        LEA EBX,DWORD PTR SS:[ESP+10H]
        MOV ESI,EBP
            SUB EBX,EBP
L031:
        MOV AL,BYTE PTR DS:[ESI+EBX]
        PUSH EDI
            PUSH EAX
            CALL G2
            MOV AL,BYTE PTR DS:[ESI+1]
        ADD ESP,8
            ADD EDI,2
            INC ESI
            TEST AL,AL
            JNZ L031
            MOV BYTE PTR DS:[EDI],0
            POP EDI
            POP ESI
            POP EBP
            POP EBX
            ADD ESP,400H
            RETN
L048:
        MOV ECX,DWORD PTR SS:[ESP+418H]
        POP EDI
            POP ESI
            POP EBP
            MOV BYTE PTR DS:[ECX],0
            POP EBX
            ADD ESP,400H
            RETN


G2:
        MOVSX ECX,BYTE PTR SS:[ESP+4]
        MOV EAX,ECX
            AND ECX,0FH
            SAR EAX,4
            AND EAX,0FH
            CMP EAX,0AH
            JGE L009
            ADD AL,30H
            JMP L010
L009:
        ADD AL,42H
L010:
        MOV EDX,DWORD PTR SS:[ESP+8]
        CMP ECX,0AH
            MOV BYTE PTR DS:[EDX],AL
            JGE L017
            ADD CL,61H
            MOV BYTE PTR DS:[EDX+1],CL
            RETN
L017:
        ADD CL,45H

            MOV BYTE PTR DS:[EDX+1],CL
            RETN



End:
        mov eax,eax
        popad
    }

    printf("%s\n",Serial);

    return 0;
}

你能帮帮我吗? 关于Asm的这个问题,不知道为什么会导致这个结果。 这个程序很简单,它是一个内部代码的程序。

运行时检查失败 #0 - ESP 的值未在函数调用中正确保存。这通常是调用使用一种调用约定声明的函数和使用另一种调用约定声明的函数指针的结果。

【问题讨论】:

  • 您说“非常简单”,然后您有一大块未注释的程序集?至于你的问题,汇编代码开头的堆栈指针是否与结尾相同?
  • 为什么不能调试呢?只需单步执行并观察寄存器值(尤其是@JoachimPileborg 所说的 ESP),然后找出问题所在。为什么我们调试比你容易?调试这样的东西并不难,它只需要一定的时间、思想和努力。我为什么要做你的繁重工作?
  • 很高兴看到你的建议,但是当这个程序运行没有问题时。它关闭时出错了。
  • 很高兴看到你的建议,但是当这个程序运行没有问题时。它关闭时出错了。

标签: c++ assembly runtime


【解决方案1】:

可能发生这种情况是因为在函数的开头G1 你是SUB ESP,400H,在L031 之后你是ADD ESP,8,最后你是ADD ESP,400HG1 调用之前的ESP 似乎比调用之后的8 少。

编辑:关于汇编函数的编码风格请参见this。这里简要描述了调用者的职责和被调用者的职责,这些职责是 ESP 所考虑的。

【讨论】:

  • 在调用G2 之前,ADD ESP,8 不代表两个PUSH 命令吗?但我不确定。最近没怎么用汇编语言。
  • @Henrik 可以是这样(我简要地查看了这段代码),但同时在L048 之后没有ADD ESP,8。这看起来有点奇怪。
  • eee,我很抱歉问了这么愚蠢的问题,这段代码是程序编译器代码的一部分。所以我忘记了 ESP。
【解决方案2】:

似乎在调用G1之前压入堆栈的两个参数永远不会从堆栈中弹出。

【讨论】:

  • 第一个参数是保存结果。花药被推。
  • @Driedbeancurd - 我不太明白你的评论。您是否尝试在CALL G1 之后(或LEA ... 之后)添加ADD ESP,8 以从堆栈中删除参数?
猜你喜欢
  • 2012-04-22
  • 2012-01-25
  • 1970-01-01
  • 2011-01-26
  • 2010-11-30
  • 1970-01-01
  • 2011-10-06
  • 1970-01-01
相关资源
最近更新 更多