Добавить в корзинуПозвонить
Найти в Дзене
Old Programmer

Ассемблер на платформе x86-64, Linux, программирование. Статья 1 (регистры, syscall)

Все ссылки на статьи и ролики моего канала Old Programmer:
Программирование. Тематическое оглавление моего Zen-канала (Old Programmer). А вот ссылки на все мои статьи по ассемблеру. См. также Old Programmer, подводя итоги. Мои последние статьи: Что такое язык ассемблера Ну что, дошла очередь до ассемблера. Сразу скажу, что учиться программировать на ассемблере - долгий и тернистый путь. Те кто, программирует на языках высокого уровня будут озадачены синтаксисом и чрезмерной детальностью программного кода. Да, это не всем понравится, но поверьте - это того стоит. Я не буду придерживаться формата, принятого в учебниках: в начале изучаем регистры, потом команды процессора, потом структуру программы и интерфейс с операционной системой и только потом сами программы. Начну прямо с программ постепенно объясняя те или иные понятия (см. также мою статью). Ассемблер (assembler) - язык низкого уровня, в сущности совпадающий с машинным языком и дополненный некоторыми элементами, облегчающими пр
Оглавление

Все ссылки на статьи и ролики моего канала Old Programmer:
Программирование. Тематическое оглавление моего Zen-канала (Old Programmer). А вот ссылки на все мои статьи по ассемблеру. См. также Old Programmer, подводя итоги.

Список разделов канала Old Programmer, канала о программировании и программистах
Old Programmer27 мая 2021

Мои последние статьи:

Объектно-ориентированное программирование. Конструкторы (С++). Статья 5
Old Programmer4 августа 2020
Из записок старого программиста. Завещание старых мастеров. Ассемблер (книга)
Old Programmer3 августа 2020
Программирование на языке программирования Python. Множества. Статья 2
Old Programmer3 августа 2020
Программирование. Некоторые "фишки" языка C
Old Programmer2 августа 2020
Объектно-ориентированное программирование. Простой пример на Python. Статья 4
Old Programmer1 августа 2020

Что такое язык ассемблера

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

Ассемблер (assembler) - язык низкого уровня, в сущности совпадающий с машинным языком и дополненный некоторыми элементами, облегчающими программирование. Он жестко привязан, во-первых к процессору, к набору его команд, во-вторых, к операционной системе, к интерфейсу с ней. Поэтому следует сделать выбор. Выбор мною сделан. Будем рассматривать Intel-совместимые процессоры, и операционную систему Linux. Кроме того, следует сделать выбор самого ассемблера, так как их несколько. Я выбрал родной Linux-ассемблер GNU Assembler (GAS), где реализован синтаксис AT&T. В Linux есть команда as, которая и запускает транслятор ассемблера, но транслировать можно и с помощью команды gcc. Я об этом скажу позднее, в других постах.

Набор intel-регистров

На рисунке 1 представлен набор программных регистров 64-битового Intel-подобного процессора. Пока нас будут интересовать регистры из первого столбца. Чтобы слишком не перегружать ваш мозг, о регистрах пока все. Будем считать, что это элементы памяти процессора. Постепенно буду подкидывать вам другую информацию о них.

Рисунок 1.  Регистры процессора x86-64
Рисунок 1. Регистры процессора x86-64

Трансляция с языка ассемблер

Простейшая программа asm1.s представлена ниже. Для ее трансляции потребуется две команды:

as --64 asm1.s -o asm1.o
ld -s asm1.o -o asm1

Если as - сам ассемблер, то ld - это сборщик или редактор связей, он объединяет объектные модули.

Несколько слов о самой программе. В ней по сути нет алгоритма, точнее он линейный. Просто выводится строка, а потом осуществляется выход из программы. В программе используются три команды: mov - перемещение операнда, в данном случае в в регистр, хоr - исключающее ИЛИ, в данном случае используется для обнуления содержимого регистра, syscall - вызов системной функции (функции ядра) в 64-битных системах (вместо int $0x80, который использовался в 32-битовых операционных системах). Также я прокомментировал саму программу, так что, как я думаю, она довольно понятна. Имена с двоеточием являются метками, другими словами адресами памяти. Наконец следует пояснить выражение len = . - msg. В нем точка обозначает текущий адрес, таким образом текущий адрес минус адрес начала строки дает нам ее длину. Попробуйте откомпилировать и запустить программу. Вот вам и первая программа на ассемблере.

Замечание 1.
В программе asm1.s есть метка _start. Метки бывают внутренними и глобальными. В дальнейшем мы будем их использовать для организации переходов внутри программы. Но метка _start объявлена как globl, по умолчанию она является точкой входа в программу. В принципе можно объявить и другую точку входа. Например, в дальнейшем мы часто будем использовать точку входа с названием main. Нужно только при трансляции объектного модуля указать эту точку входа вот так

ld -s -e main asm1.o -o asm1

Замечание 2
Системный вызов осуществляется через команду syscall (см. asm1.s). При таком вызове не гарантируется сохранение двух регистров rcx и r11. Запомним это на будущее.

Пока все. Жду вас на моем канале Old Programmer. Подписывайтесь на него. И вы забыли поставить 'ЛАЙК', не так ли?

Программа asm1.s
Программа asm1.s

#программирование #программисты #assembler #ассемблер

#языки программирования