Convert GCC / ATT style assembler to visual studio assembler?
I'm trying to rewrite this snippet to work in visual studio, but I obviously don't understand how to use colon assignment and value __volatile__
.
can you offer some help :)?
__asm__ __volatile__ (
"mov %0, %%edi\n"
"xor %%eax, %%eax\n"
"xor %%ecx, %%ecx\n"
"dec %%ecx\n"
"repne scasb\n"
"sub %%ecx, %%eax\n"
"dec %%eax\n"
:
: "m" (src)
: "memory", "%ecx", "%edi", "%eax");
Thank!
source to share
The two inline assemblers are completely different. Visual Studio's inline assembler is more primitive but easier to use. In VS:
- inline assembly language must not be enclosed in a string;
- the operands of the commands are in dest, src order;
- The C / C ++ variables are available as is:
- and etc.
There are no output statements (after the first colon) in your code, so I don't see how this might affect. But suppose the register is eax
to be stored in a variable src
at the end. Then you need something like this:
char* src;
...
__asm {
mov edi,src
xor eax,eax
xor ecx,ecx
dec ecx
repne scasb
sub eax,ecx
dec eax
mov src,eax // save result
}
By the way, it looks suboptimal to me. All this business with eax
can be done with not ecx
, if I understood the code correctly:
__asm {
mov edi,src
xor al,al
xor ecx,ecx
dec ecx
repne scasb
not ecx
mov src,ecx // save result
}
source to share
... I don't understand ... the purpose of colons ...
As Columbo pointed out in his comment, here is the relevant man page: 6.43.2 Extended Asm Instructions - Assembler with C Expression operands . Colons simply separate the tokens in the ASM block. They are like a semicolon trailing a C statement (or rather a comma operator, since they are related).
And to echo what the page says, the general format is:
asm (
Instructions (Assembler Code)
: Outputs (C variables modified by the instructions)
: Inputs (C expressions read by the instructions)
: Clobbers (Registers or other values changed by the instructions)
)
Sometimes there will be no token between the semicolons. For example, this is what the memory barrier looks like:
__asm__ __volatile__ ("" ::: "memory")
There is no assembly code, no C variables are used as output, and no C expressions are used as input. But the memory is listed as crashed, so the compiler knows that pending reads and writes have been completed before the next instruction is executed.
... I don't understand ... the meaning
__volatile__
OK, so it might be a worm, because GCC and Visual Studio interpret the meaning differently volatile
(although they use the same C language specification).
In GCC, the only reason for using it volatile
is that the hardware can change memory. So I think that using the qualifier volatile
is an abuse in the above example (because it looks like the function is scanning a byte NULL
and not doing memory mapped I / O).
You can find relevant discussion on the GCC mailing list on volatile shared memory . Ian Lance Taylor, who provided the answer below, is one of the GCC developers:
No, volatile cannot solve this problem. This is not what the qualifier is for. The volatile determinant is designed to work with memory. It is not intended for multiprocessor memory partitions. If the program is not multiprocessor, adding volatile will never make it multiprocessor.
EDIT : as Tony pointed out below, volatile
used to tame the optimizer so that the ASM block is not removed at compile time.
Also note that you can convert the code to inline assembly for x86, but you cannot do that for x64. Microsoft does not support inline assembly for x64. See Intrinsics and Inline Assembly on MSDN.
source to share