Этот учебник представляет собой краткое введение в программирование на языке ассемблера. Что делает это введение «мягким», так это то, что оно предполагает, что читатель уже знаком с программированием на C или C++. Мы используем эти предполагаемые знания для обратного моста к низкоуровневому ISA (архитектуре набора инструкций).
Мы обращаем внимание на очень острый момент:
Языка ассемблера не стоит бояться!Как уже упоминалось, если вы уже знакомы с C (или языками, произошедшими от C, такими как C++), эта книга начнется с того, что вы уже знаете.
Последующие главы более глубоко погружаются в уголки и тайники ARM V8 ISA и подходят для тех, кто хочет освоить богатый набор команд 64-битных процессоров ARM.
Да, абсолютно.
Программирование на языке ассемблера весьма тесно зависит от базовой аппаратной архитектуры. Операционная среда хоста играет огромную роль в определении того, как создаются программы на языке ассемблера. «Соглашение о вызовах» относится к тому, как вызываются функции и как передаются параметры.
Первоначально в этой книге изучались только соглашения ARM LINUX. Однако со временем мы разработали набор макросов, которые значительно упрощают написание кода для использования как в MacOS, так и в LINUX.
Эта ссылка приведет к их текущей копии, а также к документации. Также включены макросы, которые немного упрощают программирование.
В этой главе представлена дополнительная информация о программировании на языке ассемблера Apple Silicon.
Вы заметите, что мы напрямую используем среду выполнения C, а не выполняем системные вызовы ОС. Так, например, если мы хотим вызвать write()
, мы вызываем write
из ассемблера.
Эта версия write
системного вызова представляет собой функцию-оболочку, встроенную в среду выполнения C (CRT), которая обрабатывает детали нижнего уровня выполнения системного вызова. Посмотрите здесь, что на самом деле происходит внутри этих функций-оболочек.
Преимущество использования оболочек CRT заключается в том, что существуют различия между дистрибутивами и архитектурами, которые маскируются с помощью оболочек CRT. Поэтому, когда вы используете оболочки, а не прямой метод выполнения системных вызовов, ваш код будет более переносимым.
Какими бы похвальными ни были проекты ARM, соглашения ARM об именах их интеллектуальной собственности ужасны. В этой книге AARCH64 и ARM V8 рассматриваются как синонимы 64-битной архитектуры набора инструкций ARM (ISA).
Очень сложно найти документацию на сайте ARM, потому что у них так много версий , так много названий одного и того же и так много документации в целом. Это действительно может сводить с ума.
В тексте мы будем предоставлять соответствующие ссылки по мере необходимости.
Вот ссылка на главную страницу набора инструкций «а».
Получить инструменты для разработки на языке ассемблера довольно просто — возможно, они у вас уже есть. Используя apt
из терминала Linux, скажите:
sudo apt update
sudo apt install build-essential gdb
На компьютере Macintosh:
xcode-select --install
в терминал и следуйте указаниям. Обратите внимание, что gdb
заменяется на lldb
, различий которого достаточно, чтобы заставить вас плакать.
Тогда вам понадобится ваш любимый редактор. Мы сами используем vi
для быстрого редактирования и Visual Studio Code для любой тяжелой работы.
Мы используем gcc
, «компилятор» C. Также можно использовать g++
. На Mac также можно использовать clang
.
Какой в этом смысл... использовать «компилятор» для «компиляции» языка ассемблера?
Что ж, чтобы ответить на этот вопрос, нужно понимать, что слово «компилятор» относится только к одному шагу в последовательности сборки. То, о чем мы говорим как о «компиляторе», на самом деле является зонтиком, который включает в себя:
Препроцессор, который действует на любую команду препроцессора #
, например #include
. Эти команды не являются частью C или C++. Скорее это команды препроцессору.
Обратите внимание, что gcc
вызовет препроцессор C, если ваш файл языка ассемблера заканчивается на .S
- заглавную S. Он может или не может быть вызван, если ваш файл заканчивается строчной буквой s или любым другим расширением файла в зависимости от вашей системы.
Фактический компилятор, чья работа заключается в преобразовании языков высокого уровня, таких как C и C++, в язык ассемблера.
Ассемблер, превращающий язык ассемблера в машинный код, не совсем готовый к исполнению.
И, наконец, компоновщик, который объединяет потенциально множество файлов промежуточного машинного кода (называемых объектными файлами), потенциально множество библиотечных файлов (статически связанных .dll в Windows и .a файлов в Linux). Линкер — последний шаг в этой цепочке.
Вот видео, объясняющее этот процесс.
Мы используем gcc и g++ напрямую, потому что, будучи зонтиками, они автоматизируют описанные выше шаги и автоматически связываются с CRT.
Предположим, вы реализовали main()
в файле C (main.c) и хотите использовать написанный вами файл на языке ассемблера (asm.S). Это можно сделать несколькими способами.
gcc main.c asm.S
Это все, что вам нужно для минимальной сборки. Полученная программа будет записана в a.out
. Все созданные промежуточные файлы будут удалены.
gcc -c main.c
gcc -c asm.S
gcc main.o asm.o
При таком использовании файлы .o
остаются на диске. При использовании предыдущего метода файлы .o
удаляются, даже если вы их не видите.
Предположим, main()
реализована на языке ассемблера, а main.s
является автономным, тогда просто:
gcc main.S
Часто вам понадобится включить отладчик gdb
или lldb
. Сделайте это:
gcc -g main.S
Без параметра командной строки -g
ваш отладчик может работать неправильно.
Повторим: если вы хотите, чтобы gcc
запускал ваш код через препроцессор C (например, для обработки #include
), назовите файлы исходного кода ассемблера с заглавной буквы S. Итак, в Linux:
gcc main.s
Не будет проходить через препроцессор C, но
gcc main.S
воля.
Чтобы понять, что «компилятор» является зонтиком, использование gcc для «компиляции» программы приводит к вызову следующего в Ubuntu, работающей на ARM:
/usr/bin/cpp
/usr/lib/gcc/aarch64-linux-gnu/11/cc1
/usr/bin/as
/usr/lib/gcc/aarch64-linux-gnu/11/collect2 which is...
/usr/bin/ld
cpp
— это препроцессор C. Это универсальный инструмент, который может использоваться и в других языках (например, в C++).
cc1
— это настоящий компилятор.
as
и ассемблер.
ld
— компоновщик.
Вы можете понять, почему в этой книге мы по умолчанию используем команду зонтик.
Мы начнем с предоставления того, что мы называем «переходом» от C и C++ к языку ассемблера. Мы используем уже имеющиеся у вас знания для освоения новых знаний – как это круто!
Глава | Уценка | |
---|---|---|
0 | Кикстарт | Связь |
1 | Привет, мир | Связь |
2 | Если заявления | Связь |
3 | Петли | |
3а | Пока циклы | Связь |
3б | Для циклов | Связь |
3с | Реализация Продолжить | Связь |
3д | Реализация перерыва | Связь |
4 | Интерлюдии | |
4а | Регистры | Связь |
4б | Загрузка и сохранение | Связь |
4с | Подробнее о ldr | Связь |
4д | Регистр размеров | Связь |
4е | Шестнадцатеричный | Связь |
5 | switch | Связь |
6 | Функции | |
6а | Звонок и возвращение | Связь |
6б | Передача параметров | Связь |
6с | Пример вызова некоторых распространенных функций времени выполнения C | Связь |
7 | FizzBuzz — полная программа | Связь |
8 | Структуры | |
8а | Выравнивание | Связь |
8б | Определение | Связь |
8с | С использованием | Связь |
8д | Что это" | Связь |
9 | const | Связь |
Операции с плавающей запятой используют свои собственные инструкции и собственный набор регистров. Поэтому операции с плавающей запятой рассматриваются в отдельном разделе:
Глава | Уценка | |
---|---|---|
0 | Обзор главы | Связь |
1 | Что такое числа с плавающей запятой? | Связь |
2 | Регистры | Связь |
3 | Усечение и округление | Связь |
4 | Литералы | Связь |
5 | fmov | Связь |
6 | Поплавки половинной точности | Связь |
7 | NEON SIMD еще не написан | Связь |
Какой была бы книга о языке ассемблера без битовой критики?
Глава | Уценка | |
---|---|---|
1 | Битовые поля | |
1а | Без битовых полей | Связь |
1б | С битовыми полями | Связь |
1с | Обзор вновь описанных инструкций | Связь |
2 | Порядок байтов | Связь |
В этом разделе мы представляем разные материалы, включая нашу «всемирно известную лекцию» по отладке. Эту лекцию пригласили в несколько колледжей и университетов. Он предназначен для аудитории, работающей с такими языками, как C, C++ и ассемблер, но некоторые из содержащихся в нем уроков применимы ко всем языкам.
Глава | Уценка | |
---|---|---|
1 | Яблочный кремний | Связь |
2 | Конвергенция Apple и Linux | Связь |
3 | Вариадические функции | Связь |
4 | Под капотом: системные вызовы | Связь |
5 | Определение длины строковых литералов для функций C | Связь |
6 | Вызов языка ассемблера из Python | Связь |
7 | Атомарные операции | Связь |
8 | Таблицы переходов | Связь |
9 | аргв | АСМ-КОД |
10 | спин-блокировки | Связь |
- | Лекция по отладке | ППТХ |
Как указано выше, набор макросов можно найти здесь.
Вот некоторые спецификации проектов, которые бросят вызов вашему растущему мастерству. Здесь очень краткие описания, представленные в алфавитном порядке.
Возможно, прежде чем заняться этим, сначала ознакомьтесь с полностью описанной программой FIZZBUZZ.
Тогда попробуйте это как свой первый проект. С некоторыми пустыми строками и комментариями он весит 35 строк.
Проект DIRENT демонстрирует, как можно использовать сложную struct
на языке ассемблера.
Проект PI демонстрирует инструкции с плавающей запятой. Программа «бросает дротики в цель», вычисляя приблизительное значение PI, отслеживая, сколько дротиков «попали в цель» по сравнению с общим количеством «брошенных» дротиков.
В проекте SINE особое внимание уделяется математике и функциям с плавающей запятой.
Проект SNOW использует технологии эпохи 1970-х годов для анимации простой системы частиц. Этот проект демонстрирует разумный процесс проектирования, позволяющий разбить сложные проблемы на более простые части.
WALKIES представляет собой симпатичную небольшую анимацию, демонстрирующую цикл с некоторым разыменованием указателя.
Карьера Перри Киволовица в области компьютерных наук охватывает чуть менее пяти десятилетий. Он основал более 5 компаний, в основном связанных с оборудованием, обработкой изображений и визуальными эффектами (для кино и телевидения). Перри получил признание «Эмми» за свою работу над «Сбором», пилотным эпизодом «Вавилона 5». Позже он получил премию «Эмми» в области инженерных наук вместе со своими коллегами из SilhouetteFX, LLC. SilhouetteFX используется практически в каждом значимом кинофильме для ротоскопирования, рисования, отслеживания, реконструкции из 2D в 3D, композитинга и многого другого.
В 1996 году Перри получил премию Американской киноакадемии за научные и технические достижения за изобретение деформации и морфинга, управляемых формой. Эта техника отвечает за многие знаменитые эффекты в «Форресте Гампе», «Титанике» и «Звездных вратах».
Двадцать двадцать три года ознаменовали 19-й год обучения Перри информатике в колледже, десять лет в Университете штата Вашингтон в Мэдисоне и теперь 8+ в Карфагенском колледже.
Язык ассемблера — страсть Перри, работавшего над следующими ISA (в хронологическом порядке):
Унивак 1100
Корпорация цифрового оборудования PDP-11
Корпорация цифрового оборудования VAX-11
Моторола 68000
ARM, начиная с AARCH64
Эта работа посвящается моей жене Саре и сыновьям Яну и Эвану.
Перри создал библиотеку из около 200 программных проектов, подходящих для классов CS 1, CS 2, структур данных, сетей, операционных систем и компьютерной организации. Если издатель учебников по CS (или другого контента, связанного с CS) заинтересован в покупке библиотеки, свяжитесь с нами.
Также ознакомьтесь с «Get Off My L@wn», романом о зомби для программистов.
Вы правильно прочитали... элитный программист Дуг Хэндсман уезжает на пенсию в родной северный Висконсин своей жены Рут Энн. А потом, ну, случается апокалипсис. Облом.
Книга получила оценку 4,3 из 5 и более 70 отзывов. Это увлекательное чтение, которое практически ничего не стоит.