Winapi VC+中的内联汇编代码+;::系统调用WaitForSingleObject时需要帮助 我用VC++编写了VS2019编码程序,使用英特尔C++编译器编译,一个64位的命令行音乐文件播放器,用WASAPI播放WAV文件。操作系统是Win7-SP1

Winapi VC+中的内联汇编代码+;::系统调用WaitForSingleObject时需要帮助 我用VC++编写了VS2019编码程序,使用英特尔C++编译器编译,一个64位的命令行音乐文件播放器,用WASAPI播放WAV文件。操作系统是Win7-SP1,winapi,visual-c++,x86-64,system-calls,inline-assembly,Winapi,Visual C++,X86 64,System Calls,Inline Assembly,这是我有疑问并需要帮助的代码部分。为了简洁起见,省略了变量的声明 // activate an IAudioClient IAudioClient* pAudioClient; ... ... // create an event HANDLE hNeedDataEvent = CreateEvent(NULL, FALSE, FALSE, NULL); // set the event handle hr = pAudioClient->SetEventHandle(hNeedDa

这是我有疑问并需要帮助的代码部分。为了简洁起见,省略了变量的声明

// activate an IAudioClient
IAudioClient* pAudioClient;

...
...

// create an event
HANDLE hNeedDataEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

// set the event handle
hr = pAudioClient->SetEventHandle(hNeedDataEvent);

...
...

//works fine
do
{
    WaitForSingleObject(hNeedDataEvent, INFINITE);

    hr = pAudioRenderClient->ReleaseBuffer(nFramesInBuffer, 0);
    hr = pAudioRenderClient->GetBuffer(nFramesInBuffer, &pData);

    memcpy(pData, sound_buffer + nBytesToSkip, nBytesThisPass);

    nBytesToSkip += nBytesThisPass;
} while (--nBuffersPlayed);
我想替换代码行:WaitForSingleObject(HnedDataEvent,INFINITE) 使用系统调用使用内联汇编代码。可移植性并不重要,因为这只是为了实验/学习,因为我们不了解汇编程序

我找到了Win7-SP1的syscall表,下面是它对NtWaitForSingleObject的说明:

; ULONG64 __stdcall NtWaitForSingleObject( ULONG64 arg_01 , ULONG64 arg_02 , ULONG64 arg_03 );
NtWaitForSingleObject PROC STDCALL 

    mov r10 , rcx
    mov eax , 1

    ;syscall
    db 0Fh , 05h

    ret
NtWaitForSingleObject ENDP

我认为替换WaitForSingleObject调用的内联汇编代码应该是:

__asm
{
    mov r10, ?????? ; pHandle
    xor edx, edx    ; FALSE: The alert cannot be delivered
    xor r8d, r8d    ; Time-out interval, in microseconds. NULL means infinite
    mov eax, 1      ; code number for WaitForSingleObject
    syscall
}
我的问题是:

  • 为了让r10包含事件的“句柄”,我到底需要做什么
  • 内联汇编代码的其余部分正确吗
  • 另外,当我反汇编我的编译代码时,我看到:

        mov     rcx, [rbp+220h+hHandle] ; hHandle
        mov     edx, 0FFFFFFFFh ; dwMilliseconds
        call    cs:WaitForSingleObject
    

    我刚刚将HnedDataEvent的值分配给r10,它就工作了。

    MSVC不支持x86-64的内联汇编,只支持32位x86。MSVC的内部显然非常混乱,无法安全地支持内联asm或类似的东西,所以他们将其删除。除非
    syscall
    指令有一个内在特性,否则必须使用更好的编译器。Clang支持
    -fasm blocks
    以允许基本上相同的低效MSVC内联asm语法,以及GNU C内联asm(带有输出/输入约束、一个clobber列表和一个模板来替换操作数。有关它的更多信息,请参阅),或者您的意思是假设,如果您确实有一个编译器可以为x86-64编译此语法,那么您的意思是?(顺便说一句,你的英语很好,欢迎来到Stack Overflow。)我知道。我使用英特尔C++编译器,编辑我的问题来指定你的评论之前。谢谢!:)考虑到系统调用在Windows版本之间的变化,这看起来像是一个错误。您说这是为了学习,但是学习调用ntdll代码可能是一件更有用的事情。也就是说,它支持gcc的内联asm格式。r10的值应该是CreateEvent的返回值。@DavidWohlferd-感谢您的回复。如果我使用您链接到的页面中提到的系统调用,我知道这些警告/潜在问题。我知道英特尔编译器支持内联asm。我还知道需要将CreateEvent的句柄传递给r10,但由于我不了解汇编,所以不知道到底要传递什么。最后,你的回答让我思考了更多,我编码了这个:嗨,谢谢分享解决方案。请随时标记自己,以帮助有相同问题的人。
    __asm
    {
       mov r10, hNeedDataEvent ; pHandle
       xor edx, edx ; FALSE: The alert cannot be delivered
       xor r8d, r8d ; Time-out interval, in microseconds. NULL means infinite
       mov eax, 1 ; code number for WaitForSingleObject syscall
    }