04. Структура программы. Сегменты. - mRrvz/bmstu-asm GitHub Wiki

Структура программы

Любая программа состоит из сегментов

/// ! Виды сегментов:

  • Сегмент кода

  • Сегмент данных

  • Сегмент стека

/// ! Описание сегмента в исходном коде:

имя SEGMENT READONLY выравнивание тип разряд 'класс'

имя ENDS


Структура программы на ассемблере (Зубков С. В., Assembler для DOS, Windows, …, глава 3):

  • Модули (файлы исходного кода)
  • Сегменты (описание блоков памяти)
  • Составляющие программного кода:
    • команды процессора
    • инструкции описания структуры, выделения памяти, макроопределения
  • Формат строки программы:
    • метка команда/директива операнды ; комментарий

Директива SEGMENT

Каждая программа, написанная на любом языке программирования, состоит из одного или нескольких сегментов. Обычно область памяти, в которой находятся команды, называют сегментом кода, область памяти с данными - сегментом данных и область памяти, отведённую под стек, - сегментом стека.

Выравнивание:

  • BYTE

  • WORD

  • DWORD

  • PARA (по умолчанию)

  • PAGE

Тип:

  • PUBLIC - заставляет компоновщик соединить все сегменты с одинаковым именем. Новый объединенный сегмент будет целым и непрерывным. Все адреса (смещения) объектов, а это могут быть, в зависимости от типа сегмента, команды или данные, будут вычисляться относительно начала этого нового сегмента;

  • STACK - определение сегмента стека. Заставляет компоновщик соединить все одноименные сегменты и вычислять адреса в этих сегментах относительно регистра SS. Комбинированный тип STACK (стек) аналогичен комбинированному типу PUBLIC, за исключением того, что регистр SS является стандартным сегментным регистром для сегментов стека. Регистр SP устанавливается на конец объединенного сегмента стека. Если не указано ни одного сегмента стека, компоновщик выдаст предупреждение, что стековый сегмент не найден. Если сегмент стека создан, а комбинированный тип STACK не используется, программист должен явно загрузить в регистр SS адрес сегмента (подобно тому, как это делается для регистра DS);

  • COMMON - располагает все сегменты с одним и тем же именем по одному адресу. Все сегменты с данным именем будут перекрываться и совместно использовать память. Размер полученного в результате сегмента будет равен размеру самого большого сегмента;

  • AT - располагает сегмент по абсолютному адресу параграфа (параграф — объем памяти, кратный 16, поэтому последняя шестнадцатеричная цифра адреса параграфа равна 0). Абсолютный адрес параграфа задается выражением хххx. Компоновщик располагает сегмент по заданному адресу памяти (это можно использовать, например, для доступа к видеопамяти или области ПЗУ), учитывая атрибут комбинирования. Физически это означает, что сегмент при загрузке в память будет расположен, начиная с этого абсолютного адреса параграфа, но для доступа к нему в соответствующий сегментный регистр должно быть загружено заданное в атрибуте значение. Все метки и адреса в определенном таким образом сегменте отсчитываются относительно заданного абсолютного адреса;

  • PRIVATE (по умолчанию) - сегмент не будет объединяться с другими сегментами с тем же именем вне данного модуля.

Класс:

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

Директива ASSUME

ASSUME регистр : имя сегмента

  • Не является командой
  • Нужна для контроля компилятором правильности обращения к переменным

Модель памяти

.model модель, язык, модификатор

  • TINY - один сегмент на всё
  • SMALL - код в одном сегменте, данные и стек - в другом
  • COMPACT - допустимо несколько сегментов данных
  • MEDIUM - код в нескольких сегментах, данные - в одном
  • LARGE, HUGE
  • Язык - C, PASCAL, BASIC, SYSCALL, STDCALL. Для связывания с ЯВУ и вызова подпрограмм.
  • Модификатор - NEARSTACK/FARSTACK
  • Определение модели позволяет использовать сокращённые формы директив определения сегментов.

Конец программы и точка входа

...

END start

  • start - имя метки, объявленной в сегменте кода и указывающее на команду, с которой начнётся исполнение программы.
  • Если в программе несколько модулей, только один может содержать начальный адрес.