1
votes

When I try to compile

int main(void)
{
        __asm__("cmp  $0x1,0x555557e20b58");    

    return 0;
}

I get

main.cpp: Assembler messages:
main.cpp:6: Error: operand type mismatch for `cmp'

The compile command is "gcc main.cpp -o main". It works with an m32 value, e.g. "asm("cmp $0x1,0x555557e2");".

According to this X86 Opcode and Instruction Reference , there is a command with opcode 0x83, modrm_reg:7, called "CMP", first arg: r/m16/32/64, second arg: imm8, description: "Compare Two Operands". Why can gcc not find it? I tried using CMPQ, to no avail.

The reason I try to compile this instruction is that I would like to see the machine code.

This is from the "Intel® 64 and IA-32 Architectures Software Developer’s Manual":

REX.W + 83 /7 ib    CMP r/m64, imm8 MI  Valid   N.E.    Compare imm8 with r/m64.

So for the machine code, I would expect

  • the first byte to be 0x48 (REX.W) and
  • the second byte to be the opcode 0x83.
  • For the 3rd byte (ModR/M), I'm lost:

The manual says "/digit — A digit between 0 and 7 indicates that the ModR/M byte of the instruction uses only the r/m (register or memory) operand. The reg field contains the digit that provides an extension to the instruction's opcode." So from that, I understand modrm_reg = 7. But what goes into r/m then?

  • byte 4 - 11 would be the 8-byte value
  • byte 12 the compare imm8 value
1
x86 instructions have only 1 immediate, and only movabs can receive a 64-bit immediate, others have a maximum 32-bit immediatephuclv
@phuclv, the problem isn’t the immediate, it’s the addressing mode.prl
You also need an operand size suffix since cmp $1, addr can't infer whether you want to compare a byte, word, etc. If you want the r/m64 form, then use cmpq.Nate Eldredge

1 Answers

0
votes

The is no instruction format in x86_64 that specifies a 64-bit absolute address -- the r/m encoding that in 32-bit mode specifies a 32-bit absolute address is used for RIP-relative addressing -- a 32-bit (signed) displacement from the instruction pointer.

So if you want to do something like this in 64-bit mode, you'll need something like

 __asm__("cmp  $0x1,symbol(%rip)");

and arrange in the linker to have the code linked at a fixed address (no ASLR) and have symbol defined to be 0x555557e20b58.