内联asm到x64 - 理解

时间:2016-01-15 19:42:50

标签: c++ c visual-c++ assembly visual-studio-2015

需要一些帮助来理解这个内联asm(c ++)的内容,以便我可以正确转换它以便我可以编译为x64。使用Visual Studio和x64无法实现内联asm。我的研究告诉我,我应该使用内在函数或将内联asm放入asm文件并将asm文件放在我的项目中。

因为你可以我真的不知道我在这里谈论什么,但你应该得到一般的想法。

我真的想了解如何让这个内联asm在x86或x64编译代码中工作。如果我能理解这是做什么,那么也许我可以转换为c ++。或者将此内联asm移动到asm文件。我知道如何移动到一个单独的文件。移动到asm文件的问题是我不知道如何设置我的asm函数来接受我需要传递给它的参数。我想要一个简单的答案,有人为我做这个,但我需要的是一个解释,以便我将来可以自己做到这一点。我有两个内联asm块,这看起来更容易。

inline asm to asm file

// FIRST inline asm talked about above
// little endian
void BlockInc(unsigned char *data)
{
    #if DATA_BLOCK_SIZE==16
    __asm
    {
        mov edi,[data]
        add dword ptr [edi+0],1
        adc dword ptr [edi+4],0
        adc dword ptr [edi+8],0
        adc dword ptr [edi+12],0
    }
    #else
#error
    #endif
}

//this is the second more difficult inline asm not mentioned
void concThread(void *param)
{
    unsigned long threadN = *((unsigned long *)param);

    while(true)
    {
        unsigned long           index;

        // 1. synch
        WaitForSingleObject(concThread_semaphores1[threadN],INFINITE);
        ReleaseSemaphore(concThread_semaphores2[threadN],1,NULL);

        if(sharedStop)
        {
            _endthread();
        }

        // start "sharedValue" concurrent modify
        while(!sharedOkToGo);

        for(index=0;index<(CYCLE_NUM/128);index++)
        {
            LARGE_INTEGER   li;

            QueryPerformanceCounter(&li);

            if(threadN%2)
            {
                __asm
                {
                    movzx ecx,byte ptr [li]
                    jecxz LOOP0_PREHEAD
                    jmp LOOP0_HEAD

                    LOOP0_PREHEAD:
                    inc ecx
                    LOOP0_HEAD:
                    dec sharedValue
                    loop LOOP0_HEAD
                }
            }
            else
            {
                __asm
                {
                    movzx ecx,byte ptr [li]
                    jecxz LOOP1_PREHEAD
                    jmp LOOP1_HEAD

                    LOOP1_PREHEAD:
                    inc ecx
                    LOOP1_HEAD:
                    inc sharedValue
                    loop LOOP1_HEAD
                }
            }
        }

        ReleaseSemaphore(concThread_semaphores2[threadN],1,NULL);
    }
}

编辑asm:下面的评论表明它写得不正确。

2 个答案:

答案 0 :(得分:3)

对于初学者来说,代码是错误的。鉴于inc没有修改进位标志,以下adc将使用它的初始零值,因此它永远不会进入第二个双字。

也就是说,如果你想自己转换这段代码,你当然需要一个指令集引用来查看每条指令的作用。在这种情况下,显然它想要增加128位数。

答案 1 :(得分:1)

movzx ecx,byte ptr [li]
jecxz LOOP0_PREHEAD
jmp LOOP0_HEAD

LOOP0_PREHEAD:
inc ecx
LOOP0_HEAD:
dec sharedValue
loop LOOP0_HEAD

看起来像

// ecx was used to hold a loop count
uint32_t i = li;
// do-while to guarantee execution at least once
// since LOOP0_PREHEAD incremented ecx if it was zero
do {
   sharedValue--;
   i--;
} while (i > 0);