4
votes

I am converting 32-bit and 64-bit assembly language files from gas to MASM format, and ran across an instruction in my code that seems completely problematic. What I mean is, I see no way the assembler can know what size the operand is, whether the instruction fetches 8, 16, 32 or 64 bits from memory to perform the compare. Here is the instruction:

  • cmp $0, 8(%rsp)

If the instruction had been one of the following, the assembler could have figured out the size of the memory operand to fetch and compare based upon the register:

  • cmp %rax, 8(%rsp)
  • cmp %eax, 8(%rsp)
  • cmp %ax, 8(%rsp)

I would have thought that the instruction needs to be cmpb, cmpw, cmpl, cmpq... but no, my program assembles it fine with just cmp instruction. Unfortunately, I don't remember what this code is doing, and it is very non-obvious... so the easier way to resolve this is to know what the instruction is doing.

Anyone know? Anyone understand why this syntax (with operand size/type unspecified) is even allowed with an immediate operand?

1
Which one does it pick when it assembles it?Carl Norum
That's my question. I don't know!honestann
The easiest way to tell is to assemble with gas, then disassemble with objdump. (operand size used to default to 32 bits some years ago, and there was a warning for it. I'm unsure what it's now, in 64-bit code)Anton Kovalenko
But after looking at the disassembly, it appears to be fetching a 32-bit operand. But why, especially since this is a 64-bit mode program and 64-bit assembly language AND the only register specified in the instruction is %rsp, which is a 64-bit register.honestann
Looks that way. As long as I can be sure, I'm okay. But isn't that a very dangerous situation? I mean, gas syntax is so extremely hyper about making types clear.honestann

1 Answers

3
votes

It must have some kind of default. I tried on my machine, which says as is:

Apple Inc version cctools-836, GNU assembler version 1.38

And I get these results:

$ cat example.s 
    cmp $0, 8(%rsp)
$ make example.o
as   -o example.o example.s
$ otool -tV example.o
example.o:
(__TEXT,__text) section
0000000000000000    cmpl    $0x00,0x08(%rsp)

So on my machine, it picked cmpl. Using gcc rather than as gave me the same results, but using clang produced the error you expect:

$ clang -c example.s 
example.s:1:2: error: ambiguous instructions require an explicit suffix (could be 'cmpb', 'cmpw', 'cmpl', or 'cmpq')
 cmp $0, 8(%rsp)
 ^