3

I'm doing x86 asembly code and I keep getting this Error: operand type mismatch for `cmp's

The line of code it appears at is:

cmpb %rdi, $0
Paul R
  • 195,989
  • 32
  • 353
  • 519
Tyree Jackson
  • 31
  • 1
  • 4
  • 5
    Since this appears to be AT&T syntax code, the immediate operand should be on the left. – Michael Oct 10 '18 at 06:47
  • @DavidWohlferd: The immediate might be a byte though. There's both `CMP r/m64, imm8` and `CMP r/m64, imm32`, so you need a way to disambiguate between the two. – Michael Oct 10 '18 at 06:53
  • @Michael The size suffix does not indicate the size of the immediate but rather the size of the operation. – fuz Oct 10 '18 at 09:36
  • and it's not the best way to check for zero [Test whether a register is zero with CMP reg,0 vs OR reg,reg?](https://stackoverflow.com/q/33721204/995714) – phuclv Oct 22 '18 at 07:36

1 Answers1

5

In AT&T syntax (which is what you use), instructions have a size suffix to indicate the operand size. The size suffixes are:

b byte        1 bytes
w word        2 bytes
l long        4 bytes
q quad-word   8 bytes

s single      4 bytes
d double      8 bytes
t temporary  10 bytes

For example, cmpb is the instruction cmp with a 1 byte operand size indicated. However, your code uses %rdi as an operand which is a quad-word (64 bit) register, so the assembler rightfully complains that this is the wrong operand.

To fix this issue, simply leave out the size suffix; the assembler is able to infer it unless all operands are immediates or memory operands:

cmp %rdi, $0

You can of course also explicitly supply a size suffix; in this case, q is appropriate as indicated in the previous table:

cmpq %rdi, $0

That said, note that as with most instructions, the immediate operand has to be the first operand to cmpq:

cmpq $0, %rdi

The other form is actually illegal.

fuz
  • 76,641
  • 24
  • 165
  • 316
  • 1
    `t` usually mean Ten Bytes , not temporary. – Michael Petch Oct 10 '18 at 16:39
  • 1
    @MichaelPetch That's a kind of retcon; `fstpt` is explicitly called “floating point store temporary” in the 8087 datasheet. – fuz Oct 10 '18 at 22:51
  • When it comes to the assemblers themselves an m80fp is usually identified as TWORD/TBYTE (depends on if you come from a MASM world or not) and the assemblers do not identify a TBYTE/TWORD as a "temporary". The T was to denote a Ten Byte (80-bit) operand.The `t` suffix in AT&T syntax operating in the same capacity. – Michael Petch Oct 10 '18 at 23:04
  • 2
    `cmp %rdi, $0` is still illegal: x86 only allows an immediate right hand side (Intel syntax) for `cmp` http://felixcloutier.com/x86/CMP.html, so only `cmp $0, %rdi` is allowed in AT&T. If you want to compare in the opposite direction, you need the constant in a register. (Doesn't matter for `0`, which should use `test %rdi,%rdi` anyway; neither direction can carry or overflow so you can always just use the opposite condition like jge instead of jl) – Peter Cordes Oct 22 '18 at 01:24
  • @PeterCordes addressed. – fuz Oct 22 '18 at 06:09