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.
.reptis a directive to the assembler to repeat code. It is not going to take a memory reference, which you specify with"m". The compiler probably writes the memory reference as something like-4(%rbp), hence the error message about a negative value. I do not think GCC or Clang has a constraint for this. You can use"i"for an immediate operand, but that comes with the marker that denotes an immediate operand in an instruction,$in Intel assembly, so it puts$42in the assembly, whereas you need a plain42. There may not be a way to do this.retin anasm()statement, except as part of the body of an__attribute__((naked))function. (And in that case, the entire body has to be a Basic Asm statement; no input/output constraints. i.e. it's a way to let the compiler do name mangling while you write the whole function body in asm.) Other than that, you can'tret; that will break when the compiler inlines your function into some caller.int function(), I can see that[rbp-0x4]is indeed the product of the memory reference. Thank you very much for your explanation Eric.function()frommain()and all hell broke loose.asmstatement, you need to mention it as a clobber or an output operand. i.e. your asm that writes EAX steps on the compiler's toes, and you should expect breakage.