русс | укр

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

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

Записи: дополнительные возможности обработки

Понимая важность для эффективного программирования такого типа данных, как запись, разработчики транслятора TASM, начиная с версии 3.0, включили в систему его команд две дополнительные команды на правах директив.

Последнее означает, что эти команды внешне имеют формат обычных команд ассемблера, но после трансляции они приводятся к одной или нескольким машинным командам.

Введение этих команд в язык TASM повышает наглядность работы с записями, оптимизирует код и уменьшает размер программы.

Эти команды позволяют скрыть от программиста действия по выделению и установке отдельных полей записи (мы их обсуждали выше).

Для установки значения некоторого поля записи используется команда setfield с синтаксисом:

setfield имя_элемента_записи назначение,регистр_источник

Для выборки значения некоторого поля записи используется команда getfield с синтаксисом:

getfield имя_элемента_записи регистр_назначение, источник

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

Операнд имя_элемента_записи определяет элемент записи, с которым ведется работа (по сути, если вы были внимательны, он определяет смещение элемента в записи относительно младшего разряда). Новое значение, в которое необходимо установить указанный элемент записи, должно содержаться в операнде регистр_источник. Обрабатывая данную команду, транслятор генерирует последовательность команд, которые выполняют следующие действия:

  • сдвиг содержимого регистр_источник влево на количество разрядов, соответствующее расположению элемента в записи;
  • логическую операцию or над операндами назначение и регистр_источник. Результат операции помещается в операнд назначение.

Важно отметить, что setfield не производит предварительной очистки элемента, в результате после логического сложения командой or возможно наложение старого содержимого элемента и нового устанавливаемого значения. Поэтому требуется предварительно подготовить поле в записи путем его обнуления.

Действие команды getfield обратно setfield. В качестве операнда источник может быть указан либо регистр либо адрес памяти.

В регистр, указанный операндом регистр_назначение, помещается результат работы команды — значение элемента записи.

Интересная особенность связана с регистр_назначение. Команда getfield всегда использует 16-битный регистр, даже если вы укажете в этой команде имя 8-битного регистра.

В качестве примера применения команд setfield и getfield рассмотрим листинг 9.

Листинг 9. Работа с полями записи;prg_12_8.asmmasmmodel smallstack 256iotest recordi1:1,i2:2=11,i3:1,i4:2=11,i5:2=00.dataflag iotest <>.codemain: mov ax,@data mov ds,ax mov al,flag mov bl,3 setfield i5 al,bl xor bl,bl getfield i5 bl,al mov bl,1 setfield i4 al,bl setfield i5 al,blexit: mov ax,4c00h ;стандартный выход int 21hend main ;конец программы

Результат работы команд setfield и getfield удобнее всего изучать в отладчике.

При установке значений полей не производится их предварительная очистка. Это сделано специально. Для такого рода операций лучше использовать некоторые универсальные механизмы, иначе велик риск внесения ошибок, которые трудно обнаружить и исправить. В качестве такого механизма можно предложить механизм макросредств.

В заключение хотелось бы привести еще один пример использования записей.

Это описание регистра eflags. Для удобства мы разбили это описание на три части:

  • eflags_1_7 — младший байт eflags/flags;
  • eflags_8_15 — второй байт eflags/flags;
  • eflags_h — старшая половина eflags.
eflags_l_7 record sf7:1=0,zf6:1=0,c5:1=0,af4:1=0,c3:1=0,pf2:1=0,c1:=1,cf0:1=0eflags_l_15 record c15:1=0,nt14:1=0,iopl:2=0,of11:1=0,df10:1=0,if9:1=1,tf8:1=0eflags_h record c:13=0,ac18:1=0,vm17:1=0,rf16:1=0

Запомните это описание. Когда вы освоите работу с макрокомандами и в дальнейшей своей работе столкнетесь с необходимостью работать с регистром флагов, то у вас буквально “зачешутся” руки, чтобы написать соответствующую макрокоманду. Эта макрокоманда, если вы не забудете хорошо ее оттестировать, избавит вас от многих трудно обнаруживаемых ошибок.

Лекция 11. Макросредства языка ассемблера (2 пары)

  • Понятие о макросредствах языка ассемблера
  • Псевдооператоры equ и =
  • Макрокоманды
  • Макродирективы
  • Директивы условной компиляции

Любопытный читатель к этому занятию, вероятно, попытался самостоятельно написать хотя бы несколько программ на ассемблере.

Скорее всего, эти программы были предназначены для решения небольших, чисто исследовательских задач, но даже на примере этих маленьких по объему программ вам, наверное, стали очевидны некоторые из перечисленных здесь проблем:

  • плохое понимание исходного текста программы, особенно по прошествии некоторого времени после ее написания;
  • ограниченность набора команд;
  • повторяемость некоторых идентичных или незначительно отличающихся участков программы;
  • необходимость включения в каждую программу участков кода, которые уже были использованы в других программах;
  • и многое другое

Если бы мы писали программу на машинном языке, то данные проблемы были бы принципиально не решаемыми. Но язык ассемблера, являясь символическим аналогом машинного языка, предоставляет для их решения ряд средств.

Основной целью, которая при этом преследуется, является повышение удобства написания программ.

В общем случае эта цель достигается по нескольким направлениям за счет следующего:

  • расширения набора директив;
  • введения некоторых дополнительных команд, не имеющих аналогов в системе команд микропроцессора. За примером далеко ходить не нужно — команды setfield и getfield, которые скрывают от программиста рутинные действия и генерируют наиболее эффективный код;
  • введения сложных типов данных.

Но это все глобальные направления, по которым развивается сам транслятор от версии к версии.

Что же делать программисту для решения его локальной задачи, для облегчения работы в определенной проблемной области?

Для этого разработчики компиляторов ассемблера включают в язык и постоянно совершенствуют аппарат макросредств. Этот аппарат является очень мощным и важным.

В общем случае есть смысл говорить о том, что транслятор ассемблера состоит из двух частей — непосредственно транслятора, формирующего объектный модуль, и макроассемблера (рис. 1).

Рис. 1. Макроассемблер в общей схеме трансляции программы на TASM

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

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

Таким образом, обработка программы на ассемблере с использованием макросредств неявно осуществляется транслятором в две фазы(рис. 1).

На первой фазе работает часть компилятора, называемая макроассемблером, функции которого на идейном уровне мы описали чуть выше.

На второй фазе трансляции работает непосредственно ассемблер, задачей которого является формирование объектного кода, содержащего текст исходной программы в машинном виде.

Далее мы обсудим основной набор макросредств, доступных при использовании компилятора TASM. Отметим, что большинство этих средств доступно и в компиляторе с языка ассемблера фирмы Microsoft.

Обсуждение начнем с простейших средств и закончим более сложными.

Псевдооператоры equ и =

К простейшим макросредствам языка ассемблера можно отнести псевдооператоры equ и "=" (равно).

Их мы уже неоднократно использовали при написании программ.

Эти псевдооператоры предназначены для присвоения некоторому выражению символического имени или идентификатора. Впоследствии, когда в ходе трансляции этот идентификатор встретится в теле программы, макроассемблер подставит вместо него соответствующее выражение.

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

Синтаксис псевдооператора equ:

имя_идентификатора equ строка или числовое_выражение

Синтаксис псевдооператора “=”:

имя_идентификатора = числовое_выражение

Несмотря на внешнее и функциональное сходство псевдооператоры equ и “=” отличаются следующим:

  • из синтаксического описания видно, что с помощью equ идентификатору можно ставить в соответствие как числовые выражения, так и текстовые строки, а псевдооператор “=” может использоваться только с числовыми выражениями;
  • идентификаторы, определенные с помощью “=”, можно переопределять в исходном тексте программы, а определенные с использованием equ — нельзя.

Ассемблер всегда пытается вычислить значение строки, воспринимая ее как выражение. Для того чтобы строка воспринималась именно как текстовая, необходимо заключить ее в угловые скобки: <строка>.

Кстати сказать, угловые скобки являются оператором ассемблера, с помощью которого транслятору сообщается, что заключенная в них строка должна трактоваться как текст, даже если в нее входят служебные слова ассемблера или операторы. Хотя в режиме Ideal это не обязательно, так как строка для equ в нем всегда трактуется как текстовая.

Псевдооператор equ удобно использовать для настройки программы на конкретные условия выполнения, замены сложных в обозначении объектов, многократно используемых в программе, более простыми именами и т. п.

К примеру:

masmmodel smallstack 256mas_size equ 10 ;размерность массиваakk equ ax ;переименовать регистрmas_elem equ mas[bx][si] ;адресовать элемент массива.data;описание массива из 10 байт:mas db mas_size dup (0).code mov akk,@data ;фактически mov ax,@data mov ds,akk ;фактически mov ds,ax... mov al,mas_elem ;фактически — mov al,mas[bx][si]

Псевдооператор “=” удобно использовать для определения простых абсолютных (то есть не зависящих от места загрузки программы в память) математических выражений.

Главное условие то, чтобы транслятор мог вычислить эти выражения во время трансляции.

К примеру:

.dataadr1 db 5 dup (0)adr2 dw 0len = 43len = len+1 ;можно и так, через предыдущее определениеlen = adr2-adr1

Как видно из примера, в правой части псевдооператора “=” можно использовать метки и ссылки на адреса — главное, чтобы в итоге получилось абсолютное выражение.

Компилятор TASM, начиная с версии 3.00, содержит директивы, значительно расширяющие его возможности по работе с текстовыми макросами. Эти директивы аналогичны некоторым функциям обработки строк в языках высокого уровня. Под строками здесь понимается текст, описанный с помощью псевдооператора equ.

Набор этих директив следующий:

  • директива слияния строк catstr:
  • идентификатор catstr строка_1,строка_2,... — значением этого макроса будет новая строка, состоящая из сцепленной слева направо последовательности строк строка_1,строка_2,...
  • В качестве сцепляемых строк могут быть указаны имена ранее определенных макросов.
  • К примеру:
pre equ Привет,name equ < Юля>privet catstr pre,name ;privet= “Привет, Юля”
  • директива выделения подстроки в строке substr:
  • идентификатор substr строка,номер_позиции,размер — значением данного макроса будет часть заданной строки, начинающаяся с позиции с номером номер_позиции и длиной, указанной в размер.
  • Если требуется только остаток строки, начиная с некоторой позиции, то достаточно указать только номер_позиции без указания размера.
  • К примеру:
;продолжение предыдущего фрагмента:privet catstr pre,name ;privet= “Привет, Юля”name substr privet,7,3 ;name=“Юля”
  • директива определения вхождения одной строки в другую instr:
  • идентификатор instr номер_нач_позиции,строка_1,строка_2 — после обработки данного макроса транслятором идентификатору будет присвоено числовое значение, соответствующее номеру (первой) позиции, с которой совпадают строка_1 и строка_2.
  • Если такого совпадения нет, то идентификатор получит значение 0;
  • директива определения длины строки в текстовом макросе sizestr:
  • идентификатор sizestr строка — в результате обработки данного макроса значение идентификатор устанавливается равным длине строки.
;как продолжение предыдущего фрагмента:privet catstr pre,name ;privet= “Привет, Юля”len sizestr privet ;len=10

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

Просмотров: 649


Вернуться в оглавление



Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.