Hi,
I have several questions regarding GCC Inline Assembly support.
(1)
I'm porting (reasonably big) blocks of Intel-syntax Inline Assembly to
GCC/Linux.
I would like to find out if it is a good idea to utilize GCC's
.intel_syntax Inline Assembly support (for non-trivial blocks), or to
convert them to GAS or NASM assembly functions, .S files.
(2)
The source Inline Assembly blocks make full use of available x86
registers, thus causing out-of-registers problem when -fPIC is used,
where one register is used for GOT addressing.
Is there a way I can use the memory constraint, "m", effectively in
.intel_syntax Inline Assembly?
In the following Inline Assembly sample, how can I specify "m" memory
constraint in .intel_syntax (and has the proper syntax generated)?
asm __volatile__ (
".intel_syntax noprefix \n\t"
"mov ebp, eax \n\t"
"mov ebp, %8 \n\t"
...
".att_syntax noprefix \n\t"
: /* Output operands */
"=a" (dummy)
//, "=b" (dummy)
, "=D" (dummy)
, "=S" (dummy)
, "=c" (dummy)
: /* Input operands */
"0" (param0)
//, "1" (var0)
, "1" (var1)
, "2" (param1)
, "3" (var2)
, "m" (var0)
);
COMMAND LINE:
gcc -fPIC -DPIC -S -o temp.S temp.c
OUTPUT:
#APP
.intel_syntax noprefix
mov ebp, eax
mov ebp, -28(%ebp) // Trouble: AT&T syntax in .intel_syntax!
See attached files for complete .c and .S files.
(3) Is there any document providing information how I can create a
single version of assembly code (Inline Assembly or pure assembly) and
have it compiled with or without -fPIC correctly?
Thanks for any help.
--
Daniel.
#include <stdio.h>
int func(unsigned int param0, unsigned int param1, unsigned int param2, unsigned int param3)
{
unsigned int dummy = 0;
unsigned int var0 = 10;
unsigned int var1 = 20;
unsigned int var2 = 30;
unsigned int var3 = 40;
asm __volatile__ (
".intel_syntax noprefix \n\t"
//"mov eax, param0 \n\t"
//"mov ebx, var0 \n\t"
//"mov edi, var1 \n\t"
//"mov esi, param1 \n\t"
//"mov ecx, var2 \n\t"
"mov ebp, eax \n\t"
"mov ebp, %8 \n\t"
"mov ebp, edi \n\t"
"mov ebp, esi \n\t"
"mov ebp, ecx \n\t"
".att_syntax noprefix \n\t"
: /* Output operands */
"=a" (dummy)
//, "=b" (dummy)
, "=D" (dummy)
, "=S" (dummy)
, "=c" (dummy)
: /* Input operands */
"0" (param0)
//, "1" (var0)
, "1" (var1)
, "2" (param1)
, "3" (var2)
, "m" (var0)
: /* Clobbered registers */
"memory"
);
return 0;
}
int main(int argc, char **argv)
{
return 0;
}
.file "temp.c"
.text
.globl func
.type func, @function
func:
pushl %ebp
movl %esp, %ebp
pushl %edi
pushl %esi
subl $32, %esp
movl $0, -24(%ebp)
movl $10, -28(%ebp)
movl $20, -20(%ebp)
movl $30, -16(%ebp)
movl $40, -12(%ebp)
movl 8(%ebp), %eax
movl -20(%ebp), %edi
movl 12(%ebp), %esi
movl -16(%ebp), %ecx
#APP
.intel_syntax noprefix
mov ebp, eax
mov ebp, -28(%ebp)
mov ebp, edi
mov ebp, esi
mov ebp, ecx
.att_syntax noprefix
#NO_APP
movl %eax, -24(%ebp)
movl %edi, -24(%ebp)
movl %esi, -24(%ebp)
movl %ecx, -24(%ebp)
movl $0, %eax
addl $32, %esp
popl %esi
popl %edi
popl %ebp
ret
.size func, .-func
.globl main
.type main, @function
main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
pushl %ecx
movl $0, %eax
popl %ecx
popl %ebp
leal -4(%ecx), %esp
ret
.size main, .-main
.ident "GCC: (GNU) 4.1.1"
.section .note.GNU-stack,"",@progbits