问题
: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.
回答1:
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).
回答2:
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" !
来源:https://stackoverflow.com/questions/8290987/asm-error-message-rax-edx-4-is-not-a-valid-base-index-expression