正如我的问题标题所示,sleep() 函数工作正常(以及 C 函数中的所有其他函数调用),问题是在它完成运行后,我收到一条错误消息:
“运行时检查失败 #0 - ESP 的值在函数调用过程中未正确保存。这通常是由于使用一种调用约定声明的函数和用另一种调用约定声明的函数指针来调用函数的结果。 ”
我相信当我调用 sleep 函数时处理寄存器的方式是正确的,因为它实际上有效,我发布了整个函数,以防万一需要检测我可能将堆栈内容放错在另一个函数中的位置打电话。
该函数基本上打印了一部从底部最后一层到最顶层的电梯。
int deSubidaASM() {
int sleepTime = 900;
char *clear = "cls";
char *piso = "[x]";
char *pisoVacio = "[ ]";
char *texto = "%s\n";
char *fuerza = "Fuerza G: 1";
_asm {
mov ebx, 0 //int a=0
mov ecx, 9 //int b=9
_while1: //while (a <= 9)
cmp ebx, 9 //
jg _fin //if ebx>9, end
_Fuerza: //writes on screen
mov eax, fuerza
push eax
mov eax, texto
push eax
mov esi, ecx //
call printf
mov ecx, esi //
pop edx
pop edx
_sleep:
mov eax, sleepTime
push eax //pushes the sleep time input
mov esi, ebx //auxiliary variable to keep the cycle counters
mov edi, ecx //same as the above line comment
call Sleep //sleep() call
mov ecx, edi //returns the values from the aux variables
mov ebx, esi //same as the above line comment
pop eax //cleans the stack
_clearscreen:
mov eax, clear //Bloque para clearscreen
push eax
mov esi, ebx
mov edi, ecx
call system
mov ecx, edi
mov ebx, esi
pop edx
_while2 : //while (b >= 0)
cmp ecx, 0 //
jle _resetearWhile2 //if ecx<0 restart while2
cmp ebx, ecx // if the levels match
je _printPiso //print elevator
jne _printVacio //print floor
_printPiso :
mov eax, piso
push eax
mov eax, texto
push eax
mov esi, ecx //
call printf
mov ecx, esi //
pop edx
pop edx
dec ecx
jmp _while2
_printVacio :
mov eax, pisoVacio
push eax
mov eax, texto
push eax
mov esi, ecx //
call printf
mov ecx, esi //
pop edx
pop edx
dec ecx
jmp _while2
_resetearWhile2:
mov ecx, 9 //b=9
inc ebx
jmp _while1
_fin :
}
}
最佳答案
WinApi Sleep()函数遵循 STDCALL calling convention 。当它返回时,它已经清理了堆栈。当您执行相同操作时,堆栈将被“过度清理”;-)。删除该行:
pop eax //cleans the stack
不知道你用的是什么编译器。我的编译器 (Visual Studio 2010) 需要再次调用 Sleep() :
call dword ptr [Sleep]
关于c - Sleep() 内联汇编调用可以工作,但会生成运行时检查失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34455786/