Reputation: 57
:96: Error: `(%rax,%edx,4)' is not a valid base/index expression
line97: Error: `-4(%rax,%edx,4)' is not a valid base/index expression
line101: Error: `(%rax,%edx,4)' is not a valid base/index expression
line102: Error: `-4(%rax,%edx,4)' is not a valid base/index expression
I get these error messages and am not sure how to fix it.
This is my code:
__asm__ (
"loop: \n\t"
"movl $1,%3\n\t"
"movl $0, %6\n"
"start: \n\t"
"movl (%1,%3,4),%4\n\t"
"movl -4(%1, %3, 4), %5\n\t"
"cmpl %4, %5\n\t"
"jle next\n\t"
"xchgl %4, %5\n\t"
"movl %4, (%1, %3, 4)\n\t"
"movl %5, -4(%1, %3, 4)\n\t"
"movl $1, %6\n\t"
"next: \n\t"
"incl %3 \n\t"
"cmpl %3, %2\n\t"
"jge start\n\t"
"cmpl $0, %6\n\t"
"je end\n\t"
"jmp loop\n\t"
"end: \n\t"
Some help explaining how to fix these error message, please. I am trying to make a bubble sort in ASM.
Upvotes: 1
Views: 4654
Reputation: 51
I also had the same issue in a simple array sum, and after using @FrankH. 's advice, (cheers @FrankH.)
it works. here is my inline asm code for gcc
inline int array_sum(const int *value, const int &size) {
int sum = 0;
// for (int i = 0; i < size; i++) {
// sum = sum + value[i];
// }
for (int i = 0; i < size; i++)
asm("addl (%1,%2,4),%0"
: "=r"(sum)
: "r"((uintptr_t)value), "r"((uintptr_t)i), "0"(sum)
: "cc");
return (sum);
}
Upvotes: 1
Reputation: 18217
Most likely cause of your problem is the use of an explicit 32bit integer type in the %3
operand. You haven't shown the constraints list for your inline assembly. But the above occurs if you do:
int main(int argc, char **argv)
{
int result, foobaridx;
foobaridx = foobar[4];
__asm__ (
" dec %2\n\t"
" movl (%1, %2, 4), %0\n\t"
: "=r"(result) : "r"(foobar), "r"(foobaridx) : "memory", "cc");
return result;
}
Compiling this in 32bit mode works alright:
$ gcc -O8 -m32 -c tt.c $ objdump -d tt.o tt.o: file format elf32-i386 00000000 : 0: 55 push %ebp 1: b8 00 00 00 00 mov $0x0,%eax 6: 89 e5 mov %esp,%ebp 8: 83 ec 08 sub $0x8,%esp b: 8b 15 10 00 00 00 mov 0x10,%edx 11: 83 e4 f0 and $0xfffffff0,%esp 14: 4a dec %edx 15: 8b 04 90 mov (%eax,%edx,4),%eax 18: 83 ec 10 sub $0x10,%esp 1b: c9 leave 1c: c3 ret
But in 64bit mode, the compiler/assembler doesn't like it:
$ gcc -O8 -c tt.c /tmp/cckylXxC.s: Assembler messages: /tmp/cckylXxC.s:12: Error: `(%rax,%edx,4)' is not a valid base/index expression
The way to fix this is to use #include <stdint.h>
and cast register operands that'll end up being used for in addressing (as base or index registers) to uintptr_t
(which is an integer data type guaranteed to be 'size-compatible' to pointers, no matter whether you're on 32bit or 64bit). With that change, the 64bit compile succeeds and creates the following output:
$ gcc -O8 -c tt.c $ objdump -d tt.o tt.o: file format elf64-x86-64 Disassembly of section .text: 0000000000000000 : 0: 48 63 15 00 00 00 00 movslq 0(%rip),%rdx # 7 7: b8 00 00 00 00 mov $0x0,%eax c: 48 ff ca dec %rdx f: 8b 04 90 mov (%rax,%rdx,4),%eax 12: c3 retq
Good luck making your inline assembly "32/64bit agnostic" !
Upvotes: 5
Reputation: 45173
You didn't say what processor you are targeting, but it appears to be x64. On x64, (%rax, %edx, 4)
is not a legal combination. Consult the processor manual for a list of valid addressing modes. My guess is that you meant (%rax, %rdx, 4)
.
Upvotes: 6