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!

+3


source to share


2 answers


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
}

      

+2


source


... 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.

0


source







All Articles