Reputation: 63
I'm wondering, is there a limitation on reading input variables based on the actual instruction?
I'm trying to read an input variable in inline assembly for a .rept
directive to repeat an instruction x
number of times.
However, the assembler complains with:
Error: negative count for REPT - ignored
Here's my approach:
const int x = 42;
__asm__ volatile (".rept %[in]" :: [in] "m" (x));
__asm__ volatile (".endr");
Trying to load the variable value into a register works just as expected:
int function(void) {
const int x = 42;
__asm__ volatile ("mov %[in], %%eax" :: [in] "m" (x));
__asm__ volatile ("ret");
}
returns 42
, disassembly looks as expected.
I tried writing this in assembly to see if a constant can be used with .rept
directive and it does so indeed
global _start
section .data
nvalue equ 39
section .text
_start:
push rbp
mov rbp, rsp
%rep nvalue
nop
%endrep
mov rax, 60
mov rdi, nvalue
syscall
Disassembly looks as expected:
Disassembly of section .text:
0000000000401000 <_start>:
401000: 55 push rbp
401001: 48 89 e5 mov rbp,rsp
401004: 90 nop
...
40102d: 90 nop
40102e: b8 3c 00 00 00 mov eax,0x3c
401033: bf 2a 00 00 00 mov edi,0x2a
401038: 0f 05 syscall
Am I confusing .rept
with %rep
and do they not represent identical operation?
Any help will be greatly appreciated.
Upvotes: 1
Views: 1229
Reputation: 58052
As mentioned in comments, an i
operand will normally be inserted with a leading $
sign, which is correct as an immediate operand in AT&T syntax but not good for an assembler directive like .rept
. You can suppress this with the c
modifier, see Section 6.47.2.8 of the GCC manual:
void many_nops(void) {
const int num = 42;
asm(".rept %c0 ; nop ; .endr" : : "i" (num));
}
This will inline 42 nop
instructions. Of course this will only work if num
can be folded as a compile-time constant; in particular you must compile with optimization for it to work.
You could also use Intel asm syntax with -masm=intel
, in which constants don't get a leading $
in the first place.
Note that there are a number of other problems with your inline asm (you can't ret
from inline asm, shouldn't split code between multiple asm
statements, etc.) so you might want to start by reading some of the FAQs at https://stackoverflow.com/tags/inline-assembly/info.
The issue with .rept
versus %rep
: the first is the correct syntax for the GNU assembler gas
which is normally used for assembling GCC output, and the second is for the nasm
assembler.
Upvotes: 4