Pb with G++ 3.4.2 MinGW and inline assembly V2
Studious Apprentice
apprentice_99@hotmail.com
Thu Feb 9 14:26:00 GMT 2006
Thanks a lot for your answer John! Since then I managed to get this code
working but I still have a few questions, for you or others ;-) :
1.- Is there an official help for the clobbered register list and its use ?
I could not find any relevant section in the GCC manual
2.- Is there a place where I could find up to date examples (all example
around the web I could find use registers in both input and clobbered list,
which GCC no longer supports as far as I understand, and results in the
compilation error : can't find a register in class `CREG' while reloading
`asm')
3.- What is the difference in the clobber list between Âcc and ÂstÂ? When
do I have to use them ? Only when I modified the flag registers and intend
to read them thereafter or as soon as I use an instruction which might
modify them ?
4.- Is using Âcld or Âstd instructions considered modifying the flags
register ?
5.- Is the proposed snippet I wrote below as good as it can be ?
Thanks in advance,
Charles
I have made several versions of my assembly code until I got one perfectly
working. I went through several pitfalls :
- an early clobbered registers is not considered as clobbered registerÂ
This
means that though I put an ampersand in front of an input operant, GCC would
use it as if it had not changed thereafterÂ
- an asm block which provides no output variable is optimized away by the
compiler with the ÂO2 flag. This happens, even when the Âmemory clobber is
usedÂ
You have to use the __volatile__ keyword additionallyÂ
Here is the working version :
{
uint32 dummy_ecx;
uint32 dummy_esi;
uint32 dummy_edi;
__asm__ __volatile__
(
"cld\n\t"
"movl %3, %%esi\n\t"
"movl %4, %%edi\n\t"
"movl %5, %%ecx\n\t"
"rep\n\t"
"movsl"
: "=&c"(dummy_ecx), "=&S"(dummy_esi), "=&D"(dummy_edi)
: "g"(from), "g"(where), "g"(times)
: "memory"
);
}
And here is all the snippets I tried :
////First version (no clobber)
//{
// __asm__ __volatile__
// (
// "cld\n\t"
// "rep\n\t"
// "movsl"
// :
// : "S"(from), "D"(where), "c"(times)
// : "memory"
// );
//}
//Version 2 (cant remember what happened on this one)
//{
// std::size_t ecx_dummy;
// std::size_t esi_dummy;
// std::size_t edi_dummy;
// __asm__ __volatile__
// (
// "cld\n\t"
// "rep\n\t"
// "movsl"
// : "=S"(esi_dummy), "=D"(edi_dummy), "=c"(ecx_dummy)
// : "S"(from), "D"(where), "c"(times)
// : "memory"
// );
//}
//Version 3 (early clobber)
//{
// __asm__
// (
// "cld\n\t"
// "movl %0, %%esi\n\t"
// "movl %1, %%edi\n\t"
// "movl %2, %%ecx\n\t"
// "rep\n\t"
// "movsl"
// :
// : "g"(from), "g"(where), "g"(times)
// : "%esi", "%edi", "%ecx", "memory"
// );
//}
//Version 4 (lacking volatileÂ
should never had suppressed itÂ
)
//{
// uint32 dummy_ecx;
// uint32 dummy_esi;
// uint32 dummy_edi;
// __asm__
// (
// "cld\n\t"
// "movl %3, %%esi\n\t"
// "movl %4, %%edi\n\t"
// "movl %5, %%ecx\n\t"
// "rep\n\t"
// "movsl"
// : "=&c"(dummy_ecx), "=&S"(dummy_esi), "=&D"(dummy_edi)
// : "g"(from), "g"(where), "g"(times)
// : "memory"
// );
//}
//Version 5 (does not compile)
//{
// uint32 dummy_ecx;
// uint32 dummy_esi;
// uint32 dummy_edi;
// __asm__ __volatile__
// (
// "cld\n\t"
// "rep\n\t"
// "movsl"
// : "=&c"(dummy_ecx), "=&S"(dummy_esi), "=&D"(dummy_edi)
// : "S"(from), "D"(where), "c"(times)
// : "memory"
// );
//}
More information about the Gcc-help
mailing list