本文介绍了从程序集调用Win32的睡眠函数创建访问冲突错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用MASM和Visual C ++,我在x64编译。这是我的C ++代码:

  

即使当我尝试调用 Sleep 相关代码。





  • 很明显, ,我的问题是,如何摆脱访问冲突错误,我做错了什么?



    编辑



    这是C ++中 Sleep(500); 的生成程序集:

      mov ecx,1F4h 
    call qword ptr [__imp_Sleep(13F54B308h)]

    这个生成的程序集让我感到困惑...它看起来像fastcall,因为它将参数移动到ecx,但同时它不创建任何阴影空间。我不知道这是什么意思:
    qword ptr [__imp_Sleep(13F54B308h)] 。



    strong>再次,编辑

    的完整反汇编。

      int main()
    {
    000000013F991020 push rdi
    000000013F991022 sub rsp,20h
    000000013F991026 mov rdi,rsp
    000000013F991029 mov ecx,8
    000000013F99102E mov eax,0CCCCCCCCh
    000000013F991033 rep stos dword ptr [rdi]
    Sleep(500); //这里是由编译器生成的asm!
    000000013F991035 mov ecx,1F4h
    000000013F99103A call qword ptr [__imp_Sleep(13F99B308h)]
    //调用asm
    Asm();
    000000013F991040 call @ ILT + 5(Asm)(13F99100Ah)
    //获取char,返回成功
    _getch();
    000000013F991045 call qword ptr [__imp__getch(13F99B540h)]
    return EXIT_SUCCESS;
    000000013F99104B xor eax,eax
    }


    解决方案

    如果 Asm()是正常的C / C ++函数,例如:

      void Asm()
    {
    Sleep(1000);
    }

    以下是我的x64编译器为它生成的:

      Asm proc 
    push rbp;将栈重新对齐到一个16字节的边界(CALL推送8字节为调用者的返回地址)以及准备建立一个栈帧
    sub rsp,32; 32字节的影子空间
    mov rbp,rsp;使用当前堆栈指针
    完成堆栈帧;睡眠1秒
    mov ecx,1000; ecx =睡眠时间
    call Sleep; call sleep
    lea rsp,[rbp + 32];摆脱阴影空间
    pop rbp;清除堆栈帧并将堆栈指针设置回调用方返回地址的位置
    ret;返回调用者
    Asm endp

    Have a look at the following page for more information about how x64 uses the stack:

    Stack Allocation

    这篇关于从程序集调用Win32的睡眠函数创建访问冲突错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

    10-27 19:54