Секции .data, .data? и .const нужны для определения данных программы. Место под данные резервируется с помощью директив db, dw, dd, dq, dt.
db — 1 байт dw — 2 байта — 1 слово dd — 4 байта — 2 слова dq — 8 байт — 4 слова dt — 10 байт
Секция .data наиболее универсальная мы резервируем память под данные и сразу же инициализируем их, т.е. задаём им начальные значения. Все данные из этой секции включаются в исполнимый файл. Секция .data? менее гибкая, так как данные нельзя инициализировать.
Все данные в этой секции не включаются в исполнимый файл, поэтому место только резервируется, но начальные значения не задаются. Данные в обеих секциях имеют полный режим доступа. Секция .const предназначена только чтения. Но ошибок не возникает при попытке изменить эти данные (. ). Эта секция самая бесполезная.
.data Perem dd 0000FF11h X1 dw 01235h Binary db 00111010b dd 11225599h decimal dw 28d large dq 01123456789ABCDEFh dw 1011100101010111b .data? Perem1 dd ? Perem2 dq ? Perem5 dw ? Dd ? Dw ? Perem4 db ? ..const Const1 dd 012345678h dw 768d
Строки.
В ассемблере можно задавать только ANSI строки, Unicode строки сложнее задавать и для их обработки существует целый ряд API функций.
Как записать видео с экрана со звуком. Программа для Windows, Mac и Linux
В ассемблере также можно вместо присваивания однобайтовой переменной некоторого числа можно присвоить переменно букву. Но, в конечном счете, эта переменная будет равна коду буквы в кодировке ANSI. При инициализации символа можно использовать и кавычки и апострофы — без разницы.
.data Char1 db ‘W’ Char2 db ‘Й’ db «r»
Всё выше написанное тоже самое что и:
.data Char1 db 57h Char2 db 0C9h db 72h
При объявлении строк можно просто написать стоку после директивы db. Это воспринимается как последовательность символов
String db «ASM» Тоже самое: String db ‘A’ Db «S» Db «M»
String db 41h Db 53h Db 4Dh
String db 41h, 53h, 4Dh
При передаче строк функциям в качестве параметров надо чтобы в конце строки был 0, для того чтобы функция смогла найти конец строки.
String db «ASM»,0 Msg db «First ASSEMBLER program»,0 Ttl db ‘Hello, World. ‘,0
Заполнение данными.
Иногда нужно описать много одинаковых переменных примерно штук 30. Вы будете делать так
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 30 раз
Это неудобно и некрасиво, тем более можно обсчитаться. Для сделана директива DUP.
db 30 DUP (0) ; тот же результат
в скобках указываем, чем надо заполнять, можно использовать символы в кавычках, обязательно чтобы размер в скобках совпадал с директивой.
Dd 10 DUP («в») Dw 45h DUP (0DF23h) Dd 100b DUP (12345678h)
С данными всё понятно. Читаем следующий урок. На 6 уроке мы будем говорить о метках и их использовании.
Источник: codenet.ru
9. Директивы описания данных db, dw, dd. Оператор dup. Примеры.
«Имя» представляет собой идентификатор, который вы будете затем использовать для ссылки на данные. Тип может быть следующим: BYTE, WORD, DATAPTR, CODEPTR, DWORD, FWORD, PWORD, QWORD, TBYTE, SHORT, NEAR, FAR или имя структуры. «Выражение» может быть выражением-константой, вопросительным знаком или выражением с DUP.
06. Низкоуровневое программирование. Ассемблер. Пример программы. [Универсальный программист]
Иногда нужно описать много одинаковых переменных примерно штук 30. Вы будете делать так
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; 30 раз
Это неудобно и некрасиво, тем более можно обсчитаться. Для сделана директива DUP.
db 30 DUP (0) ; тот же результат
в скобках указываем, чем надо заполнять, можно использовать символы в кавычках, обязательно чтобы размер в скобках совпадал с директивой.
arraydb 99 dup 0;массив array из 99 байтов со значениями 0
10. Директивы assume, org, end
Директива ASSUME Режимы Ideal, MASM
ASSUME сегмент:имя[,сегмент:имя].
ASSUME сегментный_регистр:NOTHING
ASSUME NOTHING
Задает сегментный регистр, который будет использоваться для вычисления действующего адреса для всех меток и переменных, определенных для сегмента или группы сегментов с указанным именем.
Ключевое слово NOTHING отменяет связь между указанным сегментным регистром и именем сегмента или группы.
Директива ORG Режимы Ideal, MASM
ORG выражение
Устанавливает счетчик инструкций в текущем сегменте в соответствии с адресом, задаваемым «выражением».
Директива END Режимы Ideal, MASM
END [начальный_адрес]
Отмечает начало исходного файла. «Начальный_адрес» — это идентификатор или выражение, которое задает адрес вашей программы начале выполнения. Турбо Ассемблер игнорирует любой текст, который встречается после директивы END.
11. Директивы EXTRN, PUBLIC
EXTRN определение[,определение].
Указывает, что идентификатор определен в другом модуле. Описывает идентификатор и имеет следующий формат: [язык] имя[счетчик_1]:тип[:счетчик_2]
где «язык» задает, что к идентификатору с указанным именем должны применяться соглашения заданного языка (C, PASCAL).
«Имя» — это идентификатор, который определен в другом модуле и за которым может следовать «счетчик_1», множитель элемента массива, значение которого по умолчанию равно 1.
«Тип» должен соответствовать типу идентификатора, указанному при его определении, и может быть следующим: BYTE, WORD, DWORD, ABS или именем структуры.
Значение «счетчика_2» задает, сколько элементов определяет данный внешний идентификатор. По ум.равно 1
Для того, чтобы редактор связей мог осуществить связывание модулей в единую программу, переменные и метки, объявленные по крайней мере в одном из модулей как EXTRN, в другом модуле должны быть объявлены как доступные для всех модулей при помощи директивы PUBLIC .
PUBLIC [язык] идентификатор [,[язык] идентификатор].
Описывает идентификатор, как доступный из других модулей. Если задан «язык» (C, PASCAL, BASIC, FORTRAN, ASSEMBLER или PROLOG), то идентификатор становится доступным с учетом применения к нему соглашений по именам, принятым в указанном языке.
12. Основные команды арифметических операций. Их использование и особенности работы с двоичными и десятичными числами, со знаком и без знака.
Арифметические операции над целыми двоичными числами
В данном разделе мы рассмотрим особенности каждого из четырех основных арифметических действий для двоичных чисел со знаком и без знака.
Сложение двоичных чисел без знака
Микропроцессор выполняет сложение операндов по правилам сложения двоичных чисел. Проблем не возникает до тех пор, пока значение результата не превышает размерности поля операнда (см. табл. 6.1). Например, при сложении операндов размером в байт результат не должен превышать число 255. Если это происходит, то результат оказывается неверен.
Рассмотрим, почему так происходит. К примеру, выполним сложение: 254 + 5 = 259 в двоичном виде. 11111110 + 0000101 = 1 00000011. Результат вышел за пределы восьми бит, и правильное его значение укладывается в 9 битов, а в 8-битном поле операнда осталось значение 3, что, конечно, неверно.
В микропроцессоре этот исход сложения прогнозируется, и предусмотрены специальные средства для фиксирования подобных ситуаций и их обработки. Так, для фиксирования ситуации выхода за разрядную сетку результата, как в данном случае, предназначен флаг переноса cf. Он располагается в бите 0 регистра флагов eflags/flags.
Именно установкой этого флага фиксируется факт переноса единицы из старшего разряда операнда. Естественно, что программист должен предусматривать возможность такого исхода операции сложения и средства для корректировки. Это предполагает включение участков кода после операции сложения, в которых анализируется флаг cf. Анализ этого флага можно провести различными способами.
Самый простой и доступный — использовать команду условного перехода jc. Эта команда в качестве операнда имеет имя метки в текущем сегменте кода. Переход на эту метку осуществляется в случае, если в результате работы предыдущей команды флаг cf установился в 1. Команды условных переходов будут рассматриваться позднее.
Если теперь посмотреть на рис. 6.1, то видно, что в системе команд микропроцессора имеются три команды двоичного сложения:
О inc операнд — операция инкремента, то есть увеличения значения операнда на 1;
О add операнд_1,операнд_2 — команда сложения с принципом действия: операнд_1 = операнд_1 + операнд_2;
О adc операнд_1,операнд_2 — команда сложения с учетом флага переноса cf.
Принцип действия команды:
операнд_1 = операнд_1 + операнд_2 + значение_cf
Обратите внимание на последнюю команду — это команда сложения, учитывающая перенос единицы из старшего разряда. Механизм появления такой единицы мы уже рассмотрели. Таким образом, команда adcявляется средством микропроцессора для сложения длинных двоичных чисел, размерность которых превосходит поддерживаемые микропроцессором длины стандартных полей.
Рассмотрим пример вычисления суммы чисел (листинг 8.3).
8.3. Вычисление суммы чисел
Источник: studfile.net
Директивы ассемблера
Директивы представляют собой команды управления компилятором. Объявление каждой из них должно начинается с точки. Практика показывает, что в любом ассемблере наиболее интенсивно используется только порядка 10…20 директив. Все остальные либо не являются обязательными, либо отвечают за управление, лишь незначительными свойствами компилятора.
К “основным”, характерным и для ассемблеров других процессоров, относятся директивы .equ, .org, .def, .сseg, .dseg и т.д. Ну, а такие директивы, как .dq, .exit, .listmac в реальных программах встречаются действительно очень редко. Ниже приведен перечень, описание и примеры использования директив фирменного ассемблера микроконтроллеров AVR.
Директива .include подставляет текстовый файл в то место программы, где происходит ее употребление. В дополнении к этому сам файл подстановки также может содержать директиву .include. Если файл расположен в директории проекта или в одной из служебных папок, то вместо полного пути, допускается указывать, лишь ссылку на его имя. Директива .include
Синтаксис написания:
.include «»
Пример использования:
.include «m8def.inc» ;вставка стандартного заголовочного файла
Директива .exit указывает ассемблеру место окончания файла исходного текста. Все операторы, находящиеся после директивы, становятся невидимыми для компилятора. Если .exit встречается в подключаемом файле, то сборка проекта заканчивается строкой, где расположена директива .include. В случае отсутствия директивы .exit, конечной точкой сборки считается последняя строка исходного текста. Директива .exit
Синтаксис написания:
.exit
Пример использования:
.exit ;конец файла
Директивы .nolist и .list служат для управления файлом листинга, который обычно генерируется после сборки проекта. Первая из них запрещает, а другая, соответственно, разрешает вывод информации в файл. Директива .list отменяет действие .nolist и наоборот. Директивы .nolist, .list
Синтаксис написания:
.nolist, .list
Пример использования:
.nolist ;запретить вывод текста файла “m8def.inc” .include «m8def.inc» ;в файл листинга программы .list ;продолжить вывод информации
Директива .equ присваивает символьному имени некоторое числовое значение. Символьное имя должно быть уникальным и не может быть изменено в процессе написания программы. Директива не может применяться для назначения символьных имен регистрам общего назначения. Директива .equ
Синтаксис написания:
.equ =
Пример использования:
.equ DDRB = 0x17 ;присвоение имени DDRB значения 0x17 .equ PORTB = DDRB + 1 ;присвоение имени PORTB значения 0x18
Директива .set производит то же самое действие, что и .equ. Но в отличии от последней, символьное имя может быть переопределено в любом месте программы. Директива .set
Синтаксис написания:
.set =
Пример использования:
.set OFFSET = 0x100 ;присвоение имени OFFSET значения 0x100 . .set OFFSET = OFFSET + 1 ;переопределение значения OFFSET
Директива .def присваивает символьное имя одному из регистров общего назначения. В дальнейшем ходе программы данное имя может быть отменено директивой .undef. Директивы .def, .undef
Синтаксис написания:
.def =
.undef
Пример использования:
.def temp = R16 ;присвоение регистру R16 имя temp .undef temp ;отмена дальнейшего использования имени temp
Директивы .db, .dw, .dd, .dq предназначены для резервирования памяти микроконтроллера под инициализированные данные. Все они могут применяться только в сегментах кода и EEPROM-памяти. Разница между этими директивами заключается в разрядности, представляемых данных. Директива .db резервирует байты, .dw – слова, .dd – двойные слова. В редких случаях может так же оказаться удобным использование директивы .dq, резервирующей 64-разрядные данные. Директивы .db, .dw, .dd, .dq
Синтаксис написания:
: .db
: .dw
: .dd
: .dq
Пример использования:
label: .db 0xFA, 250, -6, 0b11111010 .dw 0xFADE, 64222, -1314, 0b1111101011011110 .dd 0xFADEEFCA, 4208914378, -86052918 .dq 0xFADEEFCAEFBACDEF, 18077149609196178927, -521103510453211
Директива .byte резервирует память под неинициализированные данные в сегментах SRAM и EEPROM. Директива .byte
Синтаксис написания:
: .byte
Пример использования:
.equ PAGESIZE = 0x20 buffer: . byte 2*PAGESIZE ;резервирование 64 байт в SRAM
Директивы .dseg, .eseg, .cseg определяют начало сегментов данных, EEPROM-памяти и кода соответственно. В исходном файле каждый из сегментов может быть представлен только в одном экземпляре. В случае если все эти директивы отсутствуют в программе, компилятор по умолчанию считает, что все операторы расположены в секции кода. Директивы .dseg, .eseg, .cseg
Синтаксис написания:
.dseg
.eseg
.cseg
Пример использования:
.dseg ;начало сегмента данных buffer: . byte 32 ;резервирование 32 байт под буфер в SRAM .cseg ;начало сегмента кода rjmp initial . string: .db «ATmega8»,0 ;строка, хранящаяся во FLASH-памяти .eseg ;начало сегмента EEPROM-памяти _var: .byte 2 ;резервирование 2-ух байт под переменную _var _cnst: .db 0xAA ;резервирование байта под переменную _cnst = 0xAA
Директива .org позволяет задать компилятору начальный адрес в пределах сегментов кода, данных и EEPROM-памяти. В случае применения в сегменте кода, директива определяет адрес размещения 16-разрядного слова программ. Директива .org
Синтаксис написания:
.org
Пример использования:
.equ SRAM_START = 0x60 .equ RAMEND = 0x045F .dseg ;начало сегмента данных .org SRAM_START ;резервирование 32 байт в SRAM под буфер, buffer: . byte 32 ;начиная с адреса 0x60 .cseg ;начало сегмента кода .org 0 ;вектор сброса по адресу 0 rjmp initial . .org 0x50 ;начало основной программы с адреса 0x50 initial: ldi temp,high(RAMEND) ;инициализация стека out SPH,temp ldi temp,low(RAMEND) out SPL,temp .
Директивы .macro, .endmacro (.endm), определяющие начало и конец макроса соответственно. Директивы .macro, .endmacro (.endm)
Синтаксис написания:
.macro
Пример использования:
Директива .listmac разрешает расширенный вывод текста макросов в файле листинга. В этом случае содержимое каждого макроопределения, встретившегося в программе, отображается целиком. Если директива не используется, то код в нутрии макроса не приводится. Директива .listmac
Синтаксис написания:
.listmac
Пример использования:
.listmac ;разрешить разворачивать текст макросов в файле листинга
Директивы .message, .warning, .error предназначены для вывода в окно сборки проекта дополнительной информации о ходе компиляции программы. Директива .message генерирует сообщение для строки, в которой был встречен ее вызов. Применение .warning приводит к выдачи предупреждения, а .error – к сообщению об ошибки. В последнем случае сборка проекта прекращается. Директивы .message, .warning, .error
Синтаксис написания:
.message «»
.warning «»
.error «»
Пример использования:
.message «Macros has been called here.» .warning «Too high frequency!» .error «Wrong macro argument!»
Группа директив условной компиляции .ifdef, .ifndef, .if, .else, elif, .endif используются для вставок программного кода в зависимости от различных условий. Директива .ifdef проверяют наличие объявления некоторого символьного имени. За директивой может следовать набор команд, которые будут подставлены в текст, если условие проверки “истина” (имя было объявлено).
Директива .ifndef противоположна .ifdef проверяет отсутствие объявления символьного имени. Директива .if производит подстановку кода, когда выполняется условие сравнения, указанное в качестве ее параметра. Команды, которые должны выполняться, в случае если условие директивы .if “ложно” – располагаются после директивы .else. Ветвление типа “если” — “то” может иметь несколько уровней вложения благодаря директиве .elif. Каждый блок проверки, начинающийся с .ifdef, .ifndef, .if, должен быть закрыт директивой .endif. Директивы if, .ifdef, .ifndef, .else, elif, .endif
Синтаксис написания:
.ifdef (или .ifndef )
.if
.else (или .elif < условие>)
.endif
Пример использования:
Перейти к следующей части: Содержимое заголовочного файла
Теги:
Котов Игорь Юрьевич
Опубликована: 2012 г.
0
Вознаградить Я собрал 0 1
Оценить статью
- Техническая грамотность
Источник: cxem.net