正如我的问题的标题所说,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 :
}
}
答案 0 :(得分:0)
评论太多了。我的意思是推送和弹出您感兴趣保留的寄存器,包括那些您从esi <-> ebx
和edi <-> ecx
处理的寄存器。
_sleep:
push ecx // save the regs
push edx
push ebp
mov eax, sleepTime // func argument
push eax // pushes the sleep time input
call Sleep // sleep() call
pop eax // clean off stack
pop ebp // restore regs
pop edx
pop ecx
答案 1 :(得分:0)
WinApi Sleep()函数跟在STDCALL calling convention之后。它返回时已经清理了堆栈。当你这样做时,堆栈是'#34; overcleaned&#34; ;-)。删除行:
pop eax //cleans the stack
我不知道您使用的编译器。我的编译器(Visual Studio 2010)需要另一次调用Sleep():
call dword ptr [Sleep]