0

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 Answers1

2

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.

Community
  • 1
  • 1
Brett Hale
  • 21,653
  • 2
  • 61
  • 90
  • The answer to the SO question you linked to actually is still correct AFAIK - the only "canonical" list is in gcc's architecture definition file, https://raw.github.com/mirrors/gcc/trunk/gcc/config/i386/i386.md – FrankH. Mar 20 '14 at 09:57