Consider the following variable reference in x64 Intel assembly, where the variable a
is declared in the .data
section:
mov eax, dword ptr [rip + _a]
I have trouble understanding how this variable reference works. Since a
is a symbol corresponding to the runtime address of the variable (with relocation), how can [rip + _a]
dereference the correct memory location of a
? Indeed, rip
holds the address of the current instruction, which is a large positive integer, so the addition results in an incorrect address of a
?
Conversely, if I use x86 syntax (which is very intuitive):
mov eax, dword ptr [_a]
, I get the following error: 32-bit absolute addressing is not supported in 64-bit mode.
Any explanation?
1 int a = 5;
2
3 int main() {
4 int b = a;
5 return b;
6 }
Compilation: gcc -S -masm=intel abs_ref.c -o abs_ref
:
1 .section __TEXT,__text,regular,pure_instructions
2 .build_version macos, 10, 14
3 .intel_syntax noprefix
4 .globl _main ## -- Begin function main
5 .p2align 4, 0x90
6 _main: ## @main
7 .cfi_startproc
8 ## %bb.0:
9 push rbp
10 .cfi_def_cfa_offset 16
11 .cfi_offset rbp, -16
12 mov rbp, rsp
13 .cfi_def_cfa_register rbp
14 mov dword ptr [rbp - 4], 0
15 mov eax, dword ptr [rip + _a]
16 mov dword ptr [rbp - 8], eax
17 mov eax, dword ptr [rbp - 8]
18 pop rbp
19 ret
20 .cfi_endproc
21 ## -- End function
22 .section __DATA,__data
23 .globl _a ## @a
24 .p2align 2
25 _a:
26 .long 5 ## 0x5
27
28
29 .subsections_via_symbols
mov eax, dword ptr [rip + _a]
? MASM? If it does it will probably use the right offset to makerip + _a
point to_a
(i.e. it will not use the address of_a
). In NASM you usemov eax, DWORD [REL _a]
(or you set it to be the default). When writing assembly, the RIP-relative thing is used as in "compute this address relative to RIP" not as in "add this specific offset to RIP" since you almost never know where your code will be. – Quadrupletrip
register; however, the syntax doesn't reflect that very good, does it? So, what you are saying is that the loader replaces[rip + _a]
with the absolute address ofa
at runtime; or will_a
be replaced with the relative offset ofa
(possible negative) w.r.t to the address of the instruction (mov rax, dword ptr [rip + _a]
)? – Flavine_a
is the final target. Inspect the opcodes and you will see. That is indeed misleading notation. – Quadruplet