Уважаемые пользователи Голос!
Сайт доступен в режиме «чтение» до сентября 2020 года. Операции с токенами Golos, Cyber можно проводить, используя альтернативные клиенты или через эксплорер Cyberway. Подробности здесь: https://golos.io/@goloscore/operacii-s-tokenami-golos-cyber-1594822432061
С уважением, команда “Голос”
GOLOS
RU
EN
UA
azrael
6 лет назад

Assembler #1 Пишем свою первую программу


Доброго времени суток, господа. Мой проект имеет главной целью помочь молодым специалистам в сфере IT. И первым делом я хотел бы начать небольшой курс для начинающих системных программистов. Сегодня мы напишем свою первую программу на Assembler(далее ASM), а именно всем известный "Hello World" для NASM x64. Работать будем ОС Linux.
Для начала представлю Вам сам код, а позже подробно расскажу как он работает:
image.png

db

В первых строках нашей программы Вы можете увидеть следущий код:
text db "Hello, World!", 10
db - расшифровывается как "define bytes". Это означает, что вы хотите выделить некоторое количество байт и занести в них какую-либо информацию.
После db мы видим строку "Hello, World!", 10. Буквы в кавычках - наш текст, как можно судя из обычных логических предположений понять. А число 10 после запятой означает знак окончания строки. Именно благодаря ему мы имеем возможность перейти на новую строку терминала и сделать наш вывод более эстетичным.
text - имя, которое мы присваиваем адресу в памяти, где будет находиться наш текст. Это можно сравнить с обычным обьявлением переменной в любом ЯП, что имеет компилятор.

Регистры

Регистры - части процессора, которые хранят данные внутри себя.
В архитектуре x86_64 регистры хранят в себе 64 бита информации
Это значит, что каждый регистр способен хранить в себе значения в таком диапазоне:

signed: -9,223,372,036,854,775,807 - 9,223,372,036,854,775,807
unsigned: 1,844674407×10¹⁹
Вот список регистров процессора на архитектуре x86_64
image.png

Системные вызовы

Системный вызов или syscall, как мы записали его в нашем коде - это событие, при котором программа обращается к ядру ОС.
Системные вызовы оличаются на разных ОС, причиной этого является то, что разные ОС могут использовать разные ядра.
Каждый системный вызов имеет ID, что асоциирован с ним. Так-же системные вызовы могут получать на вход различные аргументы или, другими словами, список входной информации. Эти самые аргументы "кладутся" в регистры процессора. Эта таблица более наглядно может объяснить сей факт:

Из этого мы видим, что в rax "кладется" ID нашего системного вызова, а в определённые регистры - аргументы, которые мы передаём.
На этой странице Вы можете найти полный список системных вызовов Linux 64bit

sys_write

Как Вы уже могли понять, зайдя на страницу, что я указал выше, мы используем системный вызов sys_write. Ему мы передаем такие аргументы:
rdi - файловый дескриптор
rsi - буфер с текстом
rdx - длина строки
В rdi мы "положили" значение 1. Это значит что мы используем stdout, стандартный системный вывод в терминал.
В rsi лежит строка, которую мы привязали к имени text
В rdi - полная длинна нашей строки.

sys_exit

В конце нашей программы мы видим ещё один системный вызов. На страничке выше, можно обнаружить, что его ID - 60, а аргумент(который только один) - код ошибки. Мы передаём туда 0, так-как это указывает на отсутсвие ошибок при исполнении и удачное завершение программы.

Секции

Все x86_64 ASM файлы имеют три секции:

  • .data
  • .bss
  • .text
    .data - содержит данные, что должны быть объявлены в процессе компиляции.
    .bss - содержит области памяти, что выделяются для будущего использования
    .text - секция, в которой содержится сам код программы.
Лейблы

Лейблы(далее Label) - точка, что указывает на определённое место в коде и позволяет компилятору ориентироваться в нём.
В нашей программе имеется один Label - _start:. Он присутсвует в каждой программе и является точкой, из которой начинается её исполнение. Без него программа не сможет работать и линкер будет выдавать ошибку. Мы дали этой метке значение global это означает, что линкеру будет доступен адрес этой метки.

Проверяем работоспособность

Теперь осталось только проверить как работает наша программа.
nasm -f elf64 hello.asm -o hello.o - компилирует программу
ld hello.o -o hello - линкует её
На выходе получаем:
image.png
Всех благодарю за внимание, надеюсь Вам понравилось. Ждите продолжения!

15
1.494 GOLOS
На Golos с August 2018
Комментарии (4)
Сортировать по:
Сначала старые