What is the %rip register and can you modify it directly?
%rip is the instruction pointer — it holds the address of the next instruction. You cannot write it directly; it changes only as a side effect of jumps, calls, and returns.
* RIP-relative addressing computes data addresses as an offset from the current instruction, so code needs no fixed load address — the basis of PIC and ASLR. *
%rip is what makes the processor advance through code. There is no mov something, %rip; instead it is updated implicitly by control-flow instructions (jmp, call, ret, conditional jumps). It is, however, readable inside an addressing mode, which gives rise to one of the most important patterns in modern code: RIP-relative addressing.
mov global_var(%rip), %rax # address = %rip + (offset to global_var)
lea message(%rip), %rdi # load the address of message
Why this matters: computing data addresses relative to the current instruction rather than as absolute constants is what makes code position-independent (PIC). That in turn is what allows shared libraries to load at any address and enables ASLR, a key security defense. A 32-bit offset is plenty because code and its nearby data are never more than 2 GB apart.
Go deeper:
Program counter (Wikipedia) — the instruction pointer holding the next-instruction address.
Position-independent code (Wikipedia) — connects RIP-relative addressing to PIC and ASLR.