Ассемблер.. Вот, как о нем отзывается xakep.ru:

В последнее время ассемблер незаслуженно находится в тени других языков.
Обусловлено это глобальной коммерциализацией, направленной на то, чтобы
в максимально короткие сроки получить как можно большую прибыль от
продукта. Иными словами, массовость взяла верх над элитарностью. А
ассемблер, по моему мнению, ближе к последнему. Гораздо выгоднее в
сравнительно небольшие сроки поднатаскать ученика в таких, например,
языках, как С++, С#, PHP, Java, JavaScript, Python, чтобы он был более-менее
способен создавать ширпотребный софт, не задаваясь вопросами, зачем и
почему он так делает, чем выпустить хорошего специалиста по ассемблеру.
Примером тому служит обширнейший рынок всевозможных курсов по
программированию на любом языке, за исключением ассемблера. Та же
тенденция прослеживается как в преподавании в вузах, так и в учебной
литературе. В обоих случаях вплоть до сегодняшнего дня большая часть
материала базируется на ранних процессорах серии 8086, на так
называемом «реальном» 16-битном режиме работы, операционной среде
MS-DOS! Возможно, что одна из причин в том, что, с одной стороны,
с появлением компьютеров IBM PC преподавателям пришлось перейти
именно на эту платформу из-за недоступности других. А с другой
стороны, по мере развития линейки 80х86 возможность запуска программ
в режиме DOS сохранялась, что позволяло сэкономить деньги на
приобретение новых учебных компьютеров и составление учебников для
изучения архитектуры новых процессоров. Однако сейчас такой выбор
платформы для изучения совершенно неприемлем. MS-DOS как среды
выполнения программ безнадежно устарела уже к середине девяносты
годов, а с переходом к 32-битным процессорам, начиная с процессора
80386, сама система команд стала намного более логичной. Так что
бессмысленно тратить время на изучение и объяснение странностей
архитектуры реального режима, которые заведомо никогда уже не
появятся ни на одном процессоре.

Что касается выбора операционной среды для изучения ассемблера, то,
если говорить о 32-битной системе команд, выбор сравнительно невелик.
Это либо операционные системы Windows, либо представители семейства UNIX.

Также следует сказать несколько слов о том, какой именно ассемблер
выбрать для той или другой операционной среды. Как известно, для работы
с процессорами х86 используются два типа синтаксиса ассемблера — это
синтаксис AT&T и синтаксис Intel. Эти синтаксисы представляют одни и те же
команды совершенно по-разному. Например, команда
в синтаксисе Intel выглядит так:

mov eax,ebx

В синтаксисе же AT&T уже будет иной вид:

movl %eax,%ebx

В среде ОС UNIX более популярен синтаксис типа AT&T, однако учебных
пособий по нему нет, он описывается исключительно в справочной и
технической литературе. Поэтому логично выбрать ассемблер на основе
синтаксиса Intel. Для UNIX-систем есть два основных ассемблера — это
NASM (Netwide Assembler) и FASM (Flat Assembler). Для линейки Windows
популярностью пользуются FASM и MASM (Macro Assembler) от фирмы
Microsoft, и также существовал еще TASM (Turbo Assembler) фирмы Borland,
которая уже довольно давно отказалась от поддержки собственного детища.

Давайте перейдем к самому языку для понимания сущности асма.

Кстати, скачать fasm можно по ссылке: https://flatassembler.net/download.php


напишем "ОС", которая напишет на экран "В":

org 7C00h

mov al, "B"
mov ah, 0Eh
int 10h

cli
hlt
jmp $-2

times 510-$+$$ db 00h
dw 0AA55h

Давайте разберем данный код.

org 07C00h

Подробно поговорим об этом позже, сейчас просто запомните,
что это нужно для такой "ОС" в начале кода.

mov al, "B"

Положим в регистр АL букву В, храниться она, само собой,
будет как число.

mov ah, 0Eh

Положим в регистр АH число 14, это номер команды.

int 10h

возбудим прерывание БИОСа. это прерывание(№10)
работает с экраном и называется "Видеосервис БИОС"

прерывание №10, с командой №14 выводит букву из АL
на экран после последней написанной на экран буквы
и возвращает управление.

cli

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

hlt

Говорим процессору зависнуть.

jmp $-2

Говорим процессору прыгнуть в строку где написано cli,
чтобы снова зависнуть. Требуется, если процессор
каким-то чудом развиснет.

times 510-$+$$ db 00h

Поговорим об этом позже. Запомните, что эта и следующая
строка требуются для такого рода "ОС".

Можете попробовать поиграть с кодом и попробовать
написать "Hello, world!". У вас все получится!

Пришло время серьезно погрузиться
в устройство процессора.

Есть исполнительный блок,
который выполняет ваши команды.

также есть регистры, ячейки
сверхбыстрой памяти.

у процессоров 80х86 есть
4 основных 16-битных регистра:
- ax
- bx
- cx
-
Это регистры общего назначения.
каждый из них делится на пары
верхний:нижний регистры в
2 раза меньшей емкости.
основные емкости:
64bit - четверное слово - dq
32bit - двойное слово - dd
16bit - слово - dw
8bit - символ - db

максимальные числа для
каждой емкости:
64bit - 18 446 744 073 709 551 616
32bit - 4 294 967 295
16bit - 65535
8bit - 255

и давайте договоримся называть
емкости "разрядностями", так
корректнее.

И, ах да, нужно же рассказать,
на какие регистры делятся
16битные общего назначения
ax - ah:al
bx - bh:bl
cx - ch:cl
dx - dh:dl
вот и все.
каждый из этих регистров
(ah, al, bh, bl, ...) 8-битной
разрядности, и их порядок
имеет значение.

Итак, мы знаем
как давать команду процессору.
Но что, если её нужно зациклить?
А как же условия? Тут же просто
поочередные команды!

Это главная часть курса. Итак,
начнем с простого.
Напишем библиотеку, которая печатает
на экран и воспользуемся ей.

  1. как это хранится?
    Файлы библиотек, или же
    подключаемые файлы принято
    сохранять с расширением *.inc.
    Есть ли отличия? Вообще нет.
    Просто это дань времени и
    структуризации программы.

  2. как создать функцию?

2.1
Функций как таковых в асме нету.
Зато есть метки! и прыжки.
Например, небезопасный метод
зависнуть процессор:

metka: jmp metka

Как можно заметить, метки
обозначаются как "название:".
Ну а если нужно несмотря ни на
что прыгнуть на метку, то
используется конструкция
"JMP название".

Но это не все, поверьте! Есть
и условные прыжки! Для
большинства из них нужно
предварительно вызвать
сравнивающую команду:
"CMP оператор1, оператор2".
В ассемблере есть эти типы прыжков:

  • JMP, безусловно прыгнуть

  • JE, оп1 == оп2

  • JNE, оп1 != оп2

  • JG, оп1 > оп2

  • JGE, оп1 >= оп2

  • JL, оп1 < оп2

  • JLE, оп1 <= оп2

  • JZ, активен зеро-флаг

  • JC, активен кэри-флаг Последние 2 рассмогрим позже.

И так мы можем прыгать на метки.
Удобно ведь?

2.2
А как же функции? Для подобных
нужд в ассемблере есть
директивы "CALL" и "RET".
Пример:

call func

cli 
hlt
jmp $-2

func:
do sth
ret

Этот код вызывает функцию func и
зависает. Удобно ведь?

  1. Ближе к делу

давайте разберем работу 10-го
прерывания 14-й команды.

mov ah, 0Eh
int 10h

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

file: print.inc

print:
mov ah, 0Eh ; номер команды
loopa:
lodsb ; подгружает в al символ по аддресу из si и увеличивает его на 1
test al, al ; проверяет на разность
jz loopb ; если al == 0, то zero-flag активен(установлен)
int 10h ; возбуждаем прерывание
jmp loopa ; это ведь цикл
loopb:
ret ; выход из функции

file: example.asm

use16

org 7C00h

jmp main

include "print.inc"

msg db "Hello from ColaOS!", 00h

main:

mov si, msg
call print

cli
hlt
jmp $-2

times 510-$+$$ db 00h
dw 0AA55h

Возник вопрос? Подскажу! ;)

П. Ы.: Конструктивная критика приветствуется

Комментарии (0)