0

I'm not sure if this is an assembly question or more a gas question. I've done the following to see how the assembler handles immediate values that are too large to encode in the respective register:

addb $0xFFFF,      %bl
addw $0xFFFFFF,    %bx
addl $0xFFFFFFFFF, %ebx
addq $0xFFFFFFFFF, %rbx

And running $ as file.s files me the following warnings and errors:

file.s: Assembler messages:
file.s:5: Warning: 16777215 shortened to 65535
file.s:6: Warning: 68719476735 shortened to 4294967295
file.s:7: Error: operand type mismatch for `add'

Here are a few questions related to that:

  • bl: Why isn't a warning raised for trying to add in 0xFFFF into bl? It gets shortened to FF after assembling, but there's no warning message for it.
  • bx: 65535 or 0xFF FF is the max 16 bit value so that makes sense. There is a warning for this.
  • ebx: 4294967295 or 0xFF FF FF FF is the largest 32 bit value so that makes sense. There is a warning for this.
  • rbx: here was the surprising part for me, on overflow this actually raises an error and not a warning. Why does this one error?
David542
  • 104,438
  • 178
  • 489
  • 842
  • `0xFFFFFFFFF` is in-range for a 64-bit integer, but not encodeable as a 32-bit *sign-extended* immediate. It's better to error than to encode `-1` (`0xFFFFFFFFFFFFFFFF`) instead by truncating it to 32-bit. – Peter Cordes Oct 10 '20 at 03:17
  • @PeterCordes I see -- so the largest 'immediate' you immediate you can provide is 32-bits? Which would be sign-extended if moved into a 64-bit register? – David542 Oct 10 '20 at 03:18
  • 1
    Not just "would be"; it *is* sign-extended to 64-bit before doing 64-bit addition in `add $imm32, r/m64`. Read the manual https://www.felixcloutier.com/x86/add. (And see [x86\_64 Cannot add 64 bit value to rax, "operand mismatch on 'add'"](https://stackoverflow.com/q/58258882)). Same for every other instruction except `mov`, which does have an encoding that takes a 64-bit immediates (with a register destination). – Peter Cordes Oct 10 '20 at 03:20
  • IDK why GAS doesn't warn about truncating `addb $0xFFFF, %bl`. That seems like a bug. – Peter Cordes Oct 10 '20 at 03:23
  • @PeterCordes oh I see, thanks for pointing that out. It's clear on the doc page: `Add imm32 sign-extended to 64-bits to r/m64.` I think I might have been looking at the `mov` instruction by accident which does have 64bit. – David542 Oct 10 '20 at 03:27
  • So the RBX part is basically a duplicate of [x86\_64 Cannot add 64 bit value to rax, "operand mismatch on 'add'"](https://stackoverflow.com/q/58258882) and/or [Can I add 64bit constants to 64bit registers?](https://stackoverflow.com/q/20020589). (You claim "It says you can add a 64-bit constant to a register here", but that's the opposite of what the linked answer says, unless you mean via `mov reg, imm64` / `add reg,reg`). – Peter Cordes Oct 10 '20 at 03:36
  • The part about not getting a warning for `addb` is totally separate; the immediate is larger than the operand size, unlike with your addq example, and whatever is happening there is totally different. That's the only part of this that's interesting, IMO; I'd suggest editing to remove the distractions, or maybe just link to an answer to explain the addq. Or change or add another addq example using a value that's actually larger than 2^64. (Although GAS probably rejects that in any context.) – Peter Cordes Oct 10 '20 at 03:38
  • 1
    @PeterCordes I see, yes that link answers the part about add64. I misread it -- it clearly says you can `mov` 64 but not `add` (directly). – David542 Oct 10 '20 at 03:41

0 Answers0