Архитектура 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.