MS-DOS и TASM 2.0. Часть 17. Константы, массивы, структуры и т.д.

Константа, массив, структура в ассемблере.

Организация данных в ассемблере.

Прежде, чем переходить к рассмотрению вопроса что такое константа, массив, структура в ассемблере, поговорим о понятии абстракции.

Для упрощения написания кода необходимо преобразовать его в понятный для человека вид, желательно не в ущерб для машины. Для этого используют условности и обобщения — определённую степень абстракции. Один из простейших способов абстракции — разбивка кода и данных на части — блоки по определённым правилам и с определёнными особенностями. Затем эти блоки обзывают понятным для человека языком.

Первоначально программа дробиться на сегменты — наиболее глобальные блоки. В исходнике данной статьи вы столкнётесь с сегментами: .CODE (сегмент кода), .DATA (сегмент инициализированных данных), .DATA? (сегмент неинициализированных данных), .CONST (сегмент констант). Инициализированные данные — те, которым присвоено значение по умолчанию, не инициализированные — значение не присвоено, но память для данных выделена (реально заполнена символами «0» или «?» — в зависимости от компилятора), константы — постоянные, не изменяемые данные. Ещё один из сегментов — .STACK. Если сегменты в коде не указаны, структура программы будет создана согласно настройкам по умолчанию.

Как мы уже знаем, в программах типа .COM, с которыми мы непосредственно работаем, данные, код и стек находятся в одном и том же 16-битном сегменте (в отличие от программ типа .EXE). Не смотря на это, для демонстрации принципа «блочности» и особенностей написания исходного кода на ассемблере, мы «раздробили» исходник на условные части кода (.CODE) и данных (.DATA, .DATA?). TASM проигнорирует наше условное дробление и  ругаться не будет.

Схематичная структура кода на ассемблере.

Схематично структура исходного кода программы .COM выглядит так:

Но для удобства программиста можно написать и так:

Опустимся по линии абстракции кода ниже. Мы уже знаем и можем назвать один из блоков кода, который имеет имя, параметры и возвращаемое значение. Этот «блок» может вызываться практически неограниченное число раз, будучи написанным один раз Вы уже догадались, что это функция.

В этой статье речь пойдёт о блоках данных. Мы рассмотрим, что такое константа, массив, структура в ассемблере, а также более редко встречающиеся: перечисление, объединение, запись с битовыми полями (запись).

Беглый обзор.

Пробежимся по понятиям в ознакомительных целях, более подробно рассмотрим вопрос потом, когда перейдём к 32 битному Windows программированию.

Мы рассчитываем, что вы сами будете изучать выкладываемый код в свободное время. Пользуйтесь созданными для Вас возможностями: DOS-1.rar . TASMED насторен и готов к работе. При внесении изменения в код не забываем жать F2 для сохранения. Если при сборке кода возникает непонятная ошибка (!) — не забываем удалять ранее сгенерированные фалы (с расширениями *.OBJ, *.CODE). Они, как и проекты находятся в папке D:\WORK\Ваша_директория… и будут появляться вновь и вновь при удачной сборке программы. Удалять можно не выходя из DOS: выходим из TASMED (ALT+X), удаляем файлики (в NC — F8) и снова запускаем TASMED — откроется сразу с кодом.

Константа в ассемблере.

Мы уже знаем, что значение (конкретное число) можно присвоить переменной, предварительно определив размер этой переменной в байт, слово, двойное слово и т.д.:

  • DB — Define Bite.
  • DW — Define Word.
  • DD — Define Double Word.
  • DQ — Define Quatro Bites.
  • DT — Define Tetro Bites.

Константа — символ, синоним конкретного числа (выражения, строки), которое, в отличие от переменной нельзя изменить.

Для задания констант применяются обозначения:

  • .const — все данные будут восприниматься как константы, до момента изменения сегмента (.data, .code и т.п.).
  • = (знак равно).
  • equ (может использоваться для создания идентификатора, константного выражения, строки).

Структура в ассемблере.

Структура в ассемблере (structure) — это совокупность переменных, объединенных одним именем. Переменные называются полями и могут быть разными по размеру. Очень удобно обращаться к данным по именам полей. Структура — основа абстракции, «блочности» кода. Понятие КЛАСС в языках высокого уровня есть не что иное, как разновидность структуры. Только в качестве полей в классе кроме данных присутствуют ещё и функции. В качестве поля в структуру может входить структура (пример — в коде).

  • MY_STRUCT_1 STRUC; структура в ассемблере объявляется словом STRUC
    member_1 dw ?;
    member_2 db ?;
    MY_STRUCT_1 ENDS;

….

  • my_struct MY_STRUCT_1 <?>; структура в ассемблере, созданная на основе объявления.
  • mov my_struct.member_1 ,33h;используем конкретный экземпляр в коде.

Константы, массив и структура в ассемблере — наиболее часто используемые организованные виды данных, однако есть и другие. Если посмотреть на структуру повнимательнее, со стороны нашего подхода к программированию, как к совокупности кода и данных, то остальные виды сгруппированных данных : массив, перечисление, объединение, битовые поля — фактически являются разновидностями структуры, реализованные в целях экономии процессорного времени и объёма памяти.

Массив в ассемблере.

Массив — структура данных, хранящих значения, которые идентифицируются по индексам, начиная с нулевого индекса. Рассмотрим работу с одномерным массивом — с учётом нашего начального уровня.

  • my_mass_1 db 10 dup(8); создать байтовый массив, состоящий из 10 байт и заполнить его цифрами 8. Реально : дублировать (DUPlicate) 10 раз число 8.
  • mov my_mass_1[0],1 ; поместить в первый байт число 1 (поля массива считаются с нуля, а не с единицы).

Перечисление в ассемблере.

Перечисления (enum) представляет собой структуру, состоящую из именованных констант. Создана для удобства программирования в Си. При этом можно просто перечислять константы, компилятор будет присваивать им целые значения в порядке возрастания, начиная с нуля. Если присвоить полю конкретное значение, которое не совпадает с простой последовательностью, отсчёт следующих, не определённых полей будет происходить по алгоритму «+1».
enum eDirection
{
RIGHT, // по умолчанию = 0
LEFT, // = 1
DOWN=5, // = 5 — присвоили, если бы не присвоить, то DOWN==2 (предыдущее поле +1)
UP // = 6 (+1)
};

В ассемблере перечисление (enum) как отдельный, самостоятельный тип данных не существует. При необходимости используют структуру с целочисленными полями либо просто отдельные целочисленные константы.

  • _ENUM STRUC;В ассемблере Нет ENUM, используем STRUC
    RIGHT db ?;
    LEFT db ?;
    DOWN db ?;
    UP db ? ;
    _ENUM ENDS
  • my_enum _ENUM <0,1,2,3>

  • xor ax,ax;ax==0
  • mov ah,my_enum.LEFT

Объединения в ассемблере.

Объединение (union) —  одна и та же область памяти, используемая как разные типы данных. Естественно, в таком случае размер объединения будет равен размеру наибольшего из значений и не равна сумме длин всех запоминаемых, как в структуре. Тип данных создавался для Си, как способ экрномии памяти компьютера (сейчас — не актуально, но ранее активно использовался в написании кода, в том числе и сетевого характера, поэтому применяется и сейчас для совместимости).

  • MY_UNION union
    _word dw ?
    _byte db ?
    MY_UNION ends
  • _union MY_UNION <1234h>

После этого _union._word=1234h, а _union._byte=34h.

  • xor ax,ax;ax==0
  • mov ah,_union._byte

Записи с битовыми полями (запись).

Бит — единица данных, может содержать значение 1 или 0. Записи с битовыми полями (records) используют эту возможность.

Каждое битовое поле имеет заданную длину (в битах) и начальное значение. Размер данных типа записи равен сумме длин всех полей

Запись с битовыми полями (запись) в ассемблере.
Запись с битовыми полями (запись) — 32 бита.

Опять таки — удобно, экономит место и вычислительное время. Например, чтобы задать цвет точки в изображении (совокупность различных оттенков красного, зелёного, синего (RGB) или свойств окна в операционке Windows.

Не будем подробно разбирать тему, приведём пример кода.

  • BitMask RECORD f0:4=1,f1:4=1,f2:4=0,f3:4=0

  • xor ax,ax;ax==0
  • mov ax,BitMask;ax==257

Работающий ассемблерный код с примерами.

Ниже приведён пример кода — GBLSTRUC.COM (вставили дополнительные строки в goblin.com). Прогоните готовый исполняемый файл через дизасемблер и дебагер при желании разобраться в вопросе поглубже.

Код.

Напоминаем, что данные, код и стек в программе, типа ‘*.COM’ находятся в одном и том же 16-битном сегменте. Из-за этого ошибок компилятор не выдаёт, не смотря на то, что мы меняем параметры констант. В ‘*.EXE’ файле должно быть по-другому — там код, данные, константы, инициализированные и неинициализированные переменные разделены.

На данном этапе изучения мы не будем обращать на это внимание, для нас главное — уловить суть понятий. С указанным вопросом мы столкнемся при програмировании для Windows на MASM32 и FASM, хотя практически всё можно настроить, задавая условия компиляции.

Добавить комментарий