Reputation: 1
need some help understanding what this inline asm does (c++) so that I can properly convert it so that I can compile for x64. inline asm is not possible with Visual Studio and x64. my research tells me that I should use intrinics OR put the inline asm into an asm file and put that asm file in my project.
as you can I really do not know what I am talking about here but you should get the general idea.
I really would like to understand how to get this inline asm to work in either x86 or x64 compiled code. if i could understand what this is doing then maybe i could convert to c++. or move this inline asm to an asm file. i sort of know how to move to a separate file. the problem with moving to asm file is that i am not sure how to setup my asm function to accept the parameter i need to pass to it. i would like the easy answer where someone just does this for me BUT what i need is an explanation so that i can in the future i can do this on my own. i have two blocks of inline asm and this appears to be the easier of the two.
// 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);
}
}
EDITED asm: comment below suggested it wasn't correctly written.
Upvotes: 0
Views: 1999
Reputation: 58782
For starters, the code is wrong. Given that inc
does not modify the carry flag, the following adc
will use the initial zero value of it so it will never carry to the second dword.
That said, if you want to convert this code yourself, you will of course need an instruction set reference to see what each instruction does. In this case apparently it wants to increment a 128 bit number.
Upvotes: 3
Reputation: 6214
This
movzx ecx,byte ptr [li]
jecxz LOOP0_PREHEAD
jmp LOOP0_HEAD
LOOP0_PREHEAD:
inc ecx
LOOP0_HEAD:
dec sharedValue
loop LOOP0_HEAD
looks like
// 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);
Upvotes: 1