c - How to pass variables to intel format inline asm code compiled with gcc -
i ask form you! have project lot of c source. of them compiled gcc, compiled intel compiler. later codes have lot of inline asm codes in microsoft's masm
format. compile whole project gcc , modify few code can. wrote perl script converts intel format inline asm gas format. (btw: compile 32 bit on 64 bit linux machine).
my problem have specify gcc in inline asm("...")
c variables passed code adding :: [var1] "m" var1, [var2] "m" var2, ...
line @ end.
is way avoid explicit specification?
my tryings:
the dummy test c code replaces 4 characters destination char array elements of source char array (i know not best way it. stupid example).
in original function there no explicit specification, can compiled intel compiler (shame on me, did not test this, should work intel compiler made based on real code). loop
label used lot of times, in same c source file.
#include <stdio.h> void cp(char *psrc, char *pdst) { __asm { mov esi, psrc mov edi, pdst mov edx, 4 loop: mov al, [esi] mov [edi], al inc esi inc edi dec edx jnz loop }; } int main() { char src[] = "abcd"; char dst[] = "abcd"; cp(src, dst); printf("src: '%s', dst: '%s'\n", src, dst); return 0; }
result is: src: 'abcd', dst: 'abcd'
the working converted cp
code (compiled gcc).
gas (at&t) format (compiled: gcc -ggdb3 -std=gnu99 -m32 -o asm asm.c
)
void cp(char *psrc, char *pdst) { asm( "mov %[psrc], %%esi\n\t" "mov %[pdst], %%edi\n\t" "mov $4, %%edx\n\t" "loop%=:\n\t" "mov (%%esi), %%al\n\t" "mov %%al, (%%edi)\n\t" "inc %%esi\n\t" "inc %%edi\n\t" "dec %%edx\n\t" "jnz loop%=\n\t" : [pdst] "=m" (pdst) : [psrc] "m" (psrc) : "esi", "edi", "edx", "al" ); }
intel format (compiled: gcc -ggdb3 -std=gnu99 -m32 -masm=intel -o asm asm.c
)
void cp(char *psrc, char *pdst) { asm(".intel_syntax noprefix\n\t"); asm( "mov esi, %[psrc]\n\t" "mov edi, %[pdst]\n\t" "mov edx, 4\n\t" "loop%=:\n\t" "mov al, [esi]\n\t" "mov [edi], al\n\t" "inc esi\n\t" "inc edi\n\t" "dec edx\n\t" "jnz loop%=\n\t" : [pdst] "=m" (pdst) : [psrc] "m" (psrc) : "esi", "edi", "edx", "al" ); asm(".intel_syntax prefix"); }
both codes working, needs code modification (inserting '%' characters, collecting variables, modifying jump labels , jump
functions).
i tried version:
void cp(char *psrc, char *pdst) { asm(".intel_syntax noprefix\n\t"); asm( "mov esi, psrc\n\t" "mov edi, pdst\n\t" "mov edx, 4\n\t" "loop:\n\t" "mov al, [esi]\n\t" "mov [edi], al\n\t" "inc esi\n\t" "inc edi\n\t" "dec edx\n\t" "jnz loop\n\t" ); asm(".intel_syntax prefix"); }
but drops
gcc -ggdb3 -std=gnu99 -masm=intel -m32 -o ./asm.exe ./asm.c /tmp/cc2f9i0u.o: in function `cp': /home/tag_vr_20130311/vr/vr/slicecodec/src/./asm.c:41: undefined reference `psrc' /home/tag_vr_20130311/vr/vr/slicecodec/src/./asm.c:41: undefined reference `pdst' collect2: ld returned 1 exit status
is there way avoid definition of input arguments , avoid modifications of local labels?
addition
i tried use global variable. g
constrain has used instead of m
.
char pglob[] = "qwer"; void cp(char *pdst) { asm(".intel_syntax noprefix\n\t" "mov esi, %[pglob]\n\t" "mov edi, %[pdst]\n\t" "mov edx, 4\n\t" "loop%=:\n\t" "mov al, [esi]\n\t" "mov [edi], al\n\t" "inc esi\n\t" "inc edi\n\t" "dec edx\n\t" "jnz loop%=\n\t" ".intel_syntax prefix" : [pdst] "=m" (pdst) : [pglob] "g" (pglob) : "esi", "edi", "edx", "al"); }
addition#2
i tried
"lea esi, pglob\n\t" // ok "lea esi, %[_pglob]\n\t" // bad //"lea esi, pglob_not_defined\n\t" // bad //gcc failed with: undefined reference `pglob_not_defined'
compiled to
lea esi, pglob lea esi, offset flat:pglob // bad //compilation fails with: error: suffix or operands invalid `lea'
it seems function local variables has defined. global variable may added trailer, not necessary. both working:
"mov esi, pglob\n\t" // ok "mov esi, %[_pglob]\n\t" // ok
compiled to
mov esi, offset flat:pglob mov esi, offset flat:pglob
i defined function local variable. has defined in constraint part:
void cp(char *pdst) { char ploc[] = "yxcv"; asm(".intel_syntax noprefix\n\t" ... //"mov esi, ploc\n\t" // bad "mov esi, %[_ploc]\n\t" // ok, 'm' bad ... ".intel_syntax prefix" : [_pdst] "=m" (pdst) : [_ploc] "g" (ploc) : "esi", "edi", "edx", "al");
unfortunately should determined global , local variables. not easy asm code can defined in c
macros , surrounding function not definite. think precompiler has enough information this. maybe code has precompiled gcc -e ...
.
i realized not defining output in constraint part, code can eliminated optimizer.
tia!
yes, need specify registers explicitly. gcc not you. , can't (generally) put c variable names inside asm string.
your final code block looks good, me, in gcc don't need choose registers use yourself. should use volatile
keyword prevent compiler thinking code doesn't given has no outputs.
try this:
char pglob[] = "qwer"; void cp(char *pdst) { asm volatile (".intel_syntax noprefix\n\t" "mov edx, 4\n\t" "loop%=:\n\t" "mov al, [%[pglob]]\n\t" "mov [%[pdst]], al\n\t" "inc %[pglob]\n\t" "inc %[pdst]\n\t" "dec edx\n\t" "jnz loop%=\n\t" ".intel_syntax prefix" :: [pglob] "g" (pglob), [pdst] "g" (pdst) : "edx"); }
this way compiler deals loading variables , chooses registers (thereby eliminating pointless copy 1 register another). ideally you'd eliminate explicit use of edx
, it's not necessary here.
of course, in silly example recode whole thing in c , let compiler job.
Comments
Post a Comment