This code works perfectly fine.
when i try to compile the following piece of code
int y;
20 asm ("mov %fs:thread_local@TPOFF, %rax;"
21 "mov %%rax, %%rbx;"
22 :"=Ab" (y)
23 );
This gives a error
tls.c:20: error: invalid 'asm': operand number missing after %-letter
tls.c:20: error: invalid 'asm': operand number missing after %-letter
I think it is not recognising the %fs:thread_local@TPOFF
Can someone please explain as to what is wrong with the second part.
thanks
shankha
I'm not familiar with inline assembly syntax, but don't we need "%%"
before registers? That doesn't explain why your first version works...
Best,
Frank
If i use just % the first version dosen't work. So i assume %% is the
right syntax. I tried using %% for the second version but that didn't
work.
I think the problem is with the first line.
I'm interested in the exact rules on percents in GCC's inline assembly. I
know that one percent is used on registers some of the time, but typically
two percents are needed. If there are only branches and registers which use
percents, then you use one percent for the branches and two for the
registers. If you remove the branches, then you only need a single percent
for the registers. I'd suspect that the behavior is similar when you pass
in a variable, e.g., y as %0 here. I.e., the passed in variable (implicit
or unused in this case) uses one percent and the registers use two.
Unfortunately, I don't know enough about GCC's inline assembly to know if he
can use _two_ output register constraints, "A" and "b" as the OP is doing...
A is rax or rdx. b is rbx. Using both doesn't make sense to me. The OP
only needs _one_ register to return an "int", which appears to be "rbx".
Why did the OP specify (possibly) three? Without an explanation from the
OP, I'd guess that the OP merged an output constraint "=b" with a no longer
in use input constraint "A". At a minimum, one must ask: "Why is he moving
to rax then rbx instead of directly to rbx?" E.g., won't the following do
the same?
int y;
asm ("mov %fs:thread_local@TPOFF, %rbx;"
:"=b" (y)
);
Well, I for one am confused by what the OP is doing.
Rod Pemberton
Two things
1. Your second version mixes %%rax and %rax, only one of them can be
right
2. You add ; to your second version, I'd suggest a newline [it's
easier to read]
The following dosen't work. I got the following error messages
error: invalid 'asm': operand number missing after %-letter
error: invalid 'asm': operand number missing after %-letter
I don't get any compilation error messages if i do
int y;
asm ("mov %%fs:thread_local@TPOFF, %%rbx;"
:"=3Db" (y)
);
Basically add another %. But i get 0 in y as output which is different
from what i am getting in first case.
The OP i think specifying the output to be in ebx (in your case rb in
my case) which will be copied to y.
I did try out
25 asm (
26 "mov %fs:thread_local@TPOFF, %%rax;"
27 "mov %%rax, %%rbx;"
28 :"=3DAb" (y)
29 );
I get the error message
25: error: invalid 'asm': operand number missing after %-letter
This error message i thing is for %fs:thread_local@TPOFF. So if i add
another %
like
"mov %%fs:thread_local@TPOFF, %%rax;"
I don't get any compilation errors but the output is incorrect. The
value of y is 0.
Maybe if you posted the generated assembly for the working code and
non-working, someone can compare to see what's different between them. We
don't know what TPOFF and thread_local are. gcc -S (capital letter S) will
generate assembly.
Rod Pemberton
Working Case :
ASM Code:
18 asm ("mov %fs:thread_local@TPOFF, %rax");
19 asm ("mov %%rax, %%rbx;"
20 :"=3DAb" (y)
gcc -S output
mov %fs:thread_local@TPOFF, %rax
# 0 "" 2
# 19 "tls_long.c" 1
mov %rax, %rbx;
Non Working Code :
25 asm (
26 "mov %fs:thread_local@TPOFF, %rax;"
27 "mov %%rax, %%rbx;"
28 :"=3DAb" (y)
29 );
For Non working no assembly output is produced with -S option.
This gives the following error message
tls_long.c:25: error: invalid 'asm': operand number missing after %-
letter
tls_long.c:25: error: invalid 'asm': operand number missing after %-
letter
Now if i change line 26 to
"mov %%fs:thread_local@TPOFF, %%rax;"
The code builds without any errors.
gcc -S output
mov %fs:thread_local@TPOFF, %rax;
mov %rax, %rbx;
But now the value which i get in rax is 0 which is incorrect.
thanks
GCC (which I assume this is) is a dreadful way to write assembler. I
don't use it for asm code but have run some tests and looked at
http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Extended-Asm.html
First, one percent or two?
asm("mov %eax, %ebx"); --> mov %eax, %ebx
asm("mov %%eax, %%ebx"); --> mov %%eax, %%ebx
asm("mov %%eax, %%ebx" :"=3Db" (y)); --> mov %eax, %ebx
The text after --> is the generated code and should have one percent
before register names. So it seems you need two percents when using a
constraint and one percent otherwise.
Second, C concatenates string literals and this happens in the asm()
construct so your example
asm ("mov %fs:thread_local@TPOFF, %rax;"
"mov %%rax, %%rbx;"
:"=3DAb" (y)
);
is effectively the same as
asm ("mov %fs:thread_local@TPOFF, %rax;mov %%rax, %%rbx;"
:"=3DAb" (y)
);
which is not what you wanted, and because this has a constraint the
two single percent signs result in the message, "error: invalid 'asm':
operand number missing after %-letter".
There seem to be other problems with your code too....
James