Поделиться через


Архитектура x64

Архитектура x64 является расширением x86 с обратной совместимостью. Он предоставляет новый 64-разрядный и устаревший 32-разрядный режим, который идентичен x86.

Термин "x64" включает amd 64 и Intel64. Наборы инструкций практически идентичны.

Регистры

x64 расширяет 8 регистров общего назначения x86 до 64-разрядных и добавляет 8 новых 64-разрядных регистров. Имена 64-разрядных регистров начинаются с "r". Например, 64-разрядное расширение eax называется rax. Новые регистры называются с r8 по r15.

Нижние 32 бита, 16 битов и 8 бит каждого регистра напрямую адресуются в операндах. Сюда входят регистры, такие как esi, более низкие 8 битов которых ранее не были адресуемыми. В следующей таблице указаны имена языков сборок для нижних частей 64-разрядных регистров.

64-разрядный регистр Более низкие 32 бита Более низкие 16 бит Более низкие 8 бит
Rax Eax ax al
Rbx Ebx bx bl
rcx ecx Cx cl
rdx Edx dx Dl
Rsi Esi si sil
Rdi Edi di Dil
Rbp Ebp bp Bpl
Rsp Esp sp Spl
r8 r8d r8w r8b
r9 r9d r9w r9b
r10 r10d r10w r10b
r11 r11d r11w r11b
r12 r12d r12w r12b
r13 r13d r13w r13b
r14 r14d r14w r14b
r15 r15d r15w r15b

Операции, выводимые в 32-разрядный подрегистр, автоматически распространяются на весь 64-разрядный регистр. Операции, выводимые в 8-разрядные или 16-разрядные подрегистры, не расширяются с нуля (это совместимое поведение x86).

Высокие 8 бит ax, bx, cx и dx по-прежнему адресуются как ah, bh, ch, dh , но не могут использоваться со всеми типами операндов.

Указатель инструкций eip и регистр флагов расширен до 64 бит (rip и rflags соответственно).

Процессор x64 также предоставляет несколько наборов регистров с плавающей запятой:

  • Восемь 80-разрядных регистров x87.

  • Восемь 64-разрядных регистров MMX. (Эти регистры перекрываются с регистрами x87.)

  • Исходный набор из восьми 128-разрядных регистров SSE увеличен до шестнадцати.

Соглашения о вызовах

В отличие от x86, компилятор C/C++ поддерживает только одно соглашение о вызовах в x64. Это соглашение о вызовах использует преимущества увеличенного числа регистров, доступных в x64:

  • Первые четыре целочисленных параметра или параметры указателя передаются в регистрах rcx, rdx, r8 и r9 .

  • Первые четыре параметра с плавающей запятой передаются в первые четыре регистра SSE xmm0-xmm3.

  • Вызывающий объект резервирует место в стеке для аргументов, переданных в регистры. Вызываемая функция может использовать это пространство для переноса содержимого регистров в стек.

  • Все дополнительные аргументы передаются в стек.

  • Возвращаемое значение целого числа или указателя возвращается в регистре rax , а возвращаемое значение с плавающей запятой — в xmm0.

  • rax, rcx, rdx, r8-r11 являются переменными.

  • rbx, rbp, rdi, rsi, r12-r15 являются энергонезависимы.

Соглашение о вызовах для C++ аналогично. Этот указатель передается как неявный первый параметр. Следующие три параметра передаются в оставшихся регистрах, а остальные — в стеке.

Режимы адресации

Режимы адресации в 64-разрядном режиме похожи, но не идентичны x86.

  • Инструкции, ссылающиеся на 64-разрядные регистры, автоматически выполняются с 64-разрядной точностью. Например, mov rax, [rbx] перемещает 8 байт, начиная с rbx , в rax.

  • Для 64-разрядных непосредственных констант или адресов констант добавлена специальная форма инструкции mov . Для всех остальных инструкций непосредственные константы или адреса констант по-прежнему имеют 32 бита.

  • x64 предоставляет новый режим адресации относительного разрыва. Инструкции, ссылающиеся на один адрес константы, кодируются как смещения от rip. Например, инструкция mov rax, [addr] перемещает 8 байт, начиная сripaddr + , в rax.

Инструкции, такие как jmp, call, push и pop, которые неявно ссылаются на указатель инструкций, а указатель стека обрабатывает их как 64-разрядные регистры в x64.

См. также раздел