In x64, I want to read from memory a 32-bit value given a 64-bit address. This seems rather trivial, just use the movl instruction.
However, with GCC inline "extended" assembler, I can't make this work. The following is my code:
unsigned row = 0;
__asm __volatile__
(
"again:"
"movzbq (%[px]), %%rax\n"
"movzwq (%[symbols],%%rax,2), %%rax\n"
"add %[table], %%rax\n"
"movl (%%rax,%[row],4), %[row]\n" /* <------------ */
"cmp %[row], %[match_limit]; jb end;\n"
"inc %[px]\n"
"cmp %[px_end], %[px]; jb again\n"
"end:\n"
: "=r" (row), "=r" (px)
: [row] "0" (row),
[px] "1" (px),
[px_end] "r" (px_end),
[symbols] "r" (char_to_symbol),
[table] "r" (table),
[match_limit] "r" (match_limit)
: "%rax"
);
This gives me "invalid operand for instruction" error message. If I change the movl to a movslq, it'll do what I want (as long as my number is 31 bits or less). In other words, what I want is a movzlq behavior -- except that doesn't exist, because all moves will zero-extend anyway in x64.
I'm really new to GCC's extended inline syntax. How do I get movl in this location?