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
}
我的问题是:
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
}