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


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

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

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

РегистрЫ

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

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

64-разрядная регистрация Более низкие 32 бита Более низкий 16 бит Нижние 8 бит
rax eax ось Аль
rbx ebx bx BL
rcx ecx cx cl
rdx edx dx dl
rsi esi си sil
rdi edi ди dil
rbp ebp bp bpl
rsp эсп 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.

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

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

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

См. также