Why use RIP-relative addressing in NASM?

前端 未结 2 1352
梦毁少年i
梦毁少年i 2021-02-06 13:31

I have an assembly hello world program for Mac OS X that looks like this:

global _main


section .text

_main:
    mov rax, 0x2000004
    mov rdi, 1
    lea rsi,         


        
相关标签:
2条回答
  • 2021-02-06 13:57

    What is so special about lea that mov can't do?

    mov reg,imm loads an immediate constant into its destination operand. Immediate constant is encoded directly in the opcode, e.g. mov eax,someVar would be encoded as B8 EF CD AB 00 if address of someVar is 0x00ABCDEF. I.e. to encode such an instruction with imm being address of msg you need to know exact address of msg. In position-independent code you don't know it a priori.

    mov reg,[expression] loads the value located at address described by expression. The complex encoding scheme of x86 instructions allows to have quite complex expression: in general it's reg1+reg2*s+displ, where s can be 0,1,2,4, reg1 and reg2 can be general-purpose registers or zero, and displ is immediate displacement. In 64-bit mode expression can have one more form: RIP+displ, i.e. the address is calculated relative to the next instruction.

    lea reg,[expression] uses all this complex way of calculating addresses to load the address itself into reg (unlike mov, which dereferences the address calculated). Thus the information, unavailable at compilation time, namely absolute address which would be in RIP, can be encoded in the instruction without knowing its value. The nasm expression lea rsi,[rel msg] gets translated into something like

        lea rsi,[rip+(msg-nextInsn)]
    nextInsn:
    

    which uses the relative address msg-nextInsn instead of absolute address of msg, thus allowing the assembler to not know the actual address but still encode the instruction.

    0 讨论(0)
  • 2021-02-06 14:00

    What is so special about lea that mov can't do?

    LEA r, [rel symbol] can access RIP at run-time. mov r, imm can't. The immediate constant is encoded into the binary representation of the instruction, which means it won't work if the code+data are mapped to an address that isn't known at link time. (i.e. it's position-dependent code.)

    This is why RIP-relative addressing is so nice for PIC (position-independent code): instead of needing a level of indirection through the Global Offset Table to access even static data defined in the same object file, you can just use RIP-relative addresses.

    MacOS X requires PIC even in executables (not just shared libraries), so you need to avoid absolute addressing in all cases.

    0 讨论(0)
提交回复
热议问题