Всем привет!
Сегодня вы узнаете:
1. Что такое Assembler?
2. История Assembler-а
3. Какие компиляторы этого языка существуют?
4. Почему этот язык - это не просто очередной странный язык?
5. Примеры программирования на Assembler для Linux систем.
"Глава 1 - Что такое Assembler?"
Assembler - это старейший язык программирования, идея которого была создана в 1949. Это очень долгая, но интересная история.
Создателем языка программирования как идеи был Дэвид Уилер (David Wheeler)
Как это было: В 1949 году, работая над легендарным компьютером EDSAC в Кембриджском университете, Уилер разработал систему под названием "Initial Orders" (Начальные команды).
В чем суть: До него программистам приходилось вручную вводить двоичный код (бесконечные нули и единицы) или задавать инструкции с помощью переключателей на передней панели компьютера. Уилер придумал, как заменить эти сложные числовые коды на короткие, понятные человеку слова (мнемоники), например, ADD вместо кода операции сложения.
Итог: Именно эта работа сделала Дэвида Уилера создателем первого в мире языка ассемблера. Позже, в 1985 году, Институт инженеров электротехники и электроники (IEEE) вручил ему медаль "За изобретение языка ассемблера".
Интересный факт: иногда в этой связи упоминают Кэтлин Бут (Kathleen Booth). Она работала параллельно и тоже внесла большой вклад в развитие языков программирования низкого уровня, но именно система Уилера на EDSAC считается первым полноценным ассемблером.
А вот создателем данного языка программирования как программа была создана американским инженером Натаном Рочестером (Nathan Rochester).
Где и когда: В 1950-1951 годах Рочестер работал в IBM над созданием первого массового компьютера IBM 701.
В чем суть: Ему нужен был инструмент, который бы позволял программистам писать код для новой машины более эффективно. Рочестер написал первый в мире символический ассемблер — программу, которая автоматически преобразовывала понятные человеку команды (вроде тех, что придумал Уилер) в двоичные инструкции, понятные процессору.
Итог: Натан Рочестер создал первую практическую программу-ассемблер, которая использовалась для реальной коммерческой разработки.
Именно так и появился на свет язык программирования Assembler. Но вы не думайте, что это один язык программирования. Компиляторов этого языка было создано десятки, если не сотни, и каждый был абсолютно разный. Один компилятор подходил только для Windows систем x86 архитектуры, другой для Linux ARM, а третий мог вообще работать только на процессорах Эльбрус старого поколения. Так что, если вы хотите выучить синтаксис одного компилятора, то знайте, что если вы установите другой компилятор, то там нужно учить другой синтаксис.
Кстати, важная информация: то, что обычно называют "компилятором Assembler" - это транслятор. Компиляторы работают с кодом высокого уровня, а вот тут самый низкий уровень, почти машинный код. Так что, правильнее говорить не "компилятор Assembler-а", а "транслятор Assembler-а"
Стоит сказать про самые популярные трансляторы на сегодня:
1. NASM (Netwide Assembler) — кроссплатформенный, удобный для Linux и Windows (который я использовал);
2. MASM (Microsoft Macro Assembler) — только для Windows, идёт в комплекте с Visual Studio;
3. FASM (Flat Assembler) — один из самых быстрых, умеет компилировать сам себя;
4. GAS (GNU Assembler) — встроен в GCC, использует AT&T синтаксис;
5. TASM (Turbo Assembler) — старый, от Borland, для DOS и ранних Windows;
"Глава 2 - Почему язык Assembler - это не просто язык программирования?"
Как я уже сказал выше, Assembler - это первый язык программирования, который упрощал разработку программ. Но на основе Assembler сейчас стоит весь мир. Все системы, включая Linux, Windows, Mac OS, FreeBSD и другие основаны на Assembler. Без Assembler у нас не было бы мощных и компактных компьютеров, а до сих пор стояли бы огромные шкафы, которые обрабатывали 1 уравнение не одну миллисекунду, а несколько часов.
"Глава 3 - Примеры кода на Assembler"
А вот тут сложно. Так как я сейчас работаю на Linux, я не очень знаю, как дела обстоят на Windows, по этому в какой-то степени я буду опираться на информацию из интернета.
Для того, что бы нам программировать на языке Assembler-а, нам нужно установить компилятор. Я бы рекомендовал NASM, так как он (как по мне) удобен как для Linux, так и для Windows.
Как установить для Linux?
Нужно ввести команду: "sudo [ваш пакетный менеджер] install nasm gcc"
У меня (Debian/Ubuntu) это через команду: "sudo apt install nasm gcc"
Как мы видим, nasm и gcc у меня уже установлены, а вот вам придётся его установить для работы с языком.
После этого вы должны создать новый файл через "touch" (пример: "touch main.asm"). После этого нужно редактировать файл, это команда "nano main.asm"
Как установить для Windows?
Для этого нужно установить GCC + NASM, а мне это не позволяет сделать Debian 13 с его Wine (так как он у меня не работает), по этому я буду опираться на Linux.
Теперь нужно записать в файл код, по этому приступим.
Важное замечание про синтаксис: В мире Assembler-а есть два основных "диалекта" - Intel (который я показываю) и AT&T. В Intel синтаксисе сначала пишется регистр назначения, потом источник: "mov rax, 1". В AT&T — наоборот: "mov $1, %rax". AT&T используется по умолчанию в GCC, а Intel — в NASM. Я выбрал NASM и Intel, потому что он понятнее для начинающих.
Код (для Linux!):
```ASM
global main
section .text
main:
; write(1, message, 13)
; Номер системного вызова 'write' — 1
mov rax, 1 ; Код syscall (write)
mov rdi, 1 ; Дескриптор файла: stdout (1)
mov rsi, HL ; Указатель на строку
mov rdx, 13 ; Длина строки (байт)
syscall ; Вызов ядра
; exit(0)
; Номер системного вызова 'exit' — 60
mov rax, 60 ; Код syscall (exit)
xor rdi, rdi ; Код возврата: 0
syscall
section .data
HL: db "Hello, world!", 10 ; 10 (0xA) — символ новой строки
```
Вы вставляете данный код в файл, после этого нажимаете комбинацию клавиш CTRL + S, а после CTLR + X.
Теперь нужно скомпилировать. Для любых Linux систем нужно ввести в терминал: "nasm -f elf64 main.asm -o main.o", дальше мы должны ввести команду "gcc -no-pie main.o -o main", а после запустить программу через "./main".
Альтернатива (более сложная но более сжатая): выполнить всё в одной команде "nasm -f elf64 main.asm -o main.o && gcc -no-pie main.o main && ./main".
Готово! Теперь в терминале есть текст "Hello, world!".
Вы можете всё сделать в одну команду (записать весь код в файл .sh и выполнить его), но это уже отдельная статья.
Как отлаживать такие программы? Простой способ — использовать "strace ./main" (sudo apt install strace), чтобы увидеть, какие системные вызовы реально выполняет ваша программа. Для пошаговой отладки подойдёт "gdb" (sudo apt install gdb), но это уже тема для отдельной статьи.
"Глава 4 - Что в итоге?"
Вы узнали за эту статью:
1. Что такое Assembler;
2. Кто был создателем идеи и создателем транслятора Assembler-а;
3. Почему Assembler - это не просто язык программирования;
4. Почему Assembler - это не один язык, а несколько десятков трансляторов;
5. Как программировать на Assembler (НО ЭТО ТОЛЬКО ДЛЯ Linux Я РАССКАЗАЛ!).
Следующая статья будет про язык программирования C, и выйдет она в следующее воскресенье (а именно 3 мая) в 00:00 по МСК.
Пишите в комментариях: Как вы относитесь к языку Assembler? Хотели ли бы вы от меня увидеть программирование на Assembler для голого железа? Спорим, вы такой информации которую я вам сейчас рассказал, никогда не видели?
Так же, если вы хотите мне помочь с тем, как же всё таки программировать на языке Assembler-а для Windows, то вы мне можете помочь написав эту информацию в комментариях, я буду рад просто прочитать комментарии и ответить на них!
С вами был Сам Самыч, всем пока!