Sleep()内联汇编调用有效,但生成运行时检查失败 [英] Sleep() inline assembly call works but generates runtime check-failure
问题描述
正如我的问题的标题所说,sleep()函数可以正常工作(以及C函数中的所有其他函数调用,问题在于运行完成后,我得到一个错误消息:
As the title of my question says the sleep() function works properly (and every other function call in the C function, the problem is that after it's finished running I get an error that says:
运行时检查失败#0-ESP的值未在函数调用中正确保存.这通常是由于用一种调用约定声明的函数和用另一种调用约定声明的函数指针一起调用的结果. "
"Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention."
我相信调用睡眠函数时我处理寄存器的方式已正确完成,因为它确实起作用,我发布了整个函数,以防万一需要检测到我可能将堆栈内容放到另一个函数中的位置打电话.
I believe the way I'm handling the registers when I call the sleep function is done properly because it actually works, I posted the whole function just in case it's needed to detect where I might be misplacing the stack contents in another function call.
该功能基本上可以打印从底部的最后一层到最顶层的电梯.
The function basically prints an elevator going up from the last floor on the bottom to the top-most one.
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调用约定.返回时,它已经清理了堆栈.当您执行相同的操作时,堆栈将被过度清洗" ;-).删除行:
The WinApi Sleep() function follows the STDCALL calling convention. It had already cleaned up the stack when it returns. When you do the same, the stack is "overcleaned" ;-). Remove the line:
pop eax //cleans the stack
我不知道您使用什么编译器.我的编译器(Visual Studio 2010)需要再次调用 Sleep():
I don't know what compiler you use. My compiler (Visual Studio 2010) needs another call to Sleep():
call dword ptr [Sleep]
这篇关于Sleep()内联汇编调用有效,但生成运行时检查失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!