Tooprogram.ru

Компьютерный справочник
0 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Структура ассемблерной строки

Структура ассемблерной строки

Существует несколько версий программы GENS, но для определенности мы будем рассматривать GENS4. Тем не менее, почти все, о чем пойдет речь в нашей книге, справедливо и для других версий ассемблера фирмы HISOFT, поэтому мы не всегда станем уточнять версию, а чаще будем писать просто GENS.

ЗАГРУЗКА GENS4

СТРУКТУРА АССЕМБЛЕРНОЙ СТРОКИ

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

Рассмотрим назначение каждого их этих полей.

Хотя строки в программах для GENS и нумеруются, но в ассемблере ссылки на номера строк, в отличие от Бейсика, нигде не применяются. Нумерация нужна исключительно для определения очередности следования строк, вывода листинга на экран или принтер и для вызова строк на редактирование. Допустимые значения этого поля — от 1 до 32767.

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

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

Если у команды имеются какие-либо операнды, они записываются в следующем и последнем поле строки — в поле операндов. Таким образом полная команда может занимать в строке программы одно или два поля.

ВВОД СТРОКИ

Вводить строки можно двумя способами: так же, как и в Бейсике, то есть каждый раз набирать номер и текст, или воспользоваться автоматической нумерацией, что на наш взгляд несравненно удобнее. Для автоматической нумерации строк нужно на подсказку редактора (символ > с курсором C или L) ввести команду I (Insert — режим вставки строк) и нажать Enter. Первая строка будет иметь номер 10 и последующие номера будут увеличиваться с шагом 10. Если вы пожелаете изменить порядок нумерации строк, введите ту же команду I, но с двумя параметрами, разделенными запятой: первое число — начальный номер, второе — шаг. Например, I100,5.

Итак, введите команду I с параметрами или без — после старта GENS оба параметра по умолчанию равны 10, поэтому в самом начале работы их можно и не указывать.

Так как в первой строке метки нам не понадобятся, сразу перейдем к полю мнемоник. Переход к следующему полю строки осуществляется вводом символа табуляции, который получается при одновременном нажатии клавиш Caps Shift и 8. (Вместо символов табуляции можно вводить просто один или несколько пробелов — после окончательного ввода строки они автоматически будут заменены кодами табуляции, и при просмотре листинга текст будет выглядеть аккуратно выровненным по границам полей.) Нажмите эту комбинацию клавиш и увидите, как курсор перескочит вправо сразу на несколько позиций печати. Теперь можно набрать какую-нибудь инструкцию.

Как правило, программы на ассемблере начинаются с указания начального адреса, то есть того адреса, с которого полученная программа будет загружаться в память. Это достигается включением в программу директивы ORG (от англ. Origin — начало), следом за которой пишется десятичный или шестнадцатеричный адрес. (При записи шестнадцатеричных чисел они должны начинаться с символа #, например, #3FC.) Наберите в первой строке эту директиву и укажите после символа табуляции адрес 60000. Если вы случайно нажмете не ту клавишу, удалить последний введенный символ можно обычным образом, нажав клавиши Caps Shift/0 или Delete. Но вот переместить курсор к любому символу строки стандартными методами не удастся: ведь клавиши Caps Shift/8, как вы уже знаете, отвечают за ввод табуляции, а Caps Shift/5 удалит весь текст строки и переместит курсор в самое ее начало. Закончите ввод нажатием клавиши Enter, после чего строка должна принять вид а ниже появится номер следующей строки с курсором.

Аналогичным образом введите еще две строки: Теперь нам нужно вернуться в строчный редактор GENS. Для этого достаточно нажать клавишу Edit или Caps Shift/1. На экране снова появится подсказка, на которую можно вводить команды редактора.

ПРОСМОТР ТЕКСТА

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

ТРАНСЛЯЦИЯ ПРОГРАММЫ

ВЫХОД ИЗ GENS

После выхода из GENS4 мы рекомендуем вам прежде всего очищать экран оператором CLS или простым нажатием клавиши Enter. Дело в том, что эта версия пользуется для вывода на экран встроенным драйвером, позволяющим выводить в строке до 51 символа мелким шрифтом, и при выходе стандартный канал вывода по каким-то причинам не сразу восстанавливается. Поэтому до очистки экрана оператор PRINT может не дать ожидаемых результатов.

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

Снова вызовите редактор GENS и введите команду L. Как видите, текст набранной программки никуда не исчез.

ВНЕСЕНИЕ В ТЕКСТ ИЗМЕНЕНИЙ

Начнем со способов внесения правок в уже имеющийся текст. Для вызова строки на редактирование служит команда E (Edit) с номером нужной строки (рис. 3.1). Давайте в нашей программке подправим, например, строку 20, изменив число, загружаемое в регистровую пару BC. Введите команду E20. То, что вы увидели, возможно, несколько удивило вас. На экране появилась вызванная строка, но курсор на ней не задержался, а проскочил ниже, напечатав только номер. Весь остальной текст куда-то подевался. Может создаться такое впечатление, что теперь необходимо набирать весь текст заново. Однако, это только впечатление, и на самом деле строка сейчас готова к редактированию.

Рис. 3.1. Редактирование строки в GENS4

Вы можете вносить изменения в текст строки двумя способами: в режиме вставки, в котором вновь введенные символы «раздвигают» строку и не затирают имеющийся текст, и в режиме замены, в котором новые символы ложатся поверх прежних. В любом случае сначала необходимо подвести курсор к тому месту строки, где требуются какие-либо изменения. Вправо курсор можно перемещать по одной позиции, нажимая пробел, или разом перескакивать к следующему полю при нажатии Caps Shift/8. Перемещая курсор, вы увидите появляющийся под ним текст строки. Возврат на одну позицию влево происходит при нажатии клавиши Delete (Caps Shift/0)(обратите внимание на тот факт, что пока еще ничего не удаляется — вы просто перемещаете курсор, а верхняя строка нужна для подсказки).

Подведите курсор к числу 1000 так, чтобы он находился точно под единицей. Затем нажмите клавишу C для перехода в режим замены символов (в режим вставки можно перейти, нажав клавишу I, но это — на будущее). Обратите внимание, что курсор при этом изменяет свой вид. Теперь он выглядит как инвертированный символ + (в режиме вставки курсор имеет вид символа *, и это тоже — на будущее). Замените цифру 1 на 5, а следующий ноль, скажем, на 3. Затем выйдите из режима замены, нажав Enter и, наконец, введите строку в программу, еще раз нажав Enter. Редактирование строки закончено, и сейчас она должна иметь вид Можете ассемблировать новый текст и, выйдя в Бейсик, выполнить получившуюся программку оператором Прежде чем показать вам, как можно сохранить исходный текст и готовый машинный код, приведем и остальные команды редактирования строки. Вот они: Все эти команды выполняются до включения режимов вставки или замены символов (команды I или C). Если же один из этих режимов уже включен, следует прежде выйти из него, нажав Enter.

Читать еще:  Jnc команда ассемблер

СОХРАНЕНИЕ И ЗАГРУЗКА ТЕКСТОВ И ПРОГРАММ

Обратное действие — загрузка ранее созданного исходного текста — осуществляется с помощью команды редактора G (Get text). Формат ее похож на формат предыдущей команды, правда, значение имеет только последний параметр — имя файла. Поэтому для загрузки программы GAME с магнитофона следует ввести а для загрузки одноименного файла с дисковода B эта же команда примет вид По сравнению с оператором Бейсика LOAD у команды G есть одно существенное отличие: она не уничтожает уже имеющийся в памяти текст, а добавляет новый в конец. После объединения строки программы будут перенумерованы с номера 1 и с единичным шагом. Часто такая особенность команды G бывает не только полезна, но и просто необходима, однако если вы собираетесь поработать над новой программой, прежде чем ее загружать, надо убедиться, что редактор свободен от какого бы то ни было текста, а если нет, то удалить его (как это сделать, мы скажем чуть позже).

Для сохранения полученного машинного кода (нередко называемого объектным, хотя это и не совсем верно) можно воспользоваться командой O (Object). Она имеет синтаксис, аналогичный команде G, то есть для записи оттранслированной программы в файл MYPROG при работе с лентой нужно ввести строку а при работе с дисководом A эта команда запишется как Записывая тексты и программы на диск, вы иногда можете увидеть на экране надпись сообщающую о том, что одноименный файл уже имеется на диске. В этом случае вам предлагается решить, удалять этот файл или отказаться от записи с тем, чтобы заменить дискету и попытаться сохранить текст еще раз. Если на этот запрос ответить нажатием клавиши Y, то файл на диске будет переписан, нажатие любой другой клавиши приведет к отказу от выполнения команды.

УДАЛЕНИЕ ТЕКСТА

Но, как вы понимаете, такой способ приемлем для удаления двух-трех строчек, когда же требуется ликвидировать значительную часть текста, подобная методика превращается в настоящую пытку. Фирма HISOFT учла интересы программистов и включила в редактор возможность удаления произвольной группы строк. Для этих целей служит команда D (Delete — удалить) с двумя параметрами, разделенными запятой. Первым указывается номер начальной строки удаляемого фрагмента, а затем — номер последней удаляемой строки. Например, для исключения из текста строк, начиная с сотой и по стопятидесятую включительно, нужно ввести команду Обращаться с этой командой нужно достаточно осторожно, так как выполняется она сразу же после ввода, безо всяких дополнительных подтверждающих запросов, а восстановить удаленный текст можно будет только если вы успели сохранить его на ленте или дискете. Ни в коем случае не следует использовать команду D без параметров, потому как при этом будут взяты параметры предыдущей введенной команды (параметры по умолчанию), а они могут далеко не соответствовать желаемым.

В редакторе GENS есть еще одна полезная команда, предназначенная для удаления текста. Это команда Z. С ее помощью можно быстро уничтожить сразу весь текст. Она не требует никаких параметров, а после ввода просит подтвердить ваши намерения запросом Если вы не передумали стирать текст, нажмите клавишу Y, в противном случае — любую другую клавишу.

Структура программы на ассемблере

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

Каждая машинная команда состоит из двух частей:

  • операционной — определяющей, «что делать»;
  • операндной — определяющей объекты обработки, «с чем делать».

Машинная команда микропроцессора, записанная на языке ассемблера, представляет собой одну строку, имеющую следующий синтакический вид:

метка команда/директива операнд(ы) ;комментарии

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

Метка, команда/директива и операнды (если имеются) разделяются по крайней мере одним символом пробела или табуляции.

Если команду или директиву необходимо продолжить на следующей строке, то используется символ обратный слеш: .

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

Примеры строк кода:

Метки

Метка в языке ассемблера может содержать следующие символы:

  • все буквы латинского алфавита;
  • цифры от 0 до 9;
  • спецсимволы: _, @, $, ?.

В качестве первого символа метки может использоваться точка, но некоторые компиляторы не рекомендуют применять этот знак. В качестве меток нельзя использовать зарезервированные имена Ассемблера (директивы, операторы, имена команд).

Первым символом в метке должна быть буква или спецсимвол (но не цифра). Максимальная длина метки – 31 символ. Все метки, которые записываются в строке, не содержащей директиву ассемблера, должны заканчиваться двоеточием : .

Команды

Команда указывает транслятору, какое действие должен выполнить микропроцессор. В сегменте данных команда (или директива) определяет поле, рабочую область или константу. В сегменте кода команда определяет действие, например, пересылка (mov) или сложение (add).

Директивы

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

Операнды

Операнд – объект, над которым выполняется машинная команда или оператор языка программирования.
Команда может иметь один или два операнда, или вообще не иметь операндов. Число операндов неявно задается кодом команды.
Примеры:

  • Нет операндов ret ;Вернуться
  • Один операнд inc ecx ;Увеличить ecx
  • Два операнда add eax,12 ;Прибавить 12 к eax

Метка, команда (директива) и операнд не обязательно должны начинаться с какой-либо определенной позиции в строке. Однако рекомендуется записывать их в колонку для большего удобства чтения программы.

В качестве операндов могут выступать

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

Идентификаторы – последовательности допустимых символов, использующиеся для обозначения таких объектов программы, как коды операций, имена переменных и названия меток.

Правила записи идентификаторов.

  • Идентификатор может состоять из одного или нескольких символов.
  • В качестве символов можно использовать буквы латинского алфавита, цифры и некоторые специальные знаки: _, ?, $, @.
  • Идентификатор не может начинаться символом цифры.
  • Длина идентификатора может быть до 255 символов.
  • Транслятор воспринимает первые 32 символа идентификатора, а остальные игнорирует.
Комментарии

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

Структура программы на ассемблере

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

Читать еще:  Int 10h ассемблер

Пример «ничего не делающей» программы на языке ассемблера:

В данной программе представлена всего одна команда микропроцессора. Эта команда RET . Она обеспечивает правильное окончание работы программы. В общем случае эта команда используется для выхода из процедуры.
Остальная часть программы относится к работе транслятора.
.686P — разрешены команды защищенного режима Pentium 6 (Pentium II). Данная директива выбирает поддерживаемый набор команд ассемблера, указывая модель процессора. Буква P, указанная в конце директивы, сообщает транслятору о работе процессора в защищенном режиме.
.MODEL FLAT, stdcall — плоская модель памяти. Эта модель памяти используется в операционной системе Windows. stdcall — используемое соглашение о вызовах процедур.
.DATA — сегмент программы, содержащий данные.
.CODE — блок программы, содержащей код.
START — метка. В ассемблере метки играют большую роль, что не скажешь о современных языках высокого уровня.
END START — конец программы и сообщение транслятору, что начинать выполнение программы надо с метки START .
Каждый модуль должен содержать директиву END , отмечающую конец исходного кода программы. Все строки, которые следуют за директивой END , игнорируются. Если опустить директиву END , то генерируется ошибка.
Метка, указанная после директивы END , сообщает транслятору имя главного модуля, с которого начинается выполнение программы. Если программа содержит один модуль, метку после директивы END можно не указывать.

Структуры в языке ассемблер

Главная > Лекция >Информатика, программирование

Структуры в языке ассемблер

Рассмотренные нами выше массивы представляют собой совокупность однотипных элементов. Но часто в приложениях возникает необходимость рассматривать некоторую совокупность данных разного типа как некоторый единый тип.

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

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

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

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

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

Задать шаблон структуры .

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

Определить экземпляр структуры .

Этот этап подразумевает инициализацию конкретной переменной заранее определенной (с помощью шаблона) структурой.

Организовать обращение к элементам структуры .

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

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

Этот шаблон можно рассматривать лишь как информацию для транслятора о расположении полей и их значении по умолчанию.

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

Описать структуру в программе можно только один раз, а определить — любое количество раз.

Описание шаблона структуры

Описание шаблона структуры имеет следующий синтаксис:

Здесь представляет собой последовательность директив описания данных db, dw, dd, dq и dt .

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

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

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

Рассмотрим работу со структурами на примере моделирования базы данных о сотрудниках некоторого отдела.

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

Определим структуру записи этой базы данных следующим шаблоном:

worker struc ;информация о сотруднике

nam db 30 dup (‘ ‘) ;фамилия, имя, отчество

sex db ‘м’ ;пол, по умолчанию ‘м’ — мужской

position db 30 dup (‘ ‘) ;должность

age db 2 dup(‘ ’) ;возраст

standing db 2 dup(‘ ’) ;стаж

salary db 4 dup(‘ ’) ;оклад в рублях

birthdate db 8 dup(‘ ’) ;дата рождения

Определение данных с типом структуры

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

[имя переменной] имя_структуры

имя переменной — идентификатор переменной данного структурного типа.

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

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

Его задание также необязательно.

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

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

К примеру: victor worker <> .

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

sotr1 worker ;здесь все значения по умолчанию

Методы работы со структурой

Идея введения структурного типа в любой язык программирования состоит в объединении разнотипных переменных в один объект.

В языке должны быть средства доступа к этим переменным внутри конкретного экземпляра структуры. Для того чтобы сослаться в команде на поле некоторой структуры, используется специальный оператор — символ » . » (точка) . Он используется в следующей синтаксической конструкции:

адресное_выражение — идентификатор переменной некоторого структурного типа или выражение в скобках в соответствии с указанными ниже синтаксическими правилами (рис. 1);

имя_поля_структуры — имя поля из шаблона структуры.

Это, на самом деле, тоже адрес, а точнее, смещение поля от начала структуры.

Таким образом оператор » . » (точка) вычисляет выражение

Рис. 5. Синтаксис адресного выражения в операторе обращения к полю структуры

Продемонстрируем на примере определенной нами структуры worker некоторые приемы работы со структурами.

К примеру, извлечь в ax значения поля с возрастом. Так как вряд ли возраст трудоспособного человека будет больше величины 99 лет, то после помещения содержимого этого символьного поля в регистр ax его будет удобно преобразовать в двоичное представление командой aad .

Будьте внимательны, так как из-за принципа хранения данных “младший байт по младшему адресу” старшая цифра возраста будет помещена в al , а младшая — в ah .

Для корректировки достаточно использовать команду xchg al,ah :

mov ax,word ptr sotr1.age ;в al возраст sotr1

mov ax,word ptr [bx].age

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

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

К примеру, определим массив из 10 структур типа worker :

mas_sotr worker 10 dup (<>)

Дальнейшая работа с массивом структур производится так же, как и с одномерным массивом. Здесь возникает несколько вопросов:

Читать еще:  Час в рамках системы си является

Как быть с размером и как организовать индексацию элементов массива?

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

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

mas_sotr worker 10 dup (<>)

mov bx,type worker ;bx=77

;извлечь и вывести на экран пол всех сотрудников:

;вывод на экран содержимого поля sex структуры worker

add di,bx ;к следующей структуре в массиве mas_sort

Как выполнить копирование поля из одной структуры в соответствующее поле другой структуры? Или как выполнить копирование всей структуры? Давайте выполним копирование поля nam третьего сотрудника в поле nam пятого сотрудника:

mas_sotr worker 10 dup (<>)

mov bx,offset mas_sotr

mov si,(type worker)*2 ;si=77*2

mov di,(type worker)*4 ;si=77*4

Мне кажется, что ремесло программиста рано или поздно делает человека похожим на хорошую домохозяйку. Он, подобно ей, постоянно находится в поиске, где бы чего-нибудь сэкономить, урезать и из минимума продуктов сделать прекрасный обед. И если это удается, то и моральное удовлетворение получается ничуть не меньше, а может и больше, чем от прекрасного обеда у домохозяйки. Степень этого удовлетворения, как мне кажется, зависит от степени любви к своей профессии.

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

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

Структура ассемблерной строки

4.1. Назначение языков ассемблера.

Ассемблер (от англ. assemble — собирать) — компилятор с языка ассемблера в команды машинного языка.

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

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

Язык ассемблера — тип языка программирования низкого уровня. Команды языка ассемблера один в один соответствуют командам процессора и представляют собой удобную символьную форму записи (мнемокод) команд и аргументов. Язык ассемблера обеспечивает связывание частей программы и данных через метки, выполняемое при ассемблировании (для каждой метки высчитывается адрес, после чего каждое вхождение метки заменяется на этот адрес).

Каждая модель процессора имеет свой набор команд и соответствующий ему язык (или диалект) ассемблера.

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

Связывание ассемблерного кода с другими языками. Большинство современных компиляторов позволяют комбинировать в одной программе код, написанный на разных языках программирования. Это дает возможность быстро писать сложные программы, используя высокоуровневый язык, не теряя быстродействия в критических ко времени задачах, применяя для них части, написанные на языке ассемблера. Комбинирование достигается несколькими приемами:

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

2. Модульная компиляция. Большинство современных компиляторов работают в два этапа. На первом этапе каждый файл программы компилируется в объектный модуль. А на втором объектные модули линкуются (связываются) в готовую программу. Прелесть модульной компиляции состоит в том, что каждый объектный модуль будущей программы может быть полноценно написан на своем языке программирования и скомпилирован своим компилятором (ассемблером).

Достоинства языков ассемблера.

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

2. Использование расширенных наборов инструкций процессора (MMX, SSE, SSE2, SSE3).

3. Доступ к портам ввода-вывода и особым регистрам процессора (в большинстве ОС эта возможность доступна только на уровне модулей ядра и драйверов)

4. Возможность использования самомодифицирующегося (в том числе перемещаемого) кода (под многими платформами она недоступна, так как запись в страницы кода запрещена, в том числе и аппаратно, однако в большинстве общедоступных систем из-за их врожденных недостатков имеется возможность исполнения кода, содержащегося в сегменте (секции) данных, куда запись разрешена).

5. Максимальная адаптация для нужной платформы.

Однако следует отметить, что последние технологии безопасности, внедряемые в операционные системы и компиляторы, не позволяют делать самомодифицирующего кода, так как исключают одновременную возможность исполнения программы и запись в одном и том же участке памяти (технология W^X).

Технология W^X используется в OpenBSD , в других BSD-системах, в Linux. В Microsoft Windows (начиная с Windows XP SP2) применяется схожая технология DEP.

Недостатки языков ассемблера.

1. Большие объемы кода, большое число дополнительных мелких задач, меньшее количество доступных для использования библиотек по сравнению с языками высокого уровня.

2. Трудоемкость чтения и поиска ошибок (хотя здесь многое зависит от комментариев и стиля программирования).

3. Часто компилятор языка высокого уровня, благодаря современным алгоритмам оптимизации, даёт более эффективную программу (по соотношению качество/время разработки).

4. Непереносимость на другие платформы (кроме совместимых).

5. Ассемблер более сложен для совместных проектов.

4.2. Синтаксис ассемблера.

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

Синтаксис строки имеет следующий общий вид:

Все эти четыре поля необязательны, в программе вполне могут присутствовать и полностью пустые строки для выделения каких либо блоков кода. Метка может быть любой комбинацией букв английского алфавита, цифр и символов _, $, @, ?, но цифра не может быть первым символом метки, а символы $ и ? иногда имеют специальные значения и обычно не рекомендуются к использованию. Большие и маленькие буквы по умолчанию не различаются, но различие можно включить, задав ту или иную опцию в командной строке ассемблера. Во втором поле, поле команды, может располагаться команда процессора, которая транслируется в исполняемый код, или директива, которая не приводит к появлению нового кода, а управляет работой самого ассемблера. В поле операндов располагаются требуемые командой или директивой операнды (то есть нельзя указать операнды и не указать команду или директиву). И наконец, в поле комментариев, начало которого отмечается символом ; (точка с запятой), можно написать все что угодно — текст от символа «;» до конца строки не анализируется ассемблером.

4.3. Ассемблерные вставки в языках высокого уровня.

Языки высокого уровня поддерживают возможность вставки ассемблерного кода. Последовательность команд Ассемблера в С-программе размещается в asm-блоке:

Ссылка на основную публикацию
Adblock
detector