64-битный привет Крис Касперски ака мыщъх Хакер, номер #083, стр. 083-118-4 [обзор x86-64] За подробным описанием x86-64-архитектуры лучше всего обратиться к фирменной документации AMD64 Technology - AMD64 Architecture Programmer's Manual Volume 1:Application Programming (http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/24593.pdf). Мы же ограничимся только беглым обзором основных нововведений. Наконец-то AMD сжалилась над нами и подарила программистам то, что все так долго ждали. К семи регистрам общего назначения (восьми - с учетом ESP) добавилось еще восемь, в результате чего их общее количество достигло 15 (16) штук. Старые регистры, расширенные до 64-бит, получили имена RAX, RBX, RCX, RDX, RBP, RSI, RDI, RSP, RIP и RFLAGS. Новые регистры остались безымянными и просто пронумерованы от R8 до R15. Для обращения к младшим 8-, 16- и 32-битам новых регистров можно использовать суффиксы b, w и d. Например, R9 - это 64-разряный регистр, R9b - его младший байт (по аналогии с AL), а R9w - младшее слово (тоже самое, что AX в EAX). Прямых наследников AH к сожалению не наблюдается и для манипуляции со средней частью регистров приходится извращаться со сдвигами и математическими операциями. Регистр, указатель команд RIP, теперь адресуется точно так же, как и все остальные регистры общего назначения. Программисты, заставшие живую PDP-11 (или ее отечественный клон - Электронику БК или УКНЦ), только презрительно хмыкнут - наконец-то до разработчиков стали доходить очевидные истины, которые на всех нормальных платформах были реализованы еще неизвестно когда. Возьмем простейший пример: загрузим в регистр AL опкод следующей машинной команды. На x86 приходится поступать так. [загрузка опкода следующей машинной команды в классическом x86] call $ + 5 ; запихнуть в стек адрес следующей команды и передать на нее управление pop ebx ; вытолкнуть из стека адрес возврата add ebx, 6 ; скорректировать адрес на размер команд pop/add/mov mov al, [ebx] ; теперь AL содержит опкод команды NOP NOP ; команда, чей опкод мы хотим загрузить в AL Это же умом поехать можно, пока все это напишешь! И еще здесь очень легко ошибиться в размере команд, который приходится вычислять либо вручную, либо загромождать листинг никому не нужными метками, к тому же неизбежно затрагивается стек, что в ряде случаев нежелательно или недопустимо (особенно в защитных механизмах, нашпигованных антиотлаодчными приемами). А теперь перепишем тот же самый пример на x86-64. [загрузка опкода следующей машинной команды на x86-64] mov al,[rip] ; загружаем опкод следующей машинной команды NOP ; команда, чем опкод мы хотим загрузить в AL Красота! Только следует помнить, что RIP всегда указывает на следующую, а отнюдь не текущую инструкцию! К сожалению, ни Jx RIP, ни CALL RIP не работают. Таких команд в лексиконе x86-64 просто нет. Но это еще что! Исчезла абсолютная адресация! Если нам надо изменить содержимое ячейки памяти по конкретному адресу, на x86 мы поступаем приблизительно так: |