0
votes

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?

1
This is AT&T syntax -- the destination is %[row], not %rax - RobertDavidGraham
It appears that you're trying to move from memory to memory. This can't be done with mov. - Jonathon Reinhart

1 Answers

2
votes

You need to use the k operand modifier for the (lower) 32-bit register, e.g.,

movl (%%rax,%0,4), %k0

I'm not sure where to find a definitive list of these. There are some in these answers, and in this tutorial.