Введение в ассемблер GNU для Intel x86-64

Архитектура Intel x86-64

Последнее обновление: 23.09.2023

Архитектура процессоров Intel x86-64 является на сегодняшний день доминирующей архитектурой для различного рода устройств - настольных компьютеров, ноутбуков, серверов. Семейство процессоров Intel обычно классифицируется как машина с архитектурой фон Неймана - такая машина, которая содержит три основных компонента: центральный процессор (ЦП), память и устройства ввода/вывода (I/0). Эти три компонента связаны между собой через системную шину (состоит из шины адреса, данных и управления). Процессор взаимодействует с памятью и устройствами ввода-вывода, передавая через адресную шину числовой адрес участка памяти или порта устройства ввода-вывода. Через шину данных процессор, память и устройства ввода-вывода обмениваются между собой данными. Через шину управления (control bus) передаются сигналы, которые определяют направление передачи данных (в или из памяти, а также в или из устройства ввода-вывода).

Зачем изучать ассемблер в эпоху высокоуровневых языков? Ассемблер помогает лучше понять архитектуру компьютера. Знание ассемблера может помочь при реверс-инжениринге, анализе вирусов и прочих вредоносных программ, а также при их создании и поиске уязвимостей. В конце концов понимание работы ассемблера является важным навыком в низкоуровневом программировании, например, при написании операционных систем и драйверов.

При работе следует определиться с ассемблером, который будет использоваться для сборки программ. В данном руководстве мы будем использовать GNU Assembler или сокращенно GAS. Он поставляется как компонент набора компиляторов GCC. Поскольку компиляторы GCC довольно распространенны и являются кроссплатформенными, то GAC соответственно также можно использовать на разных платформах. Из недостатков можно отметить, что GAS использует синтаксис, отличный от синтаксиса Intel (а именно синтаксис AT&T), что может немного усложнить перенос программ с одного ассемблера на другой. Хотя последние версии GCC включают параметр «-masm», который при значении "-masm=intel" позволяет встраивать код ассемблера с использованием синтаксиса Intel. Эквивалентным параметром для GAS является "-msyntax=intel" или использование директивы ".intel_syntax".

Но прежде чем переходить непосредственно к написанию программ на ассемблере GAS, посмотрим вкратце, что представляет собой архитектура x86-64.

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

Архитектура x86 обозначает большое семейство процессоров как с 16-битной, так и с 32-битной архитектурой набора команд. История x86 началась с выходом процессора Intel 8086 в 1978 году. В 1979 году выходит функционально похожий на 8086 процессор Intel 8088. Последующие поколения этой серии процессоров получили названия 80186, 80286, 80386 и 80486, что привело к возникновению термина «x86» как сокращению для семьи процессоров. В последствии процессоры и серии процессоров Intel, которые представляли эту архитектуру, имели совершенно другие имена, например, серии Pentium, Celeron и т.д., но они принадлежали также к этой архитектуре. Кроме компании Intel процессоры на архитектуре x86 также выпускала компания AMD, в частности, это серии процессоров Athlon, Duron и т.д.

Процессоры 8086 и 8088 были 16-битными, несмотря на 8-битную шину данных в 8088. Регистры в этих процессорах имели разрядность 16 бит, а набор инструкций работал с 16-битными данными. 8086 и 8088 не поддерживали многие функции современных процессоров, например, виртуальную память и уровни защиты. Эти процессоры имели 20 адресных линий, что ограничивало размер используемой память 1 мегабайтом. Но 20-битный адрес не мог поместиться в 16-битный регистр, поэтому для работы с адресами необходимо было использовать несколько сложную систему сегментных регистров и смещений для доступа к полному адресному пространству размером 1 МБ.

В 1985 году компания Intel выпустила процессор 80386, который был важным шагом вперед в развитии архитектуры x86. Этот процессор был 32-битным. И адреса, регистры и АЛУ также имели разрядность в 32 бита, а инструкции изначально работали с операндами размером до 32 бит. Кроме того, он использовал защищенный режим (protected mode), в котором был реализан многоуровневый механизм привилегий из трех уровней - от 0 до 3. Уровень 0 представлял уровень с максимальными правами и предназначался для ядра операционной системы, тогда как уровень 3 предназначался для прикладных пользовательских программ. Уровни 1 и 2 - промежуточные. Стоит отметить, что операционные системы Windows и Linux до сих пор реализуют только 2 уровня - 0 и 3. 80386 поддерживал память размером 4 ГБ, в которой адреса были 32-битными, а манипуляции с сегментными регистрами и смещениями больше не требовались. Кроме того, была добавлена поддержка выгружаемой виртуальной памяти.

После этого процессоры данной архитектуры стали 32-битными.

Архитектура x86 имеет прямой порядок следования байтов (little-endian) что означает, что многобайтовые значения хранятся в памяти с младшим значащим байтом по младшему адресу и старшим значащим байтом по старшему адресу.

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

Архитектура х64 изначально представляла расширение процессора x86 и его набора инструкций до 64 бит. Первая специафикация этой архитектуры назвалась AMD64 и была представлена компанией AMD в 2000 году. Первый процессор AMD64, Opteron, был выпущен в 2003 году.

Компания Intel паралелльно развивала собственную 64-разрядную архитектуру, которая называлась IA-64 и которая была несовместима с х86. Результатом развития этой архитектуры стал процессор Itanium, который вышел в 2001 году. Однако затем Intel решили пойти по пути AMD и также стали развивать 64-разрядную архитектуру как расширение для x86 и которая была бы совместима с AMD64, получившую название Intel 64. Первым процессором Intel на 64-разрядной архитектуре - Xeon вышел в 2004 году. В конечном счете эта архитектура стала называться x86-64, отражая эволюцию x86 до 64 бит, и, как правило, для ее названия употребляется сокращение x64.

Стоит отметить, что первая версия операционной системы Linux, которая поддерживала архитектуру x64, была выпущена в 2001 году, задолго до появления первых процессоров x64. ОС Windows начала поддерживать архитектуру x64 в 2005 году.

Процессоры, которые реализуют архитектуры AMD64 и Intel 64, в значительной степени совместимы на уровне набора инструкций программ пользовательского режима. Между архитектурами есть несколько различий. Как правило, компиляторы операционных систем и языков программирования управляют этими различиями, что делает их редкой проблемой для разработчиков прикладного программного обеспечения. Разработчики же системного программного обеспечения ядра, драйверов и ассемблерного кода должны учитывать эти различия.

Основные особенности архитектуры x64:

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

  • Восемь 32-битных регистров общего назначения x86 расширены до 64 бит в процессорах x64. Префикс имени регистра R указывает на 64-битные регистры. Например, в x64 расширенный регистр x86 EAX называется RAX. Подкомпоненты регистра x86 EAX, AX, AH и AL по-прежнему доступны в x64.

  • Архитектура x64 реализует практически тот же набор инструкций, что и x86. При работе в 64-битном режиме архитектура x64 по умолчанию размер адреса - 64 бита, а размер операнда - 32 бита.

  • Указатель инструкций, RIP, теперь 64-битный. Регистр флагов, RFLAGS, также расширяется до 64 бит, хотя старшие 32 бита зарезервированы. Младшие 32 бита RFLAGS аналогичны EFLAGS в архитектуре x86.

  • Добавлено восемь 64-битных регистров общего назначения с именами от R8 до R15.

  • Добавлена встроенная поддержка для 64-битных целых чисел.

  • Процессоры x64 сохраняют возможность работы в режиме совместимости с x86. Этот режим позволяет использовать 32-разрядные операционные системы и позволяет любому приложению, созданному для x86, работать на процессорах x64. В 32-битном режиме совместимости 64-битные расширения недоступны.

  • Виртуальные адреса в архитектуре x64 имеют ширину 64 бита, теоретически поддерживая адресное пространство размером 16 экзабайт (EB), что эквивалентно 264 байтам. Однако современные процессоры AMD и Intel поддерживают только 48-битное виртуальное адресное пространство. Это ограничение снижает аппаратную сложность процессора, но при этом размер поддерживаемой памяти снижается до 256 терабайт виртуального адресного пространства. Процессоры текущего поколения также поддерживают максимум 48 бит физического адресного пространства. Это теоретически позволяет процессору адресовать 256 ТБ физической оперативной памяти, но современные материнские платы не поддерживают такие размеры DRAM.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850