Когда и как решается проблема адресации% rip-relative?

Возьмите следующую программу сборки:

_start:
    mov myvar,       %rax
    mov myvar(%rip), %rax
    mov myvar(%rip), %rax
    mov myvar(%rip), %rax
    mov myvar(%rip), %rax

При запуске в gdb выдает следующее:

!0x00000000004000b0  ? mov    0x600107,%rax
 0x00000000004000b8  ? mov    0x200048(%rip),%rax        # 0x600107
 0x00000000004000bf  ? mov    0x200041(%rip),%rax        # 0x600107
 0x00000000004000c6  ? mov    0x20003a(%rip),%rax        # 0x600107
 0x00000000004000cd  ? mov    0x200033(%rip),%rax        # 0x600107

Конечно, неудивительно, что все ссылки myvar разрешаются в 0x600107. Где (или, возможно, когда лучше) относительные %rip элементы разрешаются в фактический адрес? Как этот процесс работает на высоком уровне?

По теме: Почему эта инструкция MOVSS использовать относительную адресацию RIP?.


person carl.hiass    schedule 25.08.2020    source источник
comment
Это решается во время выполнения ЦП, поэтому это специальный режим адресации. Если бы это было только на уровне исходного кода, для этого не потребовался бы отдельный синтаксис.   -  person Peter Cordes    schedule 25.08.2020
comment
См. что делает mov offset (% rip),% rax?. Также Можно ли использовать rip с другим регистром с относительной адресацией RIP? объясняет некоторые детали кодирования машинного кода. Также wiki.osdev.org/. Как работают ссылки на относительные переменные RIP, такие как [RIP + _a] в Intel-синтаксисе x86-64 GAS? есть несколько примеров Машинный код.   -  person Peter Cordes    schedule 25.08.2020
comment
В любом случае, вы спрашиваете, как ЦП декодирует машинный код, который использует относительный адрес RIP? Или как инструменты (например, ассемблер или компоновщик) в первую очередь определяют правильный относительный адрес?   -  person Peter Cordes    schedule 25.08.2020
comment
@PeterCordes Я бы сказал немного и того, и другого, но если ассемблер / компоновщик в основном «откладывает» его на процессор, тогда да, было бы действительно здорово понять (на базовом уровне), как это работает и декодируется.   -  person carl.hiass    schedule 25.08.2020
comment
Затем прочтите wiki.osdev.org/. x86-64 перепрофилировал один из 2-х избыточных способов кодирования [disp32] (с / без SIB); более короткий (без SIB) означает [rip+rel32] вместо [disp32]. ЦП знает адрес конца инструкции, поэтому он может производить вычисления.   -  person Peter Cordes    schedule 25.08.2020