Question

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?

Was it helpful?

Solution

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)
 ^
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top