why we can't move a 64-bit immediate value to memory?

前端 未结 2 1087
半阙折子戏
半阙折子戏 2020-12-11 22:44

First I am a little bit confused with the differences between movq and movabsq, my text book says:

The regular movq

2条回答
  •  既然无缘
    2020-12-11 23:05

    For the first question:

    From the official documentation of gnu assembler:

    In 64-bit code, movabs can be used to encode the mov instruction with the 64-bit displacement or immediate operand.

    mov reg64, imm (in intel syntax, destination first) is the only instruction that accepts a 64-bit immediate value as a parameter. That's why you can't write a 64-bit immediate value directly to memory.


    For the second question:

    For other destinations, for example a memory location, a 32-bit immediate can be sign-extended to a 64-bit immediate (which means the top 33 bits are the same there). In this case, you use the movq instruction.

    This is also possible if the target is a register, saving 3 bytes:

    C8 B0 FF FF FF 7F 00 00 00 00   movabs $0x7FFFFFFF, %rax
    C8 C7 C0 FF FF FF 7F            movq   $0x7FFFFFFF, %rax
    

    At the 64-bit immediate 0xFFFFFFFF, the top 33 bits are not the same, so movl cannot be used here. That's why I chose 0x7FFFFFFF in this example. But there is another option:

    When writing to a 32-bit register (the lower part of a 64-bit register), the upper 32-bit of the register are zeroed. For a 64-bit immediate whose upper 32-bits are zero, movl can therefore also be used, which saves another byte:

    C7 C0 FF FF FF 7F               movl   $0xFFFFFFFF, %eax
    

    GAS does not do this automatically, but it can choose between movabs and movq if you use mov, depending on the size of the immediate.

    Credit: Thanks to Peter Cordes for noting that I initially messed up something in my answer and adding further information.

提交回复
热议问题