Архитектура amd64 (em64t)

Плюсы и минусы языка ассемблера

Преимущества:

  • Ассемблер – машинный язык, позволяющий максимально задействовать возможности процессора. При этом применять как можно меньше команд и обращений к памяти, что уменьшает размер и повышает скорость работы программы.
  • Доступ к расширенным наборам инструкций процессора (MMX, SSE, SSE2, SSE3).
  • Доступность портов входа-выхода и особых регистров процессора. Обычно в операционных системах этими опциями можно пользоваться лишь применительно к драйверам и модулям ядра.
  • Можно задействовать самомодифицирующийся код, причем и перемещаемый – тоже. Очень во многих случаях это недоступная опция из-за запрета на запись в страницы кода (аппаратных записей это тоже касается). Впрочем, большая часть используемых систем имеет недостатки, по причине которых становится доступно исполнение кода, если только он расположен в сегменте данных, где запись не запрещена.
  • Возможность адаптироваться под используемую платформу.

ТОП-30 IT-профессий 2022 года с доходом от 200 000 ₽

Команда GeekBrains совместно с международными специалистами по развитию карьеры
подготовили материалы, которые помогут вам начать путь к профессии мечты.

Подборка содержит только самые востребованные и высокооплачиваемые специальности
и направления в IT-сфере. 86% наших учеников с помощью данных материалов определились
с карьерной целью на ближайшее будущее!

Скачивайте и используйте уже сегодня:

Александр Сагун
Исполнительный директор Geekbrains

Топ-30 самых востребованных и высокооплачиваемых профессий 2022

Поможет разобраться в актуальной ситуации на рынке труда

Подборка 50+ ресурсов об IT-сфере

Только лучшие телеграм-каналы, каналы Youtube, подкасты, форумы и многое другое для того, чтобы узнавать новое про IT

ТОП 50+ сервисов и приложений от Geekbrains

Безопасные и надежные программы для работы в наши дни

Получить подборку бесплатно

pdf 3,7mb
doc 1,7mb

Уже скачали 16912

И всё же имейте в виду, что используемые сейчас в операционных системах и компиляторах современные технологии безопасности не дают возможности применять самомодифицирующийся код. Они не позволяют задействовать один и тот же участок памяти и для исполнения программы, и для записи (имеется в виду технология W^X).

W^X применяется в OpenBSD, Linux, иных BSD-системах. Microsoft Windows использует у себя близкую по сути технологию DEP (для версий от Windows XP SP2 и далее).

Недостатки:

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

Любые задачи, с которыми не справляются С/С++

Сейчас встраиваемые системы чаще всего программируют на C — это стандарт. Также популярность набирает C++. А на ассемблере в основном пишут специфические программы, например для цифровой обработки сигналов, или когда высокоуровневые языки уже не справляются:

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

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

Внешние ссылки [ править ]

  • Домашняя страница Intel Itanium
  • Домашняя страница серверов Hewlett Packard Enterprise Integrity
  • Технические характеристики Intel Itanium
  • Некоторая недокументированная информация о микроархитектуре Itanium 2 на Wayback Machine (архивировано 23 февраля 2007 г.)
  • Руководство по IA-64, включая примеры кода
  • Документы Itanium в HP
vтеПроцессоры Intel
Снято с производства
BCD- ориентированный ( 4-битный )
  • 4004 (1971)
  • 4040 (1974)
pre-x86 ( 8-бит )
  • 8008 (1972)
  • 8080 (1974)
  • 8085 (1977)
Ранний x86 ( 16 бит )
  • 8086 (1978)
  • 8088 (1979)
  • 80186 (1982)
  • 80188 (1982)
  • 80286 (1982)
x87 (внешние FPU )
8/16-битная шина данных
8087 (1980)
16-битная шина данных
80187
80287
80387SX
32-битная шина данных
80387DX
80487
IA-32 ( 32-разрядная версия )
  • 80386
    • SX
    • 376
    • БЫВШИЙ
  • 80486
    • SX
    • DX2
    • DX4
    • SL
    • RapidCAD
    • OverDrive
  • A100 / A110
  • Celeron (1998)
    • M
    • D (2004)
  • Pentium
    • Оригинальный P5
    • OverDrive
    • Pro
    • II
    • II OverDrive
    • III
    • 4
    • M
    • Двухъядерный
  • некоторое ядро
    • Соло
    • Дуэт
  • Толапай
x86-64 ( 64-бит )
  • Celeron
    • D
    • Двухъядерный
  • Pentium
    • 4
    • D
    • Экстремальное издание
    • Двухъядерный
  • некоторое ядро
    • 2
    • какой-то i7
Другой
CISC
iAPX 432
ЭПИЧЕСКИЙ
Itanium
RISC
i860
i960
Сильная рука
XScale
Текущий
IA-32 ( 32-разрядная версия )
  • Атом
    • CE
    • SoC
  • Кварк
x86-64 ( 64-бит )
  • Атом
    • CE
    • SoC
  • Celeron
  • Pentium
  • Основной
    • i3
    • i5
    • i7
    • i9
    • M
  • Xeon
    • E3
    • E5
    • E7
    • D
    • Фи
Списки
  • Celeron
  • Pentium
    • Pro
    • II
    • III
    • 4
    • D
    • M
  • Основной
    • Основной
    • 2
    • i3
    • i5
    • i7
    • i9
    • M
  • Атом
  • Xeon
  • Itanium
Связанный
  • Тик-тактовая модель
  • Чипсеты
  • Графические процессоры
  • GMA
  • Графика HD и Iris
  • ПЧ
  • SCH
  • ICH
  • PIIX
  • Stratix
  • Кодовые имена
Микроархитектуры
x86
P5
800 нм
P5
600 нм
P54C
350 нм
P54CS
P55C
250 нм
Тилламук
P6 , Pentium M , улучшенный Pentium M
500  нм
P6
350 нм
P6
Кламат
250 нм
Mendocino
Диксон
Тонга
Ковингтон
Deschutes
Катмай
Дрейк
Таннер
180 нм
Медная шахта
Коппермайн Т
Тимна
Каскады
130 нм
Туалатин
Баниас
90 нм
Дотан
Стили
Толапай
Canmore
65 нм
Йона
Соссаман
NetBurst
180 нм
Willamette
взращивать
130 нм
Northwood
Галлатин
Престония
90 нм
Теджас и Джейхок
Прескотт
Smithfield
Nocona
Ирвиндейл
Cranford
Потомак
Paxville
65 нм
Кедровая мельница
Presler
Демпси
Талса
Основной
65 нм
Мером-Л
Мером
Conroe-L
Allendale
Конро
Kentsfield
Woodcrest
Clovertown
Тайгертон
45 нм
Пенрин
Penryn-QC
Wolfdale
Yorkfield
Вольфдейл-ДП
Harpertown
Dunnington
Nehalem
45 нм
Auburndale
Бектон (Nehalem-EX)
Блумфилд
Кларксфилд
Гейнстаун (Nehalem-EP)
Havendale
Джаспер Форест
Lynnfield
32 нм
Arrandale
Кларкдейл
Галфтаун (Westmere-EP)
Westmere-EX
Песчаный Мост
32 нм
Песчаный Мост
Сэнди Бридж-E
Рад
22 морских миль
Ivy Bridge
Плющ Бридж-EP
Плющ Мост-EX
Haswell
22 морских миль
Haswell
14 нм
Broadwell
Skylake
14 нм
Skylake
Озеро Каби ( Янтарное озеро )
Кофейное озеро ( Виски-Лейк )
Каскадное озеро
Comet Lake
Cooper Lake
Palm Cove
10 нм
Cannon Lake
Санни Коув
10 нм
Ледяное озеро
Willow Cove
14 нм
Ракетное озеро
10 нм
Тигровое озеро
Сапфир-Рапидс
Золотая бухта
10 нм
Ольховое озеро
7 нм
Гранитные пороги
Redwood Cove
7 нм
Метеоритное озеро
Атом
Боннелл Солтуэлл
45 нм
Silverthorne
Diamondville
Pineview
Линкрофт
Tunnel Creek
Стеллартон
Sodaville
Groveland
32 нм
Cedarview
Penwell
Cloverview
Berryville
Centerton
Silvermont Airmont
22 морских миль
Valleyview
Танжер
Anniedale
14 нм
Cherryview
Голдмонт
14 нм
Голдмонт
Голдмонт Плюс
Tremont
10 нм
Tremont
Грейсмонт

Почему следует изучать язык ассемблера?

В современной практике индустриального программирования языки ассемблера применяются крайне редко. Для разработки низкоуровневых программ практически в большинстве случаев используется язык си, позволяющий достигать тех же целей многократно меньшими затратами труда, причем с такой же, а иногда и большей эффективностью получаемого исполняемого кода (последнее достигается за счет применения оптимизаторов). На ассемблере сейчас реализуются очень специфические участки ядер операционных систем и системных библиотек. Более того, программирование на ассемблере было вытеснено и из такой традиционно ассемблерной области, как программирование микроконтроллеров. Большей частью прошивки для них также пишут на си. Тем не менее программирование на языке ассемблера очень часто применяется при написании программ, использующих возможности процессора, не реализуемые языками высокого уровня, а также при программировании всевозможных нестандартных программистских хитростей. Отдельные ассемблерные модули, как и ассемблерные вставки в текст на других языках, присутствуют и в ядрах операционных систем, и в системных библиотеках того же языка си и других языков высокого уровня. Сегодня едва ли кому придет в голову сумасшедшая мысль писать крупную программу на чистом ассемблере.

Так зачем же тратить время на его изучение? По ряду веских причин, и вот одна из них: ассемблер — это краеугольный камень, на котором покоится все бесконечное пространство программирования, начиная от рождения первого процессора. Каждый физик мечтает разгадать тайну строения вселенной, найти эти загадочные первичные неделимые (низкоуровневые) элементы, из которых она состоит, не удовлетворяясь лишь смутным о том представлением квантовой теории. Ассемблер же и есть та первичная материя, из которой состоит вселенная процессора. Он — тот инструмент, который дает человеку способность мыслить в терминах машинных команд. А подобное умение просто необходимо любому профессиональному программисту, даже если никогда в жизни он не напишет ни единой ассемблерной строчки. Нельзя отрицать того, что невозможно стать математиком, совершенно не имея понятия об элементарной арифметике. На каком бы языке вы ни писали программы, необходимо хотя бы в общих чертах понимать, что конкретно будет делать процессор, исполняя ваше высочайшее повеление. Если такого понимания нет, программист начинает бездумно применять все доступные операции, совершенно не ведая, что на самом деле он творит.

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

Иными словами, до тех пор пока существуют процессоры, ассемблер будет необходим.

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

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

Разработка 64-битных приложений

Уроки разработки 64-битных приложений на языке Си/Си++Что такое 64-битные системыПоддержка 32-битных приложенийПеренос кода на 64-битные системы. За и противСоздание 64-битной конфигурацииСборка 64-битного приложенияОшибки в 64-битном кодеПроблемы выявления 64-битных ошибокСтатический анализ для выявления 64-битных ошибокПаттерн 01. Магические числаПаттерн 02. Функции с переменным количеством аргументовПаттерн 03. Операции сдвигаПаттерн 04. Виртуальные функцииПаттерн 05. Адресная арифметикаПаттерн 06. Изменение типа массиваПаттерн 07. Упаковка указателейПаттерн 08. Memsize-типы в объединенияхПаттерн 09. Смешанная арифметикаПаттерн 10. Хранение в double целочисленных значенийПаттерн 11. Сериализация и обмен даннымиПаттерн 12. ИсключенияПаттерн 13. Выравнивание данныхПаттерн 14. Перегруженные функцииПаттерн 15. Рост размеров структурФантомные ошибкиПрактическое знакомство с паттернами 64-битных ошибокОптимизация 64-битных программОсобенности создания инсталляторов для 64-битного окруженияОценка стоимости процесса 64-битной миграции Си/Си++ приложенийраздел с обзорами статей

Немного о процессорах и машинном языке

Чтобы объяснить, что такое язык ассемблера, начнём с того, как вообще работает процессор и на каком языке с ним можно «разговаривать».

Процессор — это электронное устройство (сейчас крошечная микросхема, а раньше процессоры занимали целые залы), не понимающее слов и цифр. Он реагирует только на два уровня напряжения: высокий — единица, низкий — ноль. Поэтому каждая процессорная команда — это последовательность нулей и единиц: 1 — есть импульс, 0 — нет.

Для работы с процессором используется машинный язык. Он состоит из инструкций, записанных в двоичном коде. Каждая инструкция определяет одну простую машинную операцию: арифметическую над числами, логическую (поразрядную), ввода-вывода и так далее.

Например, для Intel 8088 инструкция 0000001111000011B — это операция сложения двух чисел, а 0010101111000011B — вычитания.

Программировать на машинном языке нелегко — приходится работать с огромными цепочками нулей и единиц. Трудно написать или проверить такую программу, а уж тем более разобраться в чужом коде.

Стресс-тест стабильности системы

Провести диагностику оборудования в AIDA64 помогут стресс-тесты. Для запуска одного из них разворачиваем раздел «Тест» и выбираем необходимый.

Три первых обозначены иконкой ОЗУ и отвечают за неё, пять последующих – за процессор, остальные – за математический сопроцессор.

Результаты каждой проверки выводятся в виде диаграммы рядом с итогами тестирования иных аппаратных компонентов различных поколений.

Рис. 12 – Тесты AIDA64

Также доступен ряд стресс-тестов в меню «Сервис»:

  • Жесткий диск;
  • Кэш и оперативная память;
  • Графический адаптер;
  • Тест стабильности компьютера.

В последнем случае можно одновременно запустить ряд алгоритмов в любой комбинации: диски, видеокарта, ЦП, ОЗУ, FPU, кэш.

Рис. 13 – Результат

Также присутствует утилита для диагностики монитора – поможет выявить неисправные (битые) пиксели на дисплее посредством ряда алгоритмов.

AIDA64 – последователь Everest и лучшая информационная утилита для получения любых данных о компьютере. Также она позволяет проверить систему на стабильность при работе в режиме предельной нагрузки и создать отчёт фактически с любыми данными.

WoW64

Windows-on-Windows 64-bit (WoW64) — подсистема операционной системы Windows, позволяющая запускать 32-битные приложения на всех 64-битных версиях Windows.

Подсистема WoW64 не поддерживает следующие программы:

  • программы, скомпилированные для 16-разрядных операционных систем;
  • программы режима ядра, скомпилированные для 32-разрядных операционных систем.

Существуют различия WoW64 в зависимости от архитектуры процессора. Например, 64-битная версия Windows разработанная для процессора Intel Itanium 2 использует WoW64 для эмуляции x86 инструкций. Такая эмуляция весьма ресурсоемка по сравнению с WoW64 для архитектуры Intel 64, так как происходит переключение с 64-битного режима в режим совместимости, при выполнении 32-битных программ.

WoW64 на архитектуре Intel 64 (AMD64 / x64) не требует эмуляции инструкций. Здесь подсистема WoW64 эмулирует только 32-битное окружение, за счет дополнительной прослойки между 32-битным приложением и 64-битным Windows API. Где-то эта прослойка тонкая, где-то не очень. Для средней программы потери в производительности из-за наличия такой прослойки составят около 2%. Для некоторых программ это значение может быть больше. Два процента это немного, но следует учитывать, что 32-битные приложения работают немного медленнее под управлением 64-битной операционной системы Windows, чем в 32-битной среде.

Компиляция 64-битного кода не только исключает необходимость в WoW64, но и дает дополнительный прирост производительности. Это связано с архитектурными изменениями в микропроцессоре, такими как увеличение количества регистров общего назначения. Для средней программы можно ожидать в пределах 5-15% прироста производительности от простой перекомпиляции.

Из-за наличия прослойки WoW64 32-битные программы работают менее эффективно в 64-битной среде, чем в 32-битной. Но все-таки, простые 32-битные приложения могут получить одно преимущество от их запуска в 64-битной среде. Вы, наверное, знаете, что программа, собранная с ключом /LARGEADDRESSAWARE:YES может выделять до 3-х гигабайт памяти, если 32-битная операционная система Windows запущена с ключом /3gb. Так вот, эта же 32-битная программа, запущенная на 64-битной системе, может выделить почти 4 GB памяти (на практике около 3.5 GB).

Подсистема WoW64 изолирует 32-разрядные программы от 64-разрядных путем перенаправления обращений к файлам и реестру. Это предотвращает случайный доступ 32-битных программ к данным 64-битных приложений. Например, 32-битное приложение, которое запускает файл DLL из каталога %systemroot%\System32, может случайно обратиться к 64-разрядному файлу DLL, который несовместим с 32-битной программой. Во избежание этого подсистема WoW64 перенаправляет доступ из папки %systemroot%\System32 в папку %systemroot%\SysWOW64. Это перенаправление позволяет предотвратить ошибки совместимости, поскольку при этом требуется файл DLL, созданный специально для работы с 32-разрядными приложениями.

Синтаксис

Синтаксис языка ассемблера определяется системой команд конкретного процессора.

Набор команд

  • Команды пересылки данных (mov, lea и т. д.)
  • Арифметичекие команды (add, sub, imul и т. д.)
  • Логические и побитовые операции (or, and, xor, shr и т. д.)
  • Команды управления ходом выполнения программы (jmp, loop, ret и т. д.)
  • cbne — перейти, если не равно
  • dbnz — декрементировать, и если результат ненулевой, то перейти
  • cfsneq — сравнить, и если не равно, пропустить следующую команду

Инструкции

Типичный формат записи команд:
<source lang=»asm»> опкод </source>

  • Если изначально существовало два стандарта записи мнемоник (система команд была наследована от процессора другого производителя).

Например, процессор наследовал систему команд , расширил ее и поменял мнемоники (и обозначения регистров) на свой лад. Процессоры наследовали систему команд Z80, несколько её урезав. Вместе с тем, Motorola официально вернулась к мнемоникам Intel. И в данный момент половина ассемблеров для Fireball работает с интеловскими мнемониками, а половина с мнемониками Zilog.

Директивы

Программа на ассемблере может содержать директивы: инструкции, не переводящиеся непосредственно в машинные команды, а управляющие работой компилятора. Набор и синтаксис их значительно разнятся и зависят не от аппаратной платформы, а от используемого транслятора (порождая диалекты языков в пределах одного семейства архитектур). В качестве «джентельменского набора» директив можно выделить следующие:

  • определение данных (констант и переменных)
  • управление организацией программы в памяти и параметрами выходного файла
  • задание режима работы компилятора

Разработка 64-битных приложений

Урок 01. Что такое 64-битные системы.

Урок 02. Поддержка 32-битных приложений.

Урок 03. Перенос кода на 64-битные системы. За и против.

Урок 04. Создание 64-битной конфигурации.

Урок 05. Сборка 64-битного приложения.

Урок 06. Ошибки в 64-битном коде.

Урок 07. Проблемы выявления 64-битных ошибок.

Урок 08. Статический анализ для выявления 64-битных ошибок.

Урок 09. Паттерн 01. Магические числа.

Урок 10. Паттерн 02. Функции с переменным количеством аргументов.

Урок 11. Паттерн 03. Операции сдвига.

Урок 12. Паттерн 04. Виртуальные функции.

Урок 13. Паттерн 05. Адресная арифметика.

Урок 14. Паттерн 06. Изменение типа массива.

Урок 15. Паттерн 07. Упаковка указателей.

Урок 16. Паттерн 08. Memsize-типы в объединениях.

Урок 17. Паттерн 09. Смешанная арифметика.

Урок 18. Паттерн 10. Хранение в double целочисленных значений.

Урок 19. Паттерн 11. Сериализация и обмен данными.

Урок 20. Паттерн 12. Исключения.

Урок 21. Паттерн 13. Выравнивание данных.

Урок 22. Паттерн 14. Перегруженные функции.

Урок 23. Паттерн 15. Рост размеров структур.

Урок 24. Фантомные ошибки.

Урок 25. Практическое знакомство с паттернами 64-битных ошибок.

Урок 26. Оптимизация 64-битных программ.

Урок 27. Особенности создания инсталляторов для 64-битного окружения.

Урок 28. Оценка стоимости процесса 64-битной миграции Си/Си++ приложений.

Авторами курса являются сотрудники компании «СиПроВер», занимающейся разработкой статического анализатора кода Viva64 для выявления ошибок в 64-битных программа. На сайте компании можно найти множество других ресурсов, посвященных разработке новых 64-битных приложений и миграции 32-битных приложений на 64-битные системы. В качестве примера можно привести раздел с обзорами статей по тематике связанной с 64-битнми технологиями.

Насколько доходно уметь программировать на ассемблере?

Ес­ли заг­лянешь на HH.ru, то, ско­рее все­го, не най­дешь ни одной вакан­сии, у которой в заголов­ке написа­но сло­во «ассем­блер». Но вре­мя от вре­мени какая‑нибудь кон­тора лихора­доч­но ищет мага‑вол­шебни­ка, который зна­ет нут­ро компь­юте­ра нас­толь­ко глу­боко, что может пол­ностью под­чинить опе­раци­онную сис­тему сво­ей воле. Мага‑вол­шебни­ка, который уме­ет (1) латать сис­тему, не имея на руках исходно­го кода, (2) перех­ватывать потоки дан­ных на лету и вме­шивать­ся в них.

Не­кото­рая часть этой глу­бокой магии — а сей­час пот­ребность в такой магии ста­новит­ся все более ред­кой — может быть воп­лощена толь­ко на язы­ке очень низ­кого уров­ня.

Я слы­шал о кон­торе, которая ищет челове­ка на раз­работ­ку новой плат­формы для высоко­час­тотно­го трей­дин­га. Там идея в том, что если ты получа­ешь информа­цию о котиров­ках быс­трее сво­их кон­курен­тов и при­нима­ешь решение быс­трее их, то будешь грес­ти бас­нослов­ные сум­мы.

«Ког­да ты получа­ешь котиров­ки, про­ходя через весь стек TCP/IP, это слиш­ком мед­ленно», — говорят пар­ни из этой фир­мы. Поэто­му у них есть при­моч­ка, которая перех­ватыва­ет тра­фик на уров­не Ethernet, пря­мо внут­ри сетевой кар­ты, куда залита кас­томизи­рован­ная про­шив­ка.

Но эти ребята пош­ли еще даль­ше. Они собира­ются раз­работать девайс для филь­тра­ции тра­фика Ethernet — на ПЛИС. Зачем? Что­бы ловить котиров­ки на аппа­рат­ном уров­не и тем самым эко­номить дра­гоцен­ные мик­росекун­ды трей­дин­гового вре­мени и в ито­ге получать неболь­шое, очень неболь­шое пре­иму­щес­тво перед кон­курен­тами. Язык С им не подошел. Им даже ассем­блер не подошел. Так что эти пар­ни выцара­пыва­ют прог­рамму пря­мо на крем­нии!

Почему это сложно?

Чтобы кодить на ассемблере, нужно питаться железными бобами, иметь гранитное терпение, а еще:

  • иметь полное понимание архитектуры процессора;
  • хорошо разбираться в железе и особенностях работы процессорного взаимодействия;
  • знать на зубок все команды, относящиеся именно к каждому конкретному типу процессора;
  • побайтовый режим работы с данными (строки и массивы — это не про ассемблер, одинокие буквы — вот что вас ждет);
  • иметь четкое понимание реализации нужной функциональности в ограниченных условиях.

А еще забудьте про привычные готовые библиотеки кода и наличие адекватных читабельных конструкций.

Когда и как был создан ассемблер?

Это произошло ещё в сороковых годах прошлого века. Ассемблер был создан для первых ЭВМ на электронных лампах, программы для которых писали на машинном языке. А так как памяти у компьютеров было мало, то команды вводили, переключая тумблеры и нажимая кнопки. Даже несложные вычисления занимали много времени.

Проблему решили, когда ЭВМ научились хранить программы в памяти. Уже в 1950 году была разработана первая программа-транслятор, которая переводила в машинный код программы, написанные на понятном человеку языке. Эту программу назвали программой-сборщиком, а язык — языком ассемблера (от англ. assembler — сборщик).

Почему это сложно

Для того, чтобы писать программы на Ассемблере, нужно очень любить кремний:

  • понимать архитектуру процессора;
  • знать устройство железа, которое работает с этим процессором;
  • знать все команды, которые относятся именно к этому типу процессоров;
  • уметь работать с данными в побайтовом режиме (забудьте о строках и массивах, ведь ваш максимум — это одна буква);
  • понимать, как в ограниченных условиях реализовать нужную функциональность.

Теперь добавьте к этому отсутствие большинства привычных библиотек для работы с чем угодно, сложность чтения текста программы, медленную скорость разработки — и вы получите полное представление о программировании на Ассемблере.

Команды передачи данных

Группа команд передачи данных предназначена для организации обмена между регистрами стека, вершиной стека сопроцессора и ячейками оперативной памяти. Команды этой группы имеют такое же значение для процесса программирования сопроцессора, как и команда mov основного процессора. С помощью этих команд осуществляются все перемещения значений операндов в сопроцессор и из него. По этой причине для каждого из трех типов данных, с которыми может работать сопроцессор, существует своя подгруппа команд передачи данных. Собственно на этом уровне все его умения по работе с различными форматами данных и заканчиваются. Главной функцией всех команд загрузки данных в сопроцессор является преобразование их к единому представлению в виде вещественного числа расширенного формата. Это же касается и обратной операции — сохранения в памяти данных из сопроцессора.
Команды передачи данных можно разделить на следующие группы:

  • команды передачи данных в вещественном формате;
  • команды передачи данных в целочисленном формате;
  • команды передачи данных в двоично-десятичном формате.

Основными командами передачи данных являются

  • команда FLD (загрузка данных в вершину стека сопроцессора);
  • команда FST (сохранение вершины стека сопроцессора в память)

и их модификации.Команды передачи данных вещественного типа
Используются в случае если операнд, применяемый в команде, имеет вещественный тип (4, 8 или 10-байтный).

Команда Операнды Пояснение Описание
FLD src TOPSWR-=1; ST(0)=src; Загрузка операнда в вершину стека
FST dst dst=ST(0); Сохранение вершины стека в память
FSTP dst dst=ST(0); TOPSWR+=1; Сохранение вершины стека в память с выталкиванием
FXCH ST(i) ST(0) ST(i) Обмен значений ST(0) и ST(i)

Команды передачи данных целого типа Используются в случае если операнд, применяемый в команде, имеет целый тип (1, 2, 4 или 8-байтный).

Команда Операнды Пояснение Описание
FILD src TOPSWR-=1; ST(0)=src; Загрузка операнда в вершину стека
FIST dst dst=ST(0); Сохранение вершины стека в память
FISTP dst dst=ST(0); TOPSWR+=1; Сохранение вершины стека в память с выталкиванием

Команды передачи данных двоично-десятичного типа Используются в случае если операнд, применяемый в команде, представлен в двоично-десятичной системе счисления (1, 2, 4 или 8-байтный).

Команда Операнды Пояснение Описание
FBLD src TOPSWR-=1; ST(0)=src; Загрузка операнда в вершину стека
FBSTP dst dst=ST(0); TOPSWR+=1; Сохранение вершины стека в память с выталкиванием

Команды загрузки констант Команды загрузки констант не имеют операндов и загружают соответствующее константное значение в вершину стека сопроцессора.

Команда Пояснение Описание
FLDZ TOPSWR-=1; ST(0)=0; Загрузка 0
FLD1 TOPSWR-=1; ST(0)=1; Загрузка 1
FLDPI TOPSWR-=1; ST(0)=3.1415926535; Загрузка π
FLDL2T TOPSWR-=1; ST(0)=3.3219280948; Загрузка log210
FLDL2E TOPSWR-=1; ST(0)=1.4426950408; Загрузка log2e
FLDLG2 TOPSWR-=1; ST(0)=0.3010299956; Загрузка lg 2
FLDLN2 TOPSWR-=1; ST(0)=0.6931471805; Загрузка ln 2

Какие программы нельзя написать на ассемблере?

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

Ты при желании можешь написать на ассем­бле­ре даже веб‑сайт. В девянос­тые С был впол­не разум­ным выбором для этой цели. Исполь­зуя такую вещь, как CGI BIN, веб‑сер­вер мог вызывать прог­рамму, написан­ную на С. Через сайт получал зап­рос, а через отправ­лял резуль­тат в бра­узер. Ты можешь лег­ко реали­зовать тот же прин­цип на ассем­бле­ре.

Но зачем? Ты дол­жен быть мазохис­том, что­бы про­делы­вать такое. Потому что ког­да ты пишешь на ассем­бле­ре, то стал­кива­ешь­ся вот с такими проб­лемами.

  • У тебя более низ­кая про­дук­тивность, чем если бы ты работал на язы­ке высоко­го уров­ня.
  • У тво­его кода нет никакой струк­туры, поэто­му дру­гим раз­работ­чикам будет труд­но читать его.
  • Те­бе при­дет­ся писать мно­го букв. А там, где боль­ше букв, боль­ше потен­циаль­ных багов.
  • С Secure Coding здесь все очень печаль­но. На ассем­бле­ре писать так, что­бы код был безопас­ным, слож­нее все­го. На С в этом пла­не ты чувс­тву­ешь себя куда более ком­фор­тно.

Да, все мож­но написать на ассем­бле­ре. Но сегод­ня это нецеле­сооб­разно. Луч­ше пиши на С. Ско­рее все­го, будет безопас­нее, быс­трее и более лаконич­но.

От редакции

Ав­тор статьи — боль­шой пок­лонник С и нас­тоятель­но рекомен­дует этот язык. Мы не будем лишать его такой воз­можнос­ти. С — отличная шту­ка и помога­ет как осво­ить основные кон­цепции прог­рамми­рова­ния, так и про­чувс­тво­вать прин­ципы работы компь­юте­ра. Одна­ко при выборе язы­ка для изу­чения ты можешь руководс­тво­вать­ся самыми раз­ными сооб­ражени­ями. Нап­ример:

  • На­до учить Python или Lua, что­бы момен­таль­но получать резуль­таты. Это мотиви­рует!
  • На­до учить Scheme или Haskell из тех же сооб­ражений, что в шко­ле учат алгебру, а не, к при­меру, авто­меха­нику.
  • На­до учить Go для того же, для чего C, но в 2020 году.
  • На­до учить JavaScript и React.js, что­бы как мож­но быс­трее най­ти работу.
  • На­до учить Java, что­бы мак­симизи­ровать зарабо­ток.
  • На­до учить Swift, потому что почему нет?
  • На­до учить HolyC, что­бы сла­вить Гос­пода.
  • На­до учить Perl во имя Сатаны.

И так далее. Ответ на воп­рос о том, с какого язы­ка начать, зависит от мно­гих фак­торов, и выбор — дело инди­виду­аль­ное.

Ко­неч­но, ког­да ты зна­ешь ассем­блер, у тебя будут зна­читель­ные пре­иму­щес­тва перед теми прог­раммис­тами, которые его не зна­ют. Но преж­де чем озна­комить­ся с эти­ми пре­иму­щес­тва­ми, запом­ни одну прос­тую вещь: хо­рошие прог­раммис­ты зна­ют ассем­блер, но поч­ти никог­да не пишут на нем.

Как мыслит процессор

Чтобы понять, как работает Ассемблер и почему он работает именно так, нам нужно немного разобраться с внутренним устройством процессора.

Кроме того, что процессор умеет выполнять математические операции, ему нужно где-то хранить промежуточные данные и служебную информацию. Для этого в самом процессоре есть специальные ячейки памяти — их называют регистрами.

Регистры бывают разного вида и назначения: одни служат, чтобы хранить информацию; другие сообщают о состоянии процессора; третьи используются как навигаторы, чтобы процессор знал, куда идти дальше, и так далее. Подробнее — в расхлопе ↓

Общего назначения. Это 8 регистров, каждый из которых может хранить всего 4 байта информации. Такой регистр можно разделить на 2 или 4 части и работать с ними как с отдельными ячейками.

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

Регистр флагов. Флаг — какое-то свойство процессора. Например, если установлен флаг переполнения, значит процессор получил в итоге такое число, которое не помещается в нужную ячейку памяти. Он туда кладёт то, что помещается, и ставит в этот флаг цифру 1. Она — сигнал программисту, что что-то пошло не так.

Флагов в процессоре много, какие-то можно менять вручную, и они будут влиять на вычисления, а какие-то можно просто смотреть и делать выводы. Флаги — как сигнальные лампы на панели приборов в самолёте. Они что-то означают, но только самолёт и пилот знают, что именно.

Сегментные регистры. Нужны были для того, чтобы работать с оперативной памятью и получать доступ к любой ячейке. Сейчас такие регистры имеют по 32 бита, и этого достаточно, чтобы получить 4 гигабайта оперативки. Для программы на Ассемблере этого обычно хватает.

Так вот: всё, с чем работает Ассемблер, — это команды процессора, переменные и регистры.

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

Архитектура Intel 64 (AMD64)

Рассматриваемая архитектура Intel 64 простое, но в то же время мощное обратно совместимое расширение устаревшей промышленной архитектуры x86. Она добавляет 64-битное адресное пространство и расширяет регистровые ресурсы для поддержки большей производительности перекомпилированных 64-битных программ. Архитектура обеспечивает поддержку устаревшего 16-битного и 32-битного кода приложений и операционных систем без их модификации или перекомпиляции.

Отличительной особенностью Intel 64 является поддержка шестнадцати 64-битных регистров общего назначения (в x86-32 имелось восемь 32-битных регистров). Поддерживаются 64-битные арифметические и логические операции над целыми числами. Поддерживаются 64-битные виртуальные адреса. Для адресации новых регистров для команд введены «префиксы расширения регистра», для которых был выбран диапазон кодов 40h-4Fh, использующихся для команд INC <регистр> и DEC <регистр> в 32- и 16-битных режимах. Команды INC и DEC в 64-битном режиме должны кодироваться в более общей, двухбайтовой форме.

Регистры:

16 целочисленных 64-битных регистра общего назначения (RAX, RBX, RCX, RDX, RBP, RSI, RDI, RSP, R8 — R15),

8 80-битных регистров с плавающей точкой (ST0 — ST7),

8 64-битных регистров Multimedia Extensions (MM0 — MM7, имеют общее пространство с регистрами ST0 — ST7),

16 128-битных регистров SSE (XMM0 — XMM15),

64-битный указатель RIP и 64-битный регистр флагов RFLAGS.

Необходимость 64-битной архитектуры определяется приложениями, которым необходимо большое адресное пространство. В первую очередь это высокопроизводительные серверы, системы управления базами данных, САПР и, конечно, игры. Такие приложения получат существенные преимущества от 64-битного адресного пространства и увеличения количества регистров. Малое количество регистров, доступное в устаревшей x86 архитектуре, ограничивает производительность в вычислительных задачах. Увеличенное количество регистров обеспечивает достаточную производительность для многих приложений.

Подчеркнем основные достоинства архитектуры x86-64:

  • 64-битное адресное пространство;
  • расширенный набор регистров;
  • привычный для разработчиков набор команд;
  • возможность запуска старых 32-битных приложений в 64-битной операционной системе;
  • возможность использования 32-битных операционных систем.
Рейтинг
( Пока оценок нет )
Editor
Editor/ автор статьи

Давно интересуюсь темой. Мне нравится писать о том, в чём разбираюсь.

Понравилась статья? Поделиться с друзьями:
Работатека
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: