2

I am having difficulty debugging or understanding the following error from gas:

movq $0x4461766964, -8(%rbp)  # "David" in hex
mov $SYS_STDOUT,    %edi
lea -8(%rbp),       %rsi
mov $5,             %edx
mov $SYS_WRITE,     %eax
syscall

Yet I get the following error:

file.s:33: Error: operand size mismatch for `movq'

I thought the movq command would move 8 bytes, from -8(%rbp) to -0(%rbp) so the resulting memory would look like:

%rbp-8 -7 -6 -5 -4 -3 -2 -1
     D  a  v  i  d

What do I seem to be missing or misunderstanding here? Note, doing movl seems to work here, it just truncates the number to 4-bytes, movl $0x4461766964, -8(%rbp):

$ ./file
# file.s: Assembler messages:
# file.s:33: Warning: 293692926308 shortened to 1635150180
# diva

And of course this works when adding it byte-by-byte:

movb $0x44, -8(%rbp)
movb $0x61, -7(%rbp)
movb $0x76, -6(%rbp)
movb $0x69, -5(%rbp)
movb $0x64, -4(%rbp)

Or this:

movl $0x44617669, -8(%rbp)
movl $0x64, -4(%rbp)

So why does the movq act so differently here?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
David542
  • 104,438
  • 178
  • 489
  • 842
  • 2
    AFAIK `movq` writes a sign extended 32-bit immediate. – ecm Sep 17 '20 at 05:19
  • @ecm I think its quad word (64 bits) -- https://www.felixcloutier.com/x86/movd:movq – David542 Sep 17 '20 at 05:22
  • 3
    Your link refers to the **Intel syntax** `movq` which is only for MMX and SSE registers. Plus, if you check the list, it doesn't have any immediate source forms. You'll have to check https://www.felixcloutier.com/x86/mov which is the GPR `mov` (which gets a `q` suffix for 64-bit operand size in AT&T syntax). The immediate source forms are listed at the end. Note that there is `MOV r64, imm64` but for an r/m64 destination there is only `MOV r/m64, imm32` which is listed as "Move imm32 sign extended to 64-bits to r/m64." – ecm Sep 17 '20 at 07:44
  • 2
    @David542 Nope, @ecm is right: this instruction can only take a 32 bit immediate. Instead, use `movabs imm64, reg` followed by `mov reg, mem64` – fuz Sep 17 '20 at 08:14
  • 1
    @ecm I see -- thanks for the feedback! – David542 Sep 17 '20 at 18:19
  • @fuz that will flip the endianness if it's zero-padded, won't it? Doing `movabsq $0x4461766964, %rax` `movq %rax, -8(%rbp)` prints `divaD` – David542 Sep 17 '20 at 23:14
  • 1
    @David542 that is correct. Recall that x86 is a little endian architecture, so the least significant byte in your constant is the first byte of the corresponding string. – fuz Sep 18 '20 at 11:14

0 Answers0