Синтаксис ассемблера: Ассемблер. Базовый синтаксис | Уроки Ассемблера

Содержание

Ассемблер. Базовый синтаксис | Уроки Ассемблера

  Обновл. 7 Дек 2020  | 

Программы на ассемблере могут быть разделены на три секции:

   секция data;

   секция bss;

   секция text.

Секции ассемблера

Секция data используется для объявления инициализированных данных или констант. Данные в этой секции НЕ могут быть изменены во время выполнения программы. Вы можете хранить константные значения и названия файлов в этой секции. Синтаксис объявления:

Секция bss используется для объявления переменных. Синтаксис объявления:

Секция text используется для хранения кода программы. Данная секция должна начинаться с объявления global_start, которое сообщает ядру, откуда нужно начинать выполнение программы. Синтаксис объявления:

section.text global _start _start:

section.text

   global _start

_start:

Комментарии

Комментарии в ассемблере должны начинаться с точки с запятой (

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

; эта программа выводит сообщение на экран

; эта программа выводит сообщение на экран

Так и на строке со стейтментом:

add eax, ebx ; добавляет ebx к eax

add eax, ebx     ; добавляет ebx к eax

Стейтменты

В ассемблере есть три вида стейтментов:

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

   Директивы ассемблера — сообщают программе об аспектах компиляции. Они не генерируют инструкции на машинном языке.

   Макросы — являются простым механизмом вставки кода.

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

[метка] mnemonic [операнды] [; комментарий]

[метка]   mnemonic   [операнды]   [; комментарий]

Базовая инструкция состоит из названия инструкции (mnemonic) и операндов (они же «параметры»). Вот примеры типичных стейтментов ассемблера:

INC COUNT ; выполняем инкремент переменной памяти COUNT MOV TOTAL, 48 ; перемещаем значение 48 в переменную памяти TOTAL ADD AH, BH ; добавляем содержимое регистра BH к регистру AH AND MASK1, 128 ; выполняем операцию AND с переменной MASK1 и 128 ADD MARKS, 10 ; добавляем 10 к переменной MARKS MOV AL, 10 ; перемещаем значение 10 в регистр AL

INC COUNT        ; выполняем инкремент переменной памяти COUNT

 

MOV TOTAL, 48    ; перемещаем значение 48 в переменную памяти TOTAL

  

ADD AH, BH       ; добавляем содержимое регистра BH к регистру AH

  

AND MASK1, 128   ; выполняем операцию AND с переменной MASK1 и 128

  

ADD MARKS, 10    ; добавляем 10 к переменной MARKS

MOV AL, 10       ; перемещаем значение 10 в регистр AL

Первая программа

Следующая программа на языке ассемблера выведет строку Hello, world! на экран:

section .text global _start ; необходимо для линкера (ld) _start: ; сообщает линкеру стартовую точку mov edx,len ; длина строки mov ecx,msg ; строка mov ebx,1 ; дескриптор файла (stdout) mov eax,4 ; номер системного вызова (sys_write) int 0x80 ; вызов ядра mov eax,1 ; номер системного вызова (sys_exit) int 0x80 ; вызов ядра section .data msg db 'Hello, world!', 0xa ; содержимое строки для вывода len equ $ - msg ; длина строки

section .text

   global _start    ; необходимо для линкера (ld)

_start:             ; сообщает линкеру стартовую точку

   mov edx,len     ; длина строки

   mov ecx,msg     ; строка

   mov ebx,1       ; дескриптор файла (stdout)

   mov eax,4       ; номер системного вызова (sys_write)

   int 0x80        ; вызов ядра

   mov eax,1       ; номер системного вызова (sys_exit)

   int 0x80        ; вызов ядра

 

section .data

msg db 'Hello, world!', 0xa  ; содержимое строки для вывода

len equ $ - msg              ; длина строки

Результат выполнения программы:

Hello, world!

Сборка программ

Убедитесь, что у вас установлен NASM. Запишите вашу программу в текстовом редакторе и сохраните её как hello.asm. Затем:

   откройте терминал;

   убедитесь, что вы находитесь в той же директории, в которой вы сохранили hello.asm;

   чтобы собрать программу, введите команду nasm -f elf hello.asm;

   если не было ошибок, то создастся объектный файл вашей программы под названием hello.o;

   чтобы ваш объектный файл прошел линкинг и создался исполняемый файл под названием

hello, введите команду ld -m elf_i386 -s -o hello hello.o;

   запустите программу командой ./hello.

Если всё прошло успешно, то вам выведется Hello, world!.

Если у вас нет возможности скомпилировать программу, например, у вас нет Linux и вы пока не хотите на него переходить, то можете использовать одну из следующих онлайн-IDE:

   TutorialsPoint

   JDoodle

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

all: nasm –f elf $(source) ld –m elf_i386 –s –o $(source) $(source).o rm $(source).o

all:

    nasm –f elf $(source)

    ld –m elf_i386 –s –o $(source) $(source).o

    rm $(source).o

Для сборки hello.asm выполните следующие действия:

   откройте терминал;

   убедитесь, что вы находитесь в той же директории, в которой вы сохранили hello.asm и Makefile;

   введите команду make source=hello.


Оценить статью:

Загрузка...

Поделиться в социальных сетях:

Лекция 4. Основы языка Ассемблер. Синтаксис языка Ассемблер. Ассемблерные вставки в языке C/C++.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

<метка:> <команда или директива> <операнды> <;комметарий>

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

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

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

asm

{

команда_1 //комментарий_1

команда_2 /* комментарий_2 */

------------------------

команда_n ; комментарий_n

}

Синтаксис языка Ассемблера - презентация онлайн

1. Синтаксис языка Ассемблера

2. Синтаксис языка Ассемблера

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

3. Синтаксис языка Ассемблера

Пример программы в машинном коде для некоторой
архитектуры
0403 1A00 0101 0001
0201 0201 0103 1604
0202 0501 060A 0703
02

4. Синтаксис языка Ассемблера

Пример программы в машинном коде
точка входа в программу
00:
01:
02:
03:
04:
07:
0A:
0D:
0F:
12:
14:
16:
04
03
1A
00
010100
010201
020101
0316
040202
0501
060A
070302
объявление переменных
команда «занести в регистр значение»
команда «сравнить регистр с ячейкой памяти»
команда «переход к команде по адресу по
условию “если больше”»
команда «домножить регистр на ячейку памяти»
команда «увеличить регистр на единицу»
команда «безусловный переход к команде по
адресу»
команда «занести ячейку памяти значение из
регистра»

5. Синтаксис языка Ассемблера

Виды предложений языка Ассемблера
Инструкции
Макрокоманды
Директивы
Комментарии

6. Синтаксис языка Ассемблера

Структура программы на языке Ассемблера
.data
; входные данные
x db 3
y dw 26
.data?
; выходные данные
z dd ?
.code
start:
mov AX, x
add AX, y
mov z, AX
end start

7. Синтаксис языка Ассемблера

Структура программы на языке Ассемблера
.data
; входные данные
x db 3
y dw 26
.data?
; выходные данные
z dd ?
.code
start:
mov AX, x
add AX, y
mov z, AX
end start

8. Синтаксис языка Ассемблера

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

9. Простейшее приложение

.486
.model flat, stdcall
option casemap: none
include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib
.data
title
message
db "Message",0
db "Hello, World!",0

10. Простейшее приложение

.486
.model flat, stdcall
option casemap: none
include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib
.data
title
message
db "Message",0
db "Hello, World!",0
Система
команд
процесора
• .286
• .386
• .486

11. Простейшее приложение

.486
.model flat, stdcall
option casemap: none
include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib
.data
title
message
db "Message",0
db "Hello, World!",0
модель
сегментации
памяти и
способ
передачи
параметров

12. Простейшее приложение

.486
.model flat, stdcall
option casemap: none
include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib
.data
title
message
db "Message",0
db "Hello, World!",0
сохранение
регистра
идентификаторов

13. Простейшее приложение

.486
.model flat, stdcall
option casemap: none
include
windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib
.data
title
message
db "Message",0
db "Hello, World!",0
подключение
заголовочных
файлов

14. Простейшее приложение

.486
.model flat, stdcall
option casemap: none
include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib
.data
title
message
db "Message",0
db "Hello, World!",0
определяет
типы данных
и константы,
используемые
операционной
системой

15. Простейшее приложение

.486
.model flat, stdcall
option casemap: none
include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib
.data
title
message
db "Message",0
db "Hello, World!",0
прототипы
функций по
работе с
пользователь
ским
интерфейсом
(окна, кнопки,
стандартные
диалоги)

16. Простейшее приложение

.486
.model flat, stdcall
option casemap: none
include windows.inc
include user32.inc
include
kernel32.inc
includelib user32.lib
includelib kernel32.lib
.data
title
message
db "Message",0
db "Hello, World!",0
прототипы
функций ядра
операционной
системы
(память,
процессы,
файлы)

17. Простейшее приложение

.486
.model flat, stdcall
option casemap: none
include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib
.data
title
message
db "Message",0
db "Hello, World!",0
gdi32.inc
прототипы
функций
интерфейса
графических
устройств

18. Простейшее приложение

.486
.model flat, stdcall
option casemap: none
include windows.inc
include user32.inc
include kernel32.inc
includelib
user32.lib
includelib kernel32.lib
.data
title
message
db "Message",0
db "Hello, World!",0
подключение
библиотеки, в
которой
находится
реализация
нужных
функций

19. Простейшее приложение

.486
.model flat, stdcall
option casemap: none
include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib
.data
title
message
db "Message",0
db "Hello, World!",0
сегмент
инициализированных
данных

20. Простейшее приложение

.486
.model flat, stdcall
option casemap: none
include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib
.data
title
message
db "Message",0
db "Hello, World!",0
.data?
сегмент
неинициализированных
данных

21. Простейшее приложение

.486
.model flat, stdcall
option casemap: none
include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib
.data
title
message
db "Message",0
db "Hello, World!",0
имя
переменной

22. Простейшее приложение

.486
.model flat, stdcall
option casemap: none
include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib
тип переменной
db – байт
dw – слово
dd – 2-е слово
dq – 4-е слово
.data
title
message
db
"Message",0
db "Hello, World!",0

23. Простейшее приложение

.486
.model flat, stdcall
option casemap: none
include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib
.data
title
message
db "Message",0
db "Hello, World!",0
значение
переменной

24. Простейшее приложение

a db 105
b db 415
c dw 415
include windows.inc
include user32.inc
d dw 415
include kernel32.inc
arr db 1,2,3,4,5
includelib user32.lib
includelib kernel32.lib
s1 db “abc”
.data
s2 db “abc”,0
title
db "Message",0
message db "Hello, World!",0
s3 db “a”,32,”c”,0
.486
.model flat, stdcall
option casemap: none

25. Простейшее приложение

.486
.model flat, stdcall
option casemap: none
arr1 dw 1,2,5
dup(0),6,7,3
dup(9)
include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib
.data
title
message
db "Message",0
db "Hello, World!",0

26. Простейшее приложение

.486
.model flat, stdcall
option casemap: none
include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib
.data
title
message
a db ?
b dw 7 dup(?)
d dd
e dq ? dup(?)
f db dup(?)
g dw 56
h dd 10 dup(4)
db "Message",0
db "Hello, World!",0

27. Простейшее приложение

.code
start:
push
push
push
push
call
MB_OK
offset title
offset message
0
MessageBox
push 0
call ExitProcess
end start

28. Простейшее приложение

начало
сегмента кода
.code
start:
push
push
push
push
call
MB_OK
offset title
offset message
0
MessageBox
push 0
call ExitProcess
end start

29. Простейшее приложение

конец
программы
.code
start:
push
push
push
push
call
MB_OK
offset title
offset message
0
MessageBox
push 0
call ExitProcess
end
start

30. Простейшее приложение

точка входа в
программу
.code
start:
push
push
push
push
call
MB_OK
offset title
offset message
0
MessageBox
push 0
call ExitProcess
end
start

31. Синтаксис языка Ассемблера

Формат инструкции или макрокоманды
[метка:] КОП [список операндов]
Формат директивы
[имя] директива [список операндов]

32. Синтаксис языка Ассемблера

Операнды





обозначения регистров;
числовые и текстовые константы;
метки и имена переменных;
знаки операций;
зарезервированные слова.

33. Синтаксис языка Ассемблера

Машинные команды могут
– не иметь операндов
ret
– иметь один операнд
inc EAX
– иметь два операнда
add EBX, 1

34. Синтаксис языка Ассемблера

Виды операндов
Регистровый операнд
обозначает регистр процессора (имя регистра)
Адресный операнд
обозначает адрес некоторой ячейки памяти
Непосредственный операнд
значение, которое указывается непосредственно в
команде

35. Синтаксис языка Ассемблера

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

36. Синтаксис языка Ассемблера

Полное выражение для вычисления адреса ячейки
памяти при косвенной адресации:
смещение
индексный
регистр
1, 2, 4 или 8
базовый
регистр
регистр + масштаб * регистр + число

37. Синтаксис языка Ассемблера

Виды косвенной адресации определяются составом
выражения для вычисления адреса, например:
Косвенная базовая
inc [EBX]
Косвенная базовая со смещением
inc [EBX + 10]
Косвенная базовая индексная со смещением
inc [EBX + 4*ESI + 10]
и т.д.

38. Синтаксис языка Ассемблера

Большинство машинных команд имеют два операнда,
один из которых является источником,
другой – приемником.
Допустимы следующие сочетания операндов:
Приемник
Источник
Регистровый операнд
Регистровый операнд
Регистровый операнд
Адресный операнд
Адресный операнд
Регистровый операнд
Регистровый операнд
Непосредственный операнд
Адресный операнд
Непосредственный операнд

Информационные технологии - Синтаксис ассемблера

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

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

Допустимые символы:

1) все латинские буквы: A – Z, a – z;

2) цифры от 0 до 9;

3) знаки? @, $, &;

4) разделители.

Лексемами являются следующие.

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

2. Цепочки символов – последовательности символов, заключенные в одинарные или двойные кавычки.

3. Целые числа.

Возможные типы операторов ассемблера.

1. Арифметические операторы. К ним относятся:

1) унарные «+» и «—»;

2) бинарные «+» и «—»;

3) умножения «*»;

4) целочисленного деления «/»; 5) получения остатка от деления «mod».

2. Операторы сдвига выполняют сдвиг выражения на указанное количество разрядов.

3. Операторы сравнения (возвращают значение «истина» или «ложь») предназначены для формирования логических выражений.

4. Логические операторы выполняют над выражениями побитовые операции.

5. Индексный оператор [].

6. Оператор переопределения типа ptr применяется для переопределения или уточнения типа метки или переменной, определяемых выражением.

7. Оператор переопределения сегмента «:» (двоеточие) заставляет вычислять физический адрес относительно конкретно задаваемой сегментной составляющей.

8. Оператор именования типа структуры «.» (точка) также заставляет транслятор производить определенные вычисления, если он встречается в выражении.

9. Оператор получения сегментной составляющей адреса выражения seg возвращает физический адрес сегмента для выражения, в качестве которого могут выступать метка, переменная, имя сегмента, имя группы или некоторое символическое имя.

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


Atmel AVR Assembler

Atmel AVR Assembler

Содержание:

Исходные коды

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

Строка кода не должна быть длиннее 120 символов.

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

Входная строка может иметь одну из четырёх форм:

[метка:] директива [операнды] [Комментарий]
[метка:] инструкция [операнды] [Комментарий]
Комментарий
Пустая строка

Комментарий имеет следующую форму:

; [Текст]

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

Примеры:

label:════ .EQU var1=100 ; Устанавливает var1 равным 100 (Это директива)
══════════ .EQU var2=200 ; Устанавливает var2 равным 200

test:═════ rjmp test════ ; Бесконечный цикл (Это инструкция)
════════════════════════ ; Строка с одним только комментарием

════════════════════════ ; Ещё одна строка с комментарием

Компилятор не требует чтобы метки, директивы, комментарии или инструкции находились в определённой колонке строки.

═Инструкции процессоров AVR

Ниже приведен набор команд процессоров AVR, более детальное описание их можно найти в AVR Data Book.

Арифметические и логические инструкции

Мнемоника Операнды Описание Операция Флаги Циклы
ADD═ Rd,Rr═ Суммирование без переноса Rd = Rd + Rr═ Z,C,N,V,H,S═ 1
ADC Rd,Rr Суммирование с переносом Rd = Rd + Rr + C Z,C,N,V,H,S 1
SUB Rd,Rr Вычитание без переноса Rd = Rd - Rr Z,C,N,V,H,S 1
SUBI Rd,K8 Вычитание константы Rd = Rd - K8 Z,C,N,V,H,S 1
SBC Rd,Rr Вычитание с переносом Rd = Rd - Rr - C Z,C,N,V,H,S 1
SBCI Rd,K8 Вычитание константы с переносом Rd = Rd - K8 - C Z,C,N,V,H,S 1
AND Rd,Rr Логическое И Rd = Rd ╥ Rr Z,N,V,S═ 1
ANDI Rd,K8 Логическое И с константой Rd = Rd ╥ K8 Z,N,V,S 1
OR Rd,Rr Логическое ИЛИ Rd = Rd V Rr Z,N,V,S 1
ORI Rd,K8 Логическое ИЛИ с константой Rd = Rd V K8 Z,N,V,S 1
EOR Rd,Rr Логическое исключающее ИЛИ Rd = Rd EOR Rr Z,N,V,S 1
COM Rd Побитная Инверсия Rd = $FF - Rd Z,C,N,V,S 1
NEG Rd Изменение знака (Доп. код) Rd = $00 - Rd Z,C,N,V,H,S 1
SBR Rd,K8 Установить бит (биты) в регистре Rd = Rd V K8 Z,C,N,V,S 1
CBR Rd,K8 Сбросить бит (биты) в регистре Rd = Rd ╥ ($FF - K8) Z,C,N,V,S 1
INC Rd Инкрементировать значение регистра Rd = Rd + 1 Z,N,V,S 1
DEC Rd Декрементировать значение регистра Rd = Rd -1 Z,N,V,S 1
TST Rd Проверка на ноль либо отрицательность Rd = Rd ╥ Rd Z,C,N,V,S 1
CLR Rd Очистить регистр Rd = 0 Z,C,N,V,S 1
SER Rd Установить регистр Rd = $FF None 1
ADIW Rdl,K6 Сложить константу и слово Rdh:Rdl = Rdh:Rdl + K6═ Z,C,N,V,S 2
SBIW Rdl,K6 Вычесть константу из слова Rdh:Rdl = Rdh:Rdl - K 6 Z,C,N,V,S 2
MUL Rd,Rr Умножение чисел без знака R1:R0 = Rd * Rr Z,C 2
MULS Rd,Rr Умножение чисел со знаком R1:R0 = Rd * Rr Z,C 2
MULSU Rd,Rr Умножение числа со знаком с числом без знака R1:R0 = Rd * Rr Z,C 2
FMUL Rd,Rr Умножение дробных чисел без знака R1:R0 = (Rd * Rr) << 1 Z,C 2
FMULS Rd,Rr Умножение дробных чисел со знаком R1:R0 = (Rd *Rr) << 1 Z,C 2
FMULSU Rd,Rr Умножение дробного числа со знаком с числом без знака R1:R0 = (Rd * Rr) << 1 Z,C 2

Инструкции ветвления

Мнемоника Операнды Описание Операция Флаги Циклы
RJMP k Относительный переход PC = PC + k +1 None 2
IJMP Нет Косвенный переход на (Z) PC = Z None 2
EIJMP Нет Расширенный косвенный переход на (Z) STACK = PC+1, PC(15:0) = Z, PC(21:16) = EIND None 2
JMP k Переход PC = k None 3
RCALL k Относительный вызов подпрограммы STACK = PC+1, PC = PC + k + 1 None 3/4*
ICALL Нет Косвенный вызов (Z) STACK = PC+1, PC = Z═ None 3/4*
EICALL Нет Расширенный косвенный вызов (Z) STACK = PC+1, PC(15:0) = Z, PC(21:16) =EIND None 4*
CALL k Вызов подпрограммы STACK = PC+2, PC = k None 4/5*
RET Нет Возврат из подпрограммы PC = STACK None 4/5*
RETI Нет Возврат из прерывания PC = STACK I 4/5*
CPSE Rd,Rr Сравнить, пропустить если равны═ if (Rd ==Rr) PC = PC 2 or 3 None 1/2/3
CP Rd,Rr Сравнить Rd -Rr Z,C,N,V,H,S 1
CPC Rd,Rr Сравнить с переносом Rd - Rr - C Z,C,N,V,H,S 1
CPI Rd,K8 Сравнить с константой Rd - K Z,C,N,V,H,S 1
SBRC Rr,b Пропустить если бит в регистре очищен if(Rr(b)==0) PC = PC + 2 or 3 None 1/2/3
SBRS Rr,b Пропустить если бит в регистре установлен if(Rr(b)==1) PC = PC + 2 or 3 None 1/2/3
SBIC P,b Пропустить если бит в порту очищен if(I/O(P,b)==0) PC = PC + 2 or 3 None 1/2/3
SBIS P,b Пропустить если бит в порту установлен if(I/O(P,b)==1) PC = PC + 2 or 3 None 1/2/3
BRBC s,k Перейти если флаг в SREG очищен if(SREG(s)==0) PC = PC + k + 1 None 1/2
BRBS s,k Перейти если флаг в SREG установлен if(SREG(s)==1) PC = PC + k + 1 None 1/2
BREQ k Перейти если равно if(Z==1) PC = PC + k + 1 None 1/2
BRNE k Перейти если не равно if(Z==0) PC = PC + k + 1 None 1/2
BRCS k Перейти если перенос установлен if(C==1) PC = PC + k + 1 None 1/2
BRCC k Перейти если перенос очищен if(C==0) PC = PC + k + 1 None 1/2
BRSH k Перейти если равно или больше if(C==0) PC = PC + k + 1 None 1/2
BRLO k Перейти если меньше if(C==1) PC = PC + k + 1 None 1/2
BRMI k Перейти если минус if(N==1) PC = PC + k + 1 None 1/2
BRPL k Перейти если плюс if(N==0) PC = PC + k + 1 None 1/2
BRGE k Перейти если больше или равно (со знаком) if(S==0) PC = PC + k + 1 None 1/2
BRLT k Перейти если меньше (со знаком) if(S==1) PC = PC + k + 1 None 1/2
BRHS k Перейти если флаг внутреннего переноса установлен if(H==1) PC = PC + k + 1 None 1/2
BRHC k Перейти если флаг внутреннего переноса очищен if(H==0) PC = PC + k + 1 None 1/2
BRTS k Перейти если флаг T установлен if(T==1) PC = PC + k + 1 None 1/2
BRTC k Перейти если флаг T очищен if(T==0) PC = PC + k + 1 None 1/2
BRVS k Перейти если флаг переполнения установлен if(V==1) PC = PC + k + 1 None 1/2
BRVC k Перейти если флаг переполнения очищен if(V==0) PC = PC + k + 1 None 1/2
BRIE k Перейти если прерывания разрешены if(I==1) PC = PC + k + 1 None 1/2
BRID k Перейти если прерывания запрещены if(I==0) PC = PC + k + 1 None 1/2

* Для операций доступа к данным количество циклов указано при условии доступа к внутренней памяти данных, и не корректно при работе с внешним ОЗУ. Для инструкций CALL, ICALL, EICALL, RCALL, RET и RETI, необходимо добавить три цикла плюс по два цикла для каждого ожидания в контроллерах с PC меньшим 16 бит (128KB памяти программ). Для устройств с памятью программ свыше 128KB , добавьте пять циклов плюс по три цикла на каждое ожидание.

Инструкции передачи данных

Мнемоника Операнды Описание Операция Флаги Циклы
MOV Rd,Rr Скопировать регистр Rd = Rr None 1
MOVW Rd,Rr Скопировать пару регистров Rd+1:Rd = Rr+1:Rr, r,d even None 1
LDI Rd,K8 Загрузить константу Rd = K None 1
LDS Rd,k Прямая загрузка Rd = (k) None 2*
LD Rd,X Косвенная загрузка Rd = (X) None 2*
LD Rd,X+ Косвенная загрузка с пост-инкрементом Rd = (X), X=X+1 None 2*
LD Rd,-X Косвенная загрузка с пре-декрементом X=X-1, Rd = (X) None 2*
LD Rd,Y Косвенная загрузка Rd = (Y) None 2*
LD Rd,Y+ Косвенная загрузка с пост-инкрементом Rd = (Y), Y=Y+1 None 2*
LD Rd,-Y Косвенная загрузка с пре-декрементом Y=Y-1, Rd = (Y) None 2*
LDD Rd,Y+q Косвенная загрузка с замещением Rd = (Y+q) None 2*
LD Rd,Z Косвенная загрузка Rd = (Z) None 2*
LD Rd,Z+ Косвенная загрузка с пост-инкрементом Rd = (Z), Z=Z+1 None 2*
LD Rd,-Z Косвенная загрузка с пре-декрементом Z=Z-1, Rd = (Z) None 2*
LDD Rd,Z+q Косвенная загрузка с замещением Rd = (Z+q) None 2*
STS k,Rr Прямое сохранение (k) = Rr None 2*
ST X,Rr Косвенное сохранение (X) = Rr None 2*
ST X+,Rr Косвенное сохранение с пост-инкрементом (X) = Rr, X=X+1 None 2*
ST -X,Rr Косвенное сохранение с пре-декрементом X=X-1, (X)=Rr None 2*
ST Y,Rr Косвенное сохранение (Y) = Rr None 2*
ST Y+,Rr Косвенное сохранение с пост-инкрементом (Y) = Rr, Y=Y+1 None 2
ST -Y,Rr Косвенное сохранение с пре-декрементом Y=Y-1, (Y) = Rr None 2
ST Y+q,Rr Косвенное сохранение с замещением (Y+q) = Rr None 2
ST Z,Rr Косвенное сохранение (Z) = Rr None 2
ST Z+,Rr Косвенное сохранение с пост-инкрементом (Z) = Rr, Z=Z+1 None 2
ST -Z,Rr Косвенное сохранение с пре-декрементом Z=Z-1, (Z) = Rr None 2
ST Z+q,Rr Косвенное сохранение с замещением (Z+q) = Rr None 2
LPM Нет Загрузка из программной памяти R0 = (Z) None 3
LPM Rd,Z Загрузка из программной памяти Rd = (Z) None 3
LPM Rd,Z+ Загрузка из программной памяти с пост-инкрементом Rd = (Z), Z=Z+1 None 3
ELPM Нет Расширенная загрузка из программной памяти R0 = (RAMPZ:Z) None 3
ELPM Rd,Z Расширенная загрузка из программной памяти Rd = (RAMPZ:Z) None 3
ELPM Rd,Z+ Расширенная загрузка из программной памяти с пост-инкрементом Rd = (RAMPZ:Z), Z = Z+1 None 3
SPM Нет Сохранение в программной памяти (Z) = R1:R0 None -
ESPM Нет Расширенное сохранение в программной памяти (RAMPZ:Z) = R1:R0 None -
IN Rd,P Чтение порта Rd = P None 1
OUT P,Rr Запись в порт P = Rr None 1
PUSH Rr Занесение регистра в стек STACK = Rr None 2
POP Rd Извлечение регистра из стека Rd = STACK None 2

* Для операций доступа к данным количество циклов указано при условии доступа к внутренней памяти данных, и не корректно при работе с внешним ОЗУ. Для инструкций LD, ST, LDD, STD, LDS, STS, PUSH и POP, необходимо добавить один цикл плюс по одному циклу для каждого ожидания.

Инструкции работы с битами

Мнемоника Операнды Описание Операция Флаги Циклы
LSL Rd Логический сдвиг влево Rd(n+1)=Rd(n), Rd(0)=0, C=Rd(7) Z,C,N,V,H,S 1
LSR Rd Логический сдвиг вправо Rd(n)=Rd(n+1), Rd(7)=0, C=Rd(0) Z,C,N,V,S 1
ROL Rd Циклический сдвиг влево через C Rd(0)=C, Rd(n+1)=Rd(n), C=Rd(7) Z,C,N,V,H,S 1
ROR Rd Циклический сдвиг вправо через C Rd(7)=C, Rd(n)=Rd(n+1), C=Rd(0) Z,C,N,V,S 1
ASR Rd Арифметический сдвиг вправо Rd(n)=Rd(n+1), n=0,...,6 Z,C,N,V,S 1
SWAP Rd Перестановка тетрад Rd(3..0) = Rd(7..4), Rd(7..4) = Rd(3..0) None 1
BSET═ s Установка флага SREG(s) = 1 SREG(s) 1
BCLR s Очистка флага SREG(s) = 0 SREG(s) 1
SBI P,b Установить бит в порту I/O(P,b) = 1 None 2
CBI P,b Очистить бит в порту I/O(P,b) = 0 None 2
BST Rr,b Сохранить бит из регистра в T T = Rr(b) T 1
BLD Rd,b Загрузить бит из T в регистр Rd(b) = T None 1
SEC Нет Установить флаг переноса C =1 C 1
CLC Нет Очистить флаг переноса C = 0 C 1
SEN Нет Установить флаг отрицательного числа N = 1 N 1
CLN Нет Очистить флаг отрицательного числа N = 0 N 1
SEZ Нет Установить флаг нуля Z = 1 Z 1
CLZ Нет Очистить флаг нуля Z = 0 Z 1
SEI Нет Установить флаг прерываний I = 1 I 1
CLI Нет Очистить флаг прерываний I = 0 I 1
SES Нет Установить флаг числа со знаком S = 1 S 1
CLN Нет Очистить флаг числа со знаком S = 0 S 1
SEV Нет Установить флаг переполнения V = 1 V 1
CLV Нет Очистить флаг переполнения V = 0 V 1
SET Нет Установить флаг T T = 1 T 1
CLT Нет Очистить флаг T T = 0 T 1
SEH Нет Установить флаг внутреннего переноса H = 1 H 1
CLH Нет Очистить флаг внутреннего переноса H = 0 H 1
NOP Нет Нет операции Нет None 1
SLEEP Нет Спать (уменьшить энергопотребление) Смотрите описание инструкции None 1
WDR Нет Сброс сторожевого таймера Смотрите описание инструкции None 1


Ассемблер не различает регистр символов.

Операнды могут быть таких видов:

Rd: Результирующий (и исходный) регистр в регистровом файле
Rr: Исходный регистр в регистровом файле
b: Константа (3 бита), может быть константное выражение
s: Константа (3 бита), может быть константное выражение
P: Константа (5-6 бит), может быть константное выражение
K6; Константа (6 бит), может быть константное выражение
K8: Константа (8 бит), может быть константное выражение
k: Константа (размер зависит от инструкции), может быть константное выражение
q: Константа (6 бит), может быть константное выражение
Rdl:═ R24, R26, R28, R30. Для инструкций ADIW и SBIW
X,Y,Z: Регистры косвенной адресации (X=R27:R26, Y=R29:R28, Z=R31:R30)

Директивы ассемблера

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

Все директивы предваряются точкой.

BYTE - Зарезервировать байты в ОЗУ

Директива BYTE резервирует байты в ОЗУ. Если вы хотите иметь возможность ссылаться на выделенную область памяти, то директива BYTE должна быть предварена меткой. Директива принимает один обязательный параметр, который указывает количество выделяемых байт. Эта директива может использоваться только в сегменте данных(смотреть директивы CSEG и DSEG). Выделенные байты не инициализируются.

Синтаксис:
МЕТКА: .BYTE выражение

Пример:
.DSEG
var1:═══ .BYTE 1═══════════ ; резервирует 1 байт для var1
table:══ .BYTE tab_size════ ; резервирует tab_size байт

.CSEG
════════ ldi r30,low(var1)═ ; Загружает младший байт регистра Z
════════ ldi r31,high(var1) ; Загружает старший байт регистра Z
════════ ld r1,Z═══════════ ; Загружает VAR1 в регистр 1

CSEG - Программный сегмент

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

Синтаксис:
.CSEG

Пример:
.DSEG══════════════════════ ; Начало сегмента данных
vartab: .BYTE 4════════════ ; Резервирует 4 байта в ОЗУ

.CSEG══════════════════════ ; Начало кодового сегмента
const:═ .DW 2══════════════ ; Разместить константу 0x0002 в памяти программ
═══════ mov r1,r0══════════ ; Выполнить действия

DB - Определить байты во флэш или EEPROM

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

Параметры передаваемые директиве - это последовательность выражений разделённых запятыми. Каждое выражение должно быть или числом в диапазоне (-128..255), или в результате вычисления должно давать результат в этом же диапазоне, в противном случае число усекается до байта, причём БЕЗ выдачи предупреждений.

Если директива получает более одного параметра и текущим является программный сегмент, то параметры упаковываются в слова (первый параметр - младший байт), и если число параметров нечётно, то последнее выражение будет усечено до байта и записано как слово со старшим байтом равным нулю, даже если далее идет ещё одна директива DB.

Синтаксис:
МЕТКА:═ .DB список_выражений

Пример:
.CSEG
consts: .DB 0, 255, 0b01010101, -128, 0xaa

.ESEG
const2: .DB 1,2,3

DEF - Назначить регистру символическое имя

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

Синтаксис:
.DEF Символическое_имя = Регистр

Пример:
.DEF temp=R16
.DEF ior=R0

.CSEG
═ldi temp,0xf0═ ; Загрузить 0xf0 в регистр temp (R16)
═in ior,0x3f═ ; Прочитать SREG в регистр ior (R0)
═eor temp,ior═ ; Регистры temp и ior складываются по исключающему или

DEVICE - Определить устройство для которого компилируется программа

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

Синтаксис:
.DEVICE AT90S1200 |AT90S2313 | AT90S2323 | AT90S2333 | AT90S2343 | AT90S4414 | AT90S4433 | AT90S4434 | AT90S8515 | AT90S8534 | AT90S8535 | ATtiny11 | ATtiny12 | ATtiny22 | ATmega603 | ATmega103

Пример:
.DEVICE AT90S1200═ ; Используется AT90S1200

.CSEG
═══════ push r30══ ; Эта инструкция вызовет предупреждение
══════════════════ ; поскольку AT90S1200 её не имеет

DSEG - Сегмент данных

Директива DSEG определяет начало сегмента данных. Исходный файл может состоять из нескольких сегментов данных, которые объединяются в один сегмент при компиляции. Сегмент данных обычно состоит только из директив BYTE и меток. Сегменты данных имеют свои собственные побайтные счётчики положения. Директива ORG может быть использована для размещения переменных в необходимом месте ОЗУ. Директива не имеет параметров.

Синтаксис:
.DSEG═

Пример:
.DSEG═══════════════════════ ; Начало сегмента данных
var1:═ .BYTE 1══════════════ ; зарезервировать 1 байт для var1
table:═ .BYTE tab_size══════ ; зарезервировать tab_size байт.

.CSEG
═══════ ldi r30,low(var1)═══ ; Загрузить младший байт регистра Z
═══════ ldi r31,high(var1)══ ; Загрузить старший байт регистра Z
═══════ ld r1,Z═════════════ ; Загрузить var1 в регистр r1

DW - Определить слова во флэш или EEPROM

 

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

Параметры передаваемые директиве - это последовательность выражений разделённых запятыми. Каждое выражение должно быть или числом в диапазоне (-32768..65535), или в результате вычисления должно давать результат в этом же диапазоне, в противном случае число усекается до слова, причем БЕЗ выдачи предупреждений.

Синтаксис:
МЕТКА: .DW expressionlist

Пример:
.CSEG
varlist:═ .DW 0, 0xffff, 0b1001110001010101, -32768, 65535

.ESEG
eevarlst: .DW 0,0xffff,10

ENDMACRO - Конец макроса

Директива определяет конец макроопределения, и не принимает никаких параметров. Для информации по определению макросов смотрите директиву MACRO.

Синтаксис:
.ENDMACRO═

Пример:
.MACRO SUBI16══════════════ ; Начало определения макроса
═══════ subi r16,low(@0)═══ ; Вычесть младший байт первого параметра
═══════ sbci r17,high(@0)══ ; Вычесть старший байт первого параметра
.ENDMACRO

EQU - Установить постоянное выражение

Директива EQU присваивает метке значение. Эта метка может позднее использоваться в выражениях. Метка которой присвоено значение данной директивой не может быть переназначена и её значение не может быть изменено.

Синтаксис:
.EQU метка = выражение

Пример:
.EQU io_offset = 0x23
.EQU porta════ = io_offset + 2

.CSEG════════════════ ; Начало сегмента данных
═══════ clr r2═══════ ; Очистить регистр r2
═══════ out porta,r2═ ; Записать в порт A

ESEG - Сегмент EEPROM

Директива ESEG определяет начало сегмента EEPROM. Исходный файл может состоять из нескольких сегментов EEPROM, которые объединяются в один сегмент при компиляции. Сегмент EEPROM обычно состоит только из директив DB, DW и меток. Сегменты EEPROM имеют свои собственные побайтные счётчики положения. Директива ORG может быть использована для размещения переменных в необходимом месте EEPROM. Директива не имеет параметров.

Синтаксис:
.ESEG═══

Пример:
.DSEG═══════════════════ ; Начало сегмента данных
var1:══ .BYTE 1═════════ ; зарезервировать 1 байт для var1
table:═ .BYTE tab_size══ ; зарезервировать tab_size байт.

.ESEG
eevar1: .DW 0xffff═══════ ; проинициализировать 1 слово в EEPROM

EXIT - Выйти из файла

Встретив директиву EXIT компилятор прекращает компиляцию данного файла. Если директива использована во вложенном файле (см. директиву INCLUDE), то компиляция продолжается со строки следующей после директивы INCLUDE. Если же файл не является вложенным, то компиляция прекращается.

Синтаксис:
.EXIT

Пример:
.EXIT═ ; Выйти из данного файла

INCLUDE - Вложить другой файл

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

Синтаксис:
.INCLUDE "имя_файла"

Пример:
; файл iodefs.asm:
.EQU sreg══ = 0x3f════ ; Регистр статуса
.EQU sphigh = 0x3e════ ; Старший байт указателя стека
.EQU splow═ = 0x3d════ ; Младший байт указателя стека

; файл incdemo.asm
.INCLUDE iodefs.asm═══ ; Вложить определения портов
═══════ in r0,sreg════ ; Прочитать регистр статуса

LIST - Включить генерацию листинга

Директива LIST указывает компилятору на необходимость создания листинга. Листинг представляет из себя комбинацию ассемблерного кода, адресов и кодов операций. По умолчанию генерация листинга включена, однако данная директива используется совместно с директивой NOLIST для получения листингов отдельных частей исходных файлов.

Синтаксис:
.LIST

Пример:
.NOLIST═══════════════ ; Отключить генерацию листинга
.INCLUDE "macro.inc"══ ; Вложенные файлы не будут
.INCLUDE "const.def"══ ; отображены в листинге
.LIST═════════════════ ; Включить генерацию листинга

LISTMAC - Включить разворачивание макросов в листинге

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

Синтаксис:
.LISTMAC

Пример:
.MACRO MACX════════ ; Определение макроса
═══════ add═ r0,@0═ ; Тело макроса
═══════ eor═ r1,@1═
.ENDMACRO══════════ ; Конец макроопределения

.LISTMAC═══════════ ; Включить разворачивание макросов
═══════ MACX r2,r1═ ; Вызов макроса (в листинге будет показано тело макроса)

MACRO - Начало макроса

С директивы MACRO начинается определение макроса. В качестве параметра директиве передаётся имя макроса. При встрече имени макроса позднее в тексте программы, компилятор заменяет это имя на тело макроса. Макрос может иметь до 10 параметров, к которым в его теле обращаются через @[email protected] При вызове параметры перечисляются через запятые. Определение макроса заканчивается директивой ENDMACRO.

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

Синтаксис:
.MACRO макроимя

Пример:
.MACRO SUBI16══════════════════ ; Начало макроопределения
═══════ subi @1,low(@0)════════ ; Вычесть младший байт параметра 0 из параметра 1
═══════ sbci @2,high(@0)═══════ ; Вычесть старший байт параметра 0 из параметра 2
.ENDMACRO══════════════════════ ; Конец макроопределения

.CSEG══════════════════════════ ; Начало программного сегмента
═══════ SUBI16 0x1234,r16,r17══ ; Вычесть 0x1234 из r17:r16

NOLIST - Выключить генерацию листинга

Директива NOLIST указывает компилятору на необходимость прекращения генерации листинга. Листинг представляет из себя комбинацию ассемблерного кода, адресов и кодов операций. По умолчанию генерация листинга включена, однако может быть отключена данной директивой. Кроме того данная директива может быть использована совместно с директивой LIST для получения листингов отдельных частей исходных файлов

Синтаксис:
.NOLIST

Пример:
.NOLIST═══════════════ ; Отключить генерацию листинга
.INCLUDE "macro.inc"══ ; Вложенные файлы не будут
.INCLUDE "const.def"══ ; отображены в листинге
.LIST═════════════════ ; Включить генерацию листинга

ORG - Установить положение в сегменте

Директива ORG устанавливает счётчик положения равным заданной величине, которая передаётся как параметр. Для сегмента данных она устанавливает счётчик положения в SRAM (ОЗУ), для сегмента программ это программный счётчик, а для сегмента EEPROM это положение в EEPROM. Если директиве предшествует метка (в той же строке) то метка размещается по адресу указанному в параметре директивы. Перед началом компиляции программный счётчик и счётчик EEPROM равны нулю, а счётчик ОЗУ равен 32 (поскольку адреса 0-31 заняты регистрами). Обратите внимание что для ОЗУ и EEPROM используются побайтные счётчики а для программного сегмента - пословный.

Синтаксис:
.ORG выражение

Пример:
.DSEG═══════════════ ; Начало сегмента данных

.ORG 0x37═══════════ ; Установить адрес SRAM равным 0x37
variable: .BYTE 1═══ ; Зарезервировать байт по адресу 0x37H

.CSEG
.ORG 0x10═══════════ ; Установить программный счётчик равным 0x10
═════════ mov r0,r1═ ; Данная команда будет размещена по адресу 0x10

SET - Установить переменный символический эквивалент выражения

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

Синтаксис:
.SET имя = выражение

Пример:
.SET io_offset = 0x23
.SET porta════ = io_offset + 2

.CSEG════════════════ ; Начало кодового сегмента
═══════ clr r2═══════ ; Очистить регистр 2
═══════ out porta,r2═ ; Записать в порт A

Выражения

Компилятор позволяет использовать в программе выражения которые могут состоять операндов, знаков операций и функций. Все выражения являются 32-битными.

Операнды

Могут быть использованы следующие операнды:

  • Метки определённые пользователем (дают значение своего положения).
  • Переменные определённые директивой SET
  • Константы определённые директивой EQU
  • Числа заданные в формате:
    • Десятичном (принят по умолчанию): 10, 255
    • Шестнадцатеричном (два варианта записи): 0x0a, $0a, 0xff, $ff
    • Двоичном: 0b00001010, 0b11111111
    • Восьмеричном (начинаются с нуля): 010, 077
  • PC - текущее значение программного счётчика (Programm Counter)

Операции

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

Логическое отрицание

Символ: !
Описание: Возвращает 1 если выражение равно 0, и наоборот
Приоритет: 14
Пример: ldi r16, !0xf0═ ; В r16 загрузить 0x00

Побитное отрицание

Символ: ~
Описание: Возвращает выражение в котором все биты проинвертированы
Приоритет: 14
Пример: ldi r16, ~0xf0═ ; В r16 загрузить 0x0f

Минус

Символ: -
Описание: Возвращает арифметическое отрицание выражения
Приоритет: 14
Пример: ldi r16,-2═ ; Загрузить -2(0xfe) в r16

Умножение

Символ: *
Описание: Возвращает результат умножения двух выражений
Приоритет: 13
Пример: ldi r30, label*2

Деление

Символ: /
Описание: Возвращает целую часть результата деления левого выражения на правое
Приоритет: 13
Пример: ldi r30, label/2

Суммирование

Символ: +
Описание: Возвращает сумму двух выражений
Приоритет: 12
Пример: ldi r30, c1+c2

Вычитание

Символ: -
Описание: Возвращает результат вычитания правого выражения из левого
Приоритет: 12
Пример: ldi r17, c1-c2

Сдвиг влево

Символ: <<
Описание: Возвращает левое выражение сдвинутое влево на число бит указанное справа
Приоритет: 11
Пример: ldi r17, 1<<bitmask═ ; В r17 загрузить 1 сдвинутую влево bitmask раз

Сдвиг вправо

Символ: >>
Описание: Возвращает левое выражение сдвинутое вправо на число бит указанное справа
Приоритет: 11
Пример: ldi r17, c1>>c2═ ; В r17 загрузить c1 сдвинутое вправо c2 раз

Меньше чем

Символ: <
Описание: Возвращает 1 если левое выражение меньше чем правое (учитывается знак), и 0 в противном случае
Приоритет: 10
Пример: ori r18, bitmask*(c1<c2)+1

Меньше или равно

Символ: <=
Описание: Возвращает 1 если левое выражение меньше или равно чем правое (учитывается знак), и 0 в противном случае
Приоритет: 10
Пример: ori r18, bitmask*(c1<=c2)+1

Больше чем

Символ: >
Описание: Возвращает 1 если левое выражение больше чем правое (учитывается знак), и 0 в противном случае
Приоритет: 10
Пример: ori r18, bitmask*(c1>c2)+1

Больше или равно

Символ: >=
Описание: Возвращает 1 если левое выражение больше или равно чем правое (учитывается знак), и 0 в противном случае
Приоритет: 10
Пример: ori r18, bitmask*(c1>=c2)+1

Равно

Символ: ==
Описание: Возвращает 1 если левое выражение равно правому (учитывается знак), и 0 в противном случае
Приоритет: 9
Пример: andi r19, bitmask*(c1==c2)+1

Не равно

Символ: !=
Описание: Возвращает 1 если левое выражение не равно правому (учитывается знак), и 0 в противном случае
Приоритет: 9
Пример: .c2)

Побитное ИЛИ

Символ: |
Описание: Возвращает результат побитового ИЛИ выражений
Приоритет: 6
Пример: ldi r18, Low(c1|c2)

Логическое И

Символ: &&
Описание: Возвращает 1 если оба выражения не равны нулю, и 0 в противном случае
Приоритет: 5
Пример: ldi r18, Low(c1&&c2)

Логическое ИЛИ

Символ: ||
Описание: Возвращает 1 если хотя бы одно выражение не равно нулю, и 0 в противном случае
Приоритет: 4
Пример: ldi r18, Low(c1||c2)

Функции

Определены следующие функции:

  • LOW(выражение) возвращает младший байт выражения
  • HIGH(выражение) возвращает второй байт выражения
  • BYTE2(выражение) то же что и функция HIGH
  • BYTE3(выражение) возвращает третий байт выражения
  • BYTE4(выражение) возвращает четвёртый байт выражения
  • LWRD(выражение) возвращает биты 0-15 выражения
  • HWRD(выражение) возвращает биты 16-31 выражения
  • PAGE(выражение) возвращает биты 16-21 выражения
  • EXP2(выражение) возвращает 2 в степени (выражение)
  • LOG2(выражение) возвращает целую часть log2(выражение)

Использование программы

Этот раздел описывает использование компилятора и встроенного редактора

Открытие файлов

В WAVRASM могут быть открыты как новые так и существующие файлы. Количество открытых файлов ограничено размером памяти, однако объём одного файла не может превышать 28 килобайт (в связи с ограничением MS-Windows). Компиляция файлов большего размера возможна, но они не могут быть редактируемы встроенным редактором. Каждый файл открывается в отдельном окне.

Сообщения об ошибках

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

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

Учтите, что если вы внесли изменения в исходные тексты (добавили или удалили строки), то информация о номерах строк в окне сообщений не является корректной.

Опции

Некоторые установки программы могут быть изменены через пункт меню "Options".

В поле ввода, озаглавленном "List-file extension", вводится расширение, используемое для файла листинга, а в поле "Output-file extension" находится расширение для файлов с результатом компиляции программы. В прямоугольнике "Output file format" можно выбрать формат выходного файла (как правило используется интеловский). Однако это не влияет на объектный файл (используемый AVR Studio), который всегда имеет один и тот же формат, и расширение OBJ. Если в исходном файле присутствует сегмент EEPROM то будет также создан файл с расширением EEP. Установки заданные в данном окне запоминаются на постоянно, и при следующем запуске программы, их нет необходимости переустанавливать.

Опция "Wrap relative jumps" даёт возможность "заворачивать" адреса. Эта опция может быть использована только на чипах с объёмом программной памяти 4К слов (8К байт), при этом становится возможным делать относительные переходы (rjmp) и вызовы подпрограмм (rcall) по всей памяти.

Опция "Save before assemble" указывает программе на необходимость автоматического сохранения активного окна (и только его) перед компиляцией.

Если вы хотите, чтобы при закрытии программы закрывались все открытые окна, то поставьте галочку в поле "Close all windows before exit".


Atmel, AVR являются зарегистрированными товарными знаками фирмы Atmel Corporation

Перевод выполнил Руслан Шимкевич, [email protected]

Ассемблер - это... Что такое Ассемблер?

Эта статья — о компьютерных программах. О языке программирования см. Язык ассемблера.

Ассе́мблер (от англ. assembler — сборщик) — компьютерная программа, компилятор исходного текста программы, написанной на языке ассемблера, в программу на машинном языке.

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

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

Архитектура x86

Ассемблеры для DOS

Наиболее известными ассемблерами для операционной системы DOS являлись Borland Turbo Assembler (TASM), Microsoft Macro Assembler (MASM) и Watcom Assembler (WASM). Также в своё время был популярен простой ассемблер A86.

Windows

При появлении операционной системы Windows появилось расширение TASM, именуемое TASM 5+ (неофициальный пакет, созданный человеком с ником !tE), позволившее создавать программы для выполнения в среде Windows. Последняя известная версия TASM — 5.3, поддерживающая инструкции MMX, на данный момент включена в Turbo C++ Explorer. Но официально развитие программы полностью остановлено.

Microsoft поддерживает свой продукт под названием Microsoft Macro Assembler. Она продолжает развиваться и по сей день, последние версии включены в наборы DDK. Но версия программы, направленная на создание программ для DOS, не развивается. Кроме того, Стивен Хатчессон создал пакет для программирования на MASM под названием «MASM32».

GNU и GNU/Linux

В состав операционной системы GNU входит пакет binutils, включающий в себя ассемблер gas (GNU Assembler), использующий AT&T-синтаксис, в отличие от большинства других популярных ассемблеров, которые используют Intel-синтаксис (поддерживается с версии 2.10).

Переносимые ассемблеры

Также существует открытый проект ассемблера, версии которого доступны под различные операционные системы, и который позволяет получать объектные файлы для этих систем. Называется этот ассемблер NASM (Netwide Assembler).

Yasm — это переписанная с нуля версия NASM под лицензией BSD (с некоторыми исключениями).

flat assembler (fasm) — молодой ассемблер под модифицированной для запрета перелицензирования (в том числе под GNU GPL) BSD-лицензией. Есть версии для KolibriOS, Linux, DOS и Windows; использует Intel-синтаксис и поддерживает инструкции x86-64.

Архитектуры RISC

MCS-51

MCS-51 (Intel 8051) — классическая архитектура микроконтроллера. Для неё существует кросс-ассемблер ASM51, выпущенный корпорацией MetaLink.

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

AVR

На данный момент существуют 3 компилятора производства Atmel (AVRStudio 3, AVRStudio 4, AVRStudio 5 и AVRStudio 6).

В рамках проекта AVR-GCC (он же WinAVR) существует компилятор avr-as (это портированный под AVR ассемблер GNU as из GCC).

Также существует свободный минималистический компилятор avra[1].

ARM

PIC

Пример программы на языке Assembler для микроконтроллера PIC16F628A:

 
        LIST    p=16F628A
         __CONFIG 0309H 
 
STATUS  equ     0x003
TRISB   equ     0x086
PORTB   equ     0x006
RP0     equ     5
        org  0
        goto start
start:
        bsf     STATUS,RP0             
        movlw   .00      
        movwf   TRISB                    
        bcf     STATUS,RP0        
led:
        movlw   .170   
        movwf   PORTB
        goto    led
end

AVR32

MSP430

Пример программы на языке Assembler для микроконтроллера MSP430G2231 (в среде Code Composer Studio):

 
 .cdecls C,LIST,  "msp430g2231.h"
;------------------------------------------------------------------------------
            .text                           ; Program Start
;------------------------------------------------------------------------------
RESET       mov.w   #0280h,SP               ; Initialize stackpointer
StopWDT     mov.w   #WDTPW+WDTHOLD,&WDTCTL  ; Stop WDT
SetupP1     bis.b   #001h,&P1DIR            ; P1.0 output
                                            ;                                                           
Mainloop    bit.b   #010h,&P1IN             ; P1.4 hi/low?
            jc      ON                      ; jmp--> P1.4 is set
                                            ;
OFF         bic.b   #001h,&P1OUT            ; P1.0 = 0 / LED OFF
            jmp     Mainloop                ;
ON          bis.b   #001h,&P1OUT            ; P1.0 = 1 / LED ON
            jmp     Mainloop                ;
                                            ;
;------------------------------------------------------------------------------
;           Interrupt Vectors
;------------------------------------------------------------------------------
            .sect   ".reset"                ; MSP430 RESET Vector
            .short  RESET                   ;
            .end

PowerPC

Программный пакет The PowerPC Software Development Toolset от IBM включает в себя ассемблер для PowerPC.

MIPS

Архитектуры MISC

SeaForth

Существуют:

  • 8-разрядные Flash-контроллеры семейства MCS-51
  • 8-разрядные RISC-контроллеры семейства AVR (ATtiny, ATmega, classic AVR). На данный момент семейство classic AVR трансформировано в ATtiny и ATmega
  • 8-разрядные RISC-контроллеры семейства PIC (PIC10,PIC12,PIC16,PIC18)
  • 16-разрядные RISC-контроллеры семейства PIC (PIC24HJ/FJ,dsPIC30/33)
  • 32-разрядные RISC-контроллеры семейства PIC (PIC32) с архитектурой MIPS32 M4K
  • 32-разрядные RISC-контроллеры семейства AVR32 (AVR32)
  • 32-разрядные RISC-контроллеры семейства ARM Thumb высокой производительности (серия AT91)

Макроассемблер

Не следует путать с MASM.

Макроассемблер (от греч. μάκρος — большой, обширный) — макропроцессор, базовым языком которого является язык ассемблера.[2]

Ассемблирование и компилирование

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

Примечания

См. также

Литература

  • Вострикова З. П. Программирование на языке ассемблера ЕС ЭВМ. М.: Наука, 1985.
  • Галисеев Г. В. Ассемблер для Win 32. Самоучитель. — М.: Диалектика, 2007. — С. 368. — ISBN 978-5-8459-1197-1
  • Зубков С. В. Ассемблер для DOS, Windows и UNIX.
  • Кип Ирвина. Язык ассемблера для процессоров Intel = Assembly Language for Intel-Based Computers. — М.: Вильямс, 2005. — С. 912. — ISBN 0-13-091013-9
  • Калашников О. А. Ассемблер? Это просто! Учимся программировать. — БХВ-Петербург, 2011. — С. 336. — ISBN 978-5-9775-0591-8
  • Магда Ю. С. Ассемблер. Разработка и оптимизация Windows-приложений. СПб.: БХВ-Петербург, 2003.
  • Нортон П., Соухэ Д. Язык ассемблера для IBM PC. М.: Компьютер, 1992.
  • Владислав Пирогов. Ассемблер для Windows. — СПб.: БХВ-Петербург, 2002. — 896 с. — ISBN 978-5-9775-0084-5
  • Владислав Пирогов. Ассемблер и дизассемблирование. — СПб.: БХВ-Петербург, 2006. — 464 с. — ISBN 5-94157-677-3
  • Сингер М. Мини-ЭВМ PDP-11: Программирование на языке ассемблера и организация машины. М.: Мир, 1984.
  • Скэнлон Л. Персональные ЭВМ IBM PC и XT. Программирование на языке ассемблера. М.: Радио и связь, 1989.
  • Юров В., Хорошенко С. Assembler: учебный курс. — СПб.: Питер, 2000. — С. 672. — ISBN 5-314-00047-4
  • Юров В. И. Assembler: учебник для вузов / 2-е изд. СПб.: Питер, 2004.
  • Юров В. И. Assembler. Практикум: учебник для вузов / 2-е изд. СПб.: Питер, 2004.
  • Юров В. И. Assembler. Специальный справочник. СПб.: Питер, 2000.

Ссылки

Синтаксис ассемблера / Шпаргалки

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

Допустимые символы:

1) все латинские буквы: A – Z, a – z;

2) цифры от 0 до 9;

3) знаки? @, $, &;

4) разделители.

Лексемами являются следующие.

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

2. Цепочки символов – последовательности символов, заключенные в одинарные или двойные кавычки.

3. Целые числа.

Возможные типы операторов ассемблера.

1. Арифметические операторы. К ним относятся:

1) унарные «+» и «—»;

2) бинарные «+» и «—»;

3) умножения «*»;

4) целочисленного деления «/»; 5) получения остатка от деления «mod».

2. Операторы сдвига выполняют сдвиг выражения на указанное количество разрядов.

3. Операторы сравнения (возвращают значение «истина» или «ложь») предназначены для формирования логических выражений.

4. Логические операторы выполняют над выражениями побитовые операции.

5. Индексный оператор [].

6. Оператор переопределения типа ptr применяется для переопределения или уточнения типа метки или переменной, определяемых выражением.

7. Оператор переопределения сегмента «:» (двоеточие) заставляет вычислять физический адрес относительно конкретно задаваемой сегментной составляющей.

8. Оператор именования типа структуры «.» (точка) также заставляет транслятор производить определенные вычисления, если он встречается в выражении.

9. Оператор получения сегментной составляющей адреса выражения seg возвращает физический адрес сегмента для выражения, в качестве которого могут выступать метка, переменная, имя сегмента, имя группы или некоторое символическое имя.

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

Синтаксис исходных строк на ассемблере

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

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

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

Ярлыки - это символические представления адресов. Вы можете использовать ярлыки, чтобы отмечать определенные адреса, на которые вы хотите ссылаться из других частей кода. Числовые локальные метки - это подкласс меток, которые начинаются с номера в диапазоне 0-99. В отличие от других лейблов, числовая локальная метка может быть определена много раз. Это делает их полезными при создании этикеток. с макросом.

Директивы

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

Инструкции и псевдо-инструкции составляют код, который процессор использует для выполнения задания.

Примечание

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

Некоторые директивы не разрешают использование этикеток.

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

Рекомендации при написании исходного кода на языке ассемблера

Вы должны написать мнемонику инструкций, псевдо-инструкции, директивы и символьные имена регистров (кроме a1 - a4 , v1 - v8 и регистров Wireless MMX) в любом все прописные или строчные.Вы не должны использовать смешанный регистр. Ярлыки и комментарии можно в прописные, строчные или смешанный регистр.

        ОБЛАСТЬ THUMBex, КОД, ТОЛЬКО ЧТЕНИЕ
                                ; Назовите этот блок кода THUMBex
        ВХОД                   ; Отметить первую инструкцию для выполнения
        БОЛЬШОЙ ПАЛЕЦ
Начните
        MOV r0, # 10; Настроить параметры
        MOV r1, # 3
        ДОБАВИТЬ r0, r0, r1; г0 = г0 + г1
останавливаться
        MOV r0, # 0x18; angel_SWIreason_ReportException
        LDR r1, = 0x20026; ADP_Stopped_ApplicationExit
        SVC # 0x123456; Полухостинг ARM (ранее SWI)
        КОНЕЦ                     ; Отметить конец файла 

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

Примечание

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

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

Синтаксис языка ассемблера

от Valvano

Синтаксис языка ассемблера от Valvano

Разработка программного обеспечения на языке ассемблера
Синтаксис
Джонатан В. Вальвано

В этой статье, в которой обсуждается программирование на языке ассемблера, прилагается к книге Embedded Microcomputer Systems: Real Time Interfacing , опубликованной Brooks-Cole 1999. В этом документе всего четыре частей
Обзор
Синтаксис (поля, псевдооперации) (этот документ)
Локальные переменные
Примеры


Синтаксис языка ассемблера
Программы, написанные на языке ассемблера, состоят из последовательности исходных заявлений.Каждый исходный оператор состоит из последовательности символов ASCII, оканчивающихся символом возврата каретки. Каждое исходное заявление может включать до четырех полей: метка, операция (инструкция мнемоническая или ассемблерная директива), операнд и комментарий. В ниже приведены примеры директивы сборки и обычного машинная инструкция.
PORTAequ $ 0000; Постоянная времени сборки
InpldaaPORTA; Чтение данных из порта данных ввода / вывода с фиксированным адресом

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

Иногда не все четыре поля присутствуют в ассемблере утверждение. Строка может содержать просто комментарий. Первый токен в этих строках должны начинаться со звездочки (*) или точки с запятой (;). Например,
; Эта строка является комментарием
* Это тоже комментарий
* Эта строка является комментарием

Команды с адресацией в собственном режиме не имеют операнда поле.Например,
labelclracomment
decacomment
clicomment
incacomment


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

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

------------------------------------------------- -------------------------------------
Поле метки
Поле метки появляется как первое поле исходной выписки. Поле метки может принимать одну из следующих трех форм:

A. Звездочка (*) или точка с запятой (;) в качестве первого символа в поле метки указывает, что остальная часть исходной инструкции это комментарий. Комментарии игнорируются Ассемблером и печатаются в списке источников только для информации программиста.Примеры:
* Эта строка представляет собой комментарий
; Эта строка также является комментарием

B. Пробельный символ (пробел или табуляция) в качестве первого символа. указывает, что поле метки пусто. У линии нет метки и это не комментарий. На этих сборочных линиях нет этикеток:
ldaa0
rmb10


C. Символ символа в качестве первого символа указывает на то, что строка имеет метку. Символы символов в верхнем или нижнем регистре. буквы a-z, цифры 0-9 и специальные символы, точка (.), знак доллара ($) и подчеркивание (_). Символы состоят от одного до 15 символов, первый из которых должен быть буквенным или специальным. символы точка (.) или подчеркивание (_). Все персонажи значительны буквы верхнего и нижнего регистра различны.

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

За исключением директив equ = andset, метке присваивается значение программного счетчика. первого байта собираемой инструкции или данных. Значение, присвоенное метке, является абсолютным. Этикетки могут по желанию заканчиваться двоеточием (:).Если используется двоеточие, оно не является частью ярлыка, но просто действует, чтобы отделить ярлык от остальных исходной строки. Таким образом, следующие фрагменты кода эквивалентны:
здесь: deca
bnehere


heredeca
bnehere


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

Таблица символов вмещает не менее 2000 символов длиной 8 символов или меньше.Допускаются дополнительные символы до 15 за счет уменьшения максимально возможного количества символов в таблице.

------------------------------------------------- -------------------------------------
Поле операции
Поле операции находится после метки поле и должен предшествовать хотя бы одному символу пробела. Операция Поле должно содержать допустимую мнемонику кода операции или директиву ассемблера. Символы верхнего регистра в этом поле преобразуются в нижний регистр. перед проверкой как юридическая мнемоника.Таким образом, "nop", "NOP" и «NoP» распознаются как один и тот же мнемоник. Записи в операции поле может быть одного из двух типов:

Код операции . Они прямо соответствуют машинным инструкциям. Код операции включает в себя любое имя регистра, связанное с инструкцией. Эти имена регистров не должны отделяться от кода операции никакими символы пробела. Таким образом, clra означает очистить аккумулятор A, но 'clr a' означает очищенную ячейку памяти, обозначенную меткой 'а'.Доступные инструкции зависят от микрокомпьютера, который вы используете. используют

Директива . Это специальные коды операций, известные Ассемблеру, которые контролировать процесс сборки, а не переводить на машинные инструкции. Коды псевдоопераций, поддерживаемые этим ассемблером

Группа A Группа B Группа C , что означает
орг org .org Конкретный абсолютный адрес для последующего кодирования объекта
= экв. Определить постоянный символ
комплект Определите или переопределите постоянный символ
dc.b db fcb . Байт Выделить байт (-ы) памяти с инициализированными значениями
fcc Создать строку ASCII (без символа завершения)
постоянного тока.w dw fdb . Слово Выделить слово (слова) памяти с инициализированными значениями
dc.l dl . Длинный Выделить 32-битное слово (слова) в хранилище с инициализированными значениями
DS DSB юаней .blkb Выделить байты памяти без инициализации
ds.w .blkw Выделить байты памяти без инициализации
дс.l .blkl Выделить 32-битные слова памяти без инициализации
конец конец . Конец Обозначает конец исходного кода ( TExaS игнорирует их)

------------------------------------------------- -------------------------------------
Поле операнда
Интерпретация поля операнда зависит от содержимое поля операции.Поле операнда, если требуется, должно следовать поле операции и должно предшествовать хотя бы одному пробелу персонаж. Поле операнда может содержать символ, выражение, или сочетание символов и выражений, разделенных запятыми. В поле операнда не может быть пробелов. Например следующие две строки создают идентичный объектный код, потому что пробела между данными и + в первой строке:
ldaadata + 1
ldaadata

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

Операнд Формат 6811/6812 пример
без операнда аккумулятор и собственный clra
<выражение> прямой, удлиненный или относительный ldaa 4
# <выражение> немедленная ldaa # 4
<выражение>, R индексируется адресным регистром ldaa 4, х
<выражение>, <выражение> бит установлен или сброшен bset 4, № $ 01
, , бит тест и ответвление брюссеть 4, # 01 $, там
<выражение>, R, <выражение>, <выражение> бит тест и ветвь брсет 4, х, # 01 $, там


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

Каждый символ связан с 16-битным целым значением, которое используется вместо символа во время вычисления выражения.Звездочка (*), используемая в выражении как символ, представляет текущее значение счетчика местоположения (первый байт многобайтовая инструкция)

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

0xhexadecimal, синтаксис C
% двоичный
'c' Код ASCII для одной буквы c

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

Десятичная константа состоит из строки числовых цифр. В значение десятичной константы должно находиться в диапазоне 0–65535 включительно. В следующем примере показаны как допустимые, так и недопустимые десятичные константы:

ДЕЙСТВИТЕЛЬНО НЕДЕЙСТВИТЕЛЬНО НЕВЕРНАЯ ПРИЧИНА
12 123456 более 5 цифр
12345 12.3 недопустимый символ


Шестнадцатеричная константа состоит максимум из четырех символов. из набора цифр (0-9) и заглавных букв алфавита (A-F), и перед ним стоит знак доллара ($). Шестнадцатеричные константы должно быть в диапазоне от $ 0000 до $ FFFF. В следующем примере показано как действительные, так и недопустимые шестнадцатеричные константы:

ДЕЙСТВИТЕЛЬНО НЕДЕЙСТВИТЕЛЬНО НЕВЕРНАЯ ПРИЧИНА
$ 12 ABCD без предшествующего "$"
$ ABCD $ G2A недопустимый символ
$ 001F $ 2F018 слишком много цифр


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

ДЕЙСТВИТЕЛЬНО НЕДЕЙСТВИТЕЛЬНО НЕВЕРНАЯ ПРИЧИНА
% 00101 1010101 недостающие проценты
% 1 % 10011000101010111 слишком много цифр
% 10100 % 210101 неверная цифра


Один символ ASCII может использоваться как константа в выражениях. ASCII Константы заключены в одинарные кавычки ('). Любой персонаж, кроме одинарной кавычки, может использоваться как символьная константа. В следующем примере показаны допустимые и недопустимые символьные константы:

ДЕЙСТВИТЕЛЬНО НЕДЕЙСТВИТЕЛЬНО НЕВЕРНАЯ ПРИЧИНА
'*' ДЕЙСТВИТЕЛЬНЫЙ слишком длинный


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

------------------------------------------------- -------------------------------------
Поле комментария
Последнее поле исходного кода Ассемблера заявление это комментарий поле. Это поле не является обязательным и печатается только в источнике листинг для документации. Поле комментария отделено из поля операнда (или из поля операции, если операнд отсутствует требуется) хотя бы одним символом пробела.Комментарий Поле может содержать любые печатаемые символы ASCII.
Как разработчики программного обеспечения, наша цель - создать код, который не только решает нашу текущую проблему, но может служить основой наших будущих проблем. Чтобы повторно использовать программное обеспечение, мы должны оставить наш код в таком состоянии, что будущий программист (в том числе мы сами) можем легко понять его цель, ограничения и реализация. Документация - это не что-то прикрепленное к программному обеспечению после того, как это сделано, а дисциплина, встроенная в него на каждом стадия развития.Мы тщательно разрабатываем стиль программирования предоставление соответствующих комментариев. Я чувствую комментарий, который говорит нам почему мы выполняем определенные функции информативнее, чем комментарии которые говорят нам, каковы функции. Примеры плохих комментариев будет:
clrFlagFlag = 0
seiSet I = 1
ldaa $ 1003 Читать PortC


Это плохие комментарии, потому что они не содержат информации помогите нам в будущем понять, что делает программа. Пример хороших комментариев:
clrFlagSignify ключ не был набран
sei Следующий код не будет прерван
ldaa $ 1003Bit7 = 1, если переключатель нажат


Это хорошие комментарии, потому что они упрощают внесение изменений программа на будущее.
Самодокументирующийся код - это программа, написанная простым и очевидным таким образом, что его цель и функция очевидны. К напишите такой замечательный код, сначала нужно сформулировать проблему Организуя его в четко определенные подзадачи. Как мы ломаемся сложная проблема на мелкие части проходит долгий путь, делая программное обеспечение самодокументирования. Оба понятия абстракции (представленные в последнем разделе) и модульный код (будет представлен в следующий раздел) обращается к этому важному вопросу организации программного обеспечения.
Сопровождение программного обеспечения - это процесс исправления ошибок, добавления новые функции, оптимизация по скорости или объему памяти, перенос на новое компьютерное оборудование и настройку программного обеспечения для новые ситуации. Это НАИБОЛЕЕ ВАЖНЫЙ этап разработки программного обеспечения. Мое личное мнение таково, что блок-схемы или руководства по программному обеспечению не являются хорошими механизмами для документирования программ, потому что это трудно поддерживать эти типы документации в актуальном состоянии, когда внесены изменения.
Мы должны использовать осторожные отступы и описательные имена для переменные, функции, метки, порты ввода / вывода.Либеральное использование equ provide объяснение функции программного обеспечения без затрат на скорость выполнения или требования к памяти. Дисциплинированный подход к программированию заключается в разработке шаблонов письма, которым вы постоянно следуете. Разработчики программного обеспечения не похожи на писателей рассказов. Это нормально используйте одну и ту же схему подпрограммы снова и снова. В следующей программе обратите внимание на следующее вопросов стиля:

1) Начинается и заканчивается строкой из *
2) Указывает цель подпрограммы
3) Указывает параметры ввода / вывода, что они означают и как они передаются
4) Различные фазы (подмодули) кода, обозначенные строка

******************* Макс. **************************** **
* Цель: возвращает максимум два 16-битных числа
* Эта подпрограмма создает три 16-битных локальных переменных
* Входные данные: Num1 и Num2 - два 16-битных беззнаковых числа
*, переданных в стек
* Выход: RegX - это максимум X, Y
* Уничтожено: CCR
* Вызывающая последовательность
* ldx # 100
* pshxNum1 помещена в стек
* ldx # 200
* pshx Num2 помещена в стек
* jsrMax
* pulyBalance stack
* pulyResult в RegX
Firstset0 Первая 16-битная локальная переменная
Secondset2 Вторая 16-битная локальная переменная
Resultset4 Максимум первой, второй
Num1set12 Входной параметр1
Num2set10 Входной параметр2
Maxpshy Сохраняет регистры, которые будут изменены
* - - - - - - - - - - - - - - - - - - - - - - - - - - - -
pshxAllocate Локальная переменная результата
pshxAllocate Вторая локальная переменная
pshxAllocate Первая локальная переменная
* - - - - - - - - - - - - - - - - - - - - - - - - - -
tsxCreate указатель кадра стека
ldyNum1, X
styFirst, XInitialize First = Num1
ldyNum2, X
stySecond, XInitialize Second = Num2
ldyFirst, X
styResult, XGuess that Result = Первый
cpySecond, X
bhsMaxOKSkip if First> = Second
ldySecond, XSince First styResult, Xmake Result = Second
MaxOKldxResult, XReturn Result в RegX
* - - - - - - - - - - - - - - - - - - - - - - - - - - -
puly Удаление локальных переменных
puly
puly
* - - - - - - - - - - - - - - - - - - - - - - - - - -
pulyRestore регистры
rts

****************** Конец макс. **************************** *

------------------------------------------------- -------------------------------------
Листинг ассемблера
Выходные данные ассемблера включают необязательный листинг принадлежащий исходная программа и объектные файлы.Файл листинга создается, когда открыт файл TheList.RTF .
Каждая строка списка содержит номер ссылочной строки, адрес и байты собраны, и исходный исходный ввод линия. Если строка ввода вызывает вывод более 8 байтов (например, длинная директива FCC), дополнительные байты включены в объектный код (файл S19 или загружен в память), но не показан в листинг. Есть три варианта сборки, каждый из которых можно переключать. включение / выключение с помощью команды Сборка-> Параметры.

(4) цикла показывает количество циклов для выполнения этой инструкции
[100] всего дает общее количество рабочих циклов с момента последней псевдооперации организации
{PPP} тип дает тип цикла


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

------------------------------------------------- -------------------------------------
Ошибки сборки

Ошибки программирования делятся на две категории. Простой набор текста / синтаксис ошибка будет помечена ассемблером TExaS как ошибка , когда ассемблер пытается перевести исходный код в машину код.Ошибки программирования, которые сложнее найти и удалить это функциональные ошибки, которые могут быть обнаружены во время выполнения, когда программа работает не так, как ожидалось. Имеются в виду сообщения об ошибках чтобы быть понятным. Ассемблер имеет режим verbose (см. Команду Assembler-> Options), который предоставляет более подробную информацию. об ошибке и предлагает возможные решения.

Типы ошибок ассемблера
1) Неопределенный символ: программа ссылается на метку, которая не существует
Как исправить: проверьте орфографию определения и доступа
2) Неопределенный код операции или псевдооперация
Как исправить: проверьте орфографию / наличие инструкции
3) Режим адресации недоступен
Как исправить: найдите режимы адресации, доступные для инструкция
4) Ошибка выражения
Как исправить: проверьте скобки, начните с более простого выражения
5) Ошибка фазирования возникает, когда значение символа изменяется с pass1 на pass2
Как исправить: сначала удалите все неопределенные символы, затем удалите пересылка ссылок
6) Ошибка адреса
Как исправить: используйте псевдооперации org для сопоставления доступной памяти.
Диагностические сообщения об ошибках помещаются в файл листинга просто после строки, содержащей ошибку. Если файл TheList.RTF отсутствует, то ошибки сборки сообщаются в файле TheLog.RTF . Если файлов TheList.RTF или TheLog.RTF нет, то ошибки сборки не выводятся.

------------------------------------------------- -------------------------------------
Ошибки фазировки
Ошибка фазировки во время прохода 2 ассемблера, когда адрес метки отличается от того, когда он был ранее рассчитано.Цель первого этапа ассемблера - создать таблица символов. Чтобы вычислить адрес каждой сборки строки, ассемблер должен уметь определить точное число байтов займет каждая строка. Для большинства инструкций номер требуемого байта фиксировано и легко вычисляется, но для других инструкции, количество байтов может варьироваться. Возникают ошибки фазирования когда ассемблер вычисляет размер другой инструкции в проходе 2, чем ранее рассчитывалось на проходе 2.Иногда фазировка ошибка часто возникает в строке программы ниже, чем где возникает ошибка. Ошибка фазирования обычно возникает из-за использование прямых ссылок. В этом примере 6812 символ "index" недоступен во время сборки ldaa index, x. Ассемблер неправильно выбирает 2-х байтовую адресацию IDX. версия режима, а не правильный 3-байтовый режим IDX1.
ldaaindex, x
indexequ 100
; ...
loopldaa # 0

В листинге показана ошибка фазирования.
Copyright 1999-2000 Test EXecute And Simulate
$ 0000A6E064ldaaindex, x
$ 0064indexequ100
;...
$ 00038600loopldaa # 0
#####
Ошибка фазирования
Эта строка находилась по адресу $ 0002 на проходе 1, теперь на проходе 2 это $ 0003

*************** Таблица символов *********************
индекс $ 0064
цикл $ 0002
##### Сборка завершилась неудачно, 1 ошибка!

Когда ассемблер переходит в цикл, значения Pass 1 и Pass 2 отключаются из-за ошибки фазирования в инструкции ldaa # 0 цикла. Решение здесь - просто сначала поставить индекс, равный 100.

------------------------------------------------- -------------------------------------
Ассемблер псевдооператора ' с

Псевдооперации - это специальные команды для ассемблера, которые интерпретируются в процессе сборки. Некоторые из них создают объектный код, но большинство этого не делают. Есть два распространенных формата псевдоопераций используется при разработке языка ассемблера Motorola. Ассемблер TExaS поддерживает обе категории. Если вы планируете экспортировать ПО разработан с помощью TExaS для другого приложения, тогда вам следует ограничить использование только psuedo-op совместим с этим приложением.

Group A поддерживается Motorola MCUez, HiWare и ImageCraft. ICC11 и ICC12
Group B поддерживается Motorola DOS уровня AS05, AS08, AS11 и AS12
Group C - некоторые альтернативные определения

Группа A Группа B Группа C , что означает
орг org .org Конкретный абсолютный адрес для последующего кодирования объекта
= экв. Определить постоянный символ
комплект Определите или переопределите постоянный символ
постоянного тока.б дб fcb . Байт Выделить байт (-ы) памяти с инициализированными значениями
fcc Создать строку ASCII (без символа завершения)
dc.w dw fdb . Слово Выделить слово (слова) памяти с инициализированными значениями
dc.l dl . Длинный Выделить 32-битное слово (слова) в хранилище с инициализированными значениями
ds ds.b юаней .blkb Выделить байты памяти без инициализации
ds.w .blkw Выделить байты памяти без инициализации
DSL .blkl Выделить 32-битные слова памяти без инициализации
конец конец . Конец Обозначает конец исходного кода ( TExaS игнорирует их)

------------------------------------------------- -------------------------------------
приравнять символ к значению

<метка> equ <выражение> (<комментарий>)
<метка> = <выражение> (<комментарий>)

Директива EQU (или =) присваивает значение выражения в поле операнда к метке.Директива equ присваивает значение кроме программного счетчика на этикетке. Этикетка не может быть переопределенным где-нибудь еще в программе. Выражение не может содержать любые прямые ссылки или неопределенные символы. Приравнивается к прямые ссылки помечаются как Phasing Errors phasing_error.
В следующем примере имена локальных переменных не могут быть повторно используется в другой подпрограмме:
; MC68HC812A4
; ***** фаза привязки ***************
Iequ-4
PTequ-3
Ansequ-1
; ******* Фаза распределения *********
functionpshxsave old Reg X
tsxcreate указатель кадра стека
leas-4, выделить четыре байта для I, PT, Result
; ******** Фаза доступа ************
clrI, xClear I
ldyPT, xReg Y - это копия PT
staaAns, xstore в Ans
; ******** Фаза освобождения *****
txsdeallocation
pulxrestore old X
rts

В следующем примере псевдооперация equ используется для определения порты ввода / вывода и для доступа к различным элементам связанных состав.
* *********** Moore.RTF *********************
* Джонатан В. Вальвано 18.07.98 10: 54:28 PM
* Контроллер конечного автомата Мура
* PC1, PC0 - двоичные входы, PB1, PB0 - двоичные выходы
PORTBequ0x01
DDRBequ0x03
PORTCequ0x04
DDRCequ0x06
TCNTequ0x84; 16-битные тактовые импульсы без знака, увеличивающиеся каждый цикл
TSCRequ0x86; установите бит 7 = 1, чтобы включить TCNT
* Контроллер конечного автомата
* C1, C0 - это входы B1, B0 - выходы
org $ 800 Переменные идут в RAM
StatePtrmb2Pointer в текущее состояние
org $ F000 Поместите в EEPROM, чтобы его можно было изменить
Outequ0offset для выходного значения
* 2-битный шаблон, сохраненный в младшей части 8-битного байта
Waitequ1offset для времени ожидания
Nextequ2offset для 4 следующих состояний
* Четыре 16-битных абсолютных адреса без знака
InitStatefdbS1 Начальное состояние
S1fcb% 01Output
fcb5Wa
fdbS2, S1, S2, S3
S2fcb% 10 Выход
fcb10 Время ожидания
fdbS3, S1, S2, S3
S3fcb% 11 Выход
fcb20 Время ожидания
fdbS1, S1, S2, S1
org $ F800 программ gold #
org $ F800 C00
movb # $ FF, TSCR enable TCNT
ldaa #% 11111111
staaDDRB B1, B0 - выходы светодиодов
ldaa #% 00000000
staaDDRC C1, C0 - входы переключателя
ldxInitState Указатель состояния
stxStatePt
* Цель: запустить * 1.Выполнить вывод для текущего состояния
* 2. Подождать заданное время
* 3. Вход от переключателей
* 4. Перейти к следующему состоянию в зависимости от входа.
* StatePt - указатель текущего состояния
FSMldxStatePt1. Вывести
ldabOut, xOutput значение для этого состояния в битах 1,0
stabPORTB
ldaaWait, x2. Ждать в этом состоянии
bsrWAIT
ldabPORTC3. Чтение ввода
andb # $ 03 просто интересует бит 1,0
lslb 2 байта на 16-битный адрес
abx добавить 0,2,4,6 в зависимости от ввода
ldxNext, x4.Следующее состояние в зависимости от входа
stxStatePt
braFSM
* Reg A - время ожидания (256 циклов каждый)
WAITtfra, b
clraRegD = количество циклов ожидания
adddTCNTTCNT значение в конце задержки
WloopcpdTCNTEndT-TCNT <0 когда EndT bplWloop
rts
org $ FFFE
fdbMainreset vector

------------------------------------------------- -------------------------------------
установить символ приравнивания к значению

<метка> set <выражение> (<комментарий>)

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

В следующем примере имена локальных переменных можно использовать повторно. в другой подпрограмме:
; MC68HC812A4
; ***** фаза привязки ***************
Iset-4
PTset-3
Ansset-1
; ******* Фаза распределения *********
functionpshxsave old Reg X
tsxcreate указатель кадра стека
leas-4, выделить четыре байта для I, PT, Result
; ******** Фаза доступа ************
clrI, xClear I
ldyPT, xReg Y - это копия PT
staaAns, xstore в Ans
; ******** Фаза освобождения *****
txsdeallocation
pulxrestore old X
rts


------------------------------------------------ --------------------------------------
Байт константы формы fcb

(<метка>) fcb (, ,..., ) ()
(

Директива FCB может иметь один или несколько операндов, разделенных запятыми. Значение каждого операнда усекается до восьми бит и сохраняется. в одном байте объектной программы. Несколько операндов хранятся в последовательных байтах.Операнд может быть числовой константой, символьная константа, символ или выражение. Если несколько присутствуют операнды, один или несколько из них могут быть нулевыми (два соседних запятые), и в этом случае будет присвоен один нулевой байт для этого операнда. Ошибка возникнет, если старшие восемь бит из значений оцененных операндов не все единицы или все нули.
Может быть включена строка, которая хранится как последовательность Символы ASCII. Разделители, поддерживаемые TExaS , - ​​это "'и \.Строка не заканчивается, поэтому программист должен явно прекратить его. Например:
str1 fcb «Hello World», 0

В следующем конечном автомате определения fcb используется для хранения выходных данных и времени ожидания.
Outequ0offset для выходного значения
* 2-битный шаблон, сохраненный в младшей части 8-битного байта
Waitequ1offset для времени ожидания
Nextequ2offset для 4 следующих состояний
* Четыре 16-битных абсолютных адреса без знака
InitStatefdbS1 Начальное состояние
S1fcb% 01Output
fcb5Wa
fdbS2, S1, S2, S3
S2fcb% 10 Выход
fcb10 Время ожидания
fdbS3, S1, S2, S3
S3fcb% 11 Выход
fcb20 Время ожидания
fdbS1, S1, S2, S1

------------------------------------------------- -------------------------------------
fcc Строка константных символов формы

(<метка>) FCC <разделитель> <строка> <разделитель> (<комментарий>)

Директива FCC используется для хранения строк ASCII и в последовательных байтах памяти.Начинается байтовое хранилище на текущем программном счетчике. Метка присваивается первому байт в строке. В строке может содержаться любой из печатаемых символов ASCII . Строка указана между двумя одинаковыми разделителями. Первый непустой символ после директивы FCC используется в качестве разделителя. Разделители поддерживаются TExaS : "'и \.

Примеры:

LABEL1FCC'ABC '
LABEL2fcc "Джон Вальвано"
LABEL4fcc / Добро пожаловать в FunCity! /

Первая строка создает ASCII символов ABC в ячейке LABEL1.Будьте осторожны, не размещайте код FCC в стороне от исполняемых инструкций. Сборщик произведет объектный код, как и для обычных инструкций, одна строка в время. Например, следующее приведет к сбою, потому что после выполнения инструкции LDX, 6811 будет пытаться выполнить ASCII символов «Проблема» в качестве инструкций.
ldaa100
ldx # Strg
Strgfcc "Trouble"

Обычно мы собираем все fcc, fcb, fdb вместе и помещаем их в конец нашей программы, чтобы микрокомпьютер не пытается выполнить постоянные данные.Например,
ldaaCon8
ldyCon16
ldx # Strg
braloop
* Поскольку петля бюстгальтера безусловна,
* 6811 не выходит за пределы этой точки.
Strgfcc "Нет проблем"
Con8fcb100
Con16fdb1000


------------------------------------------------ --------------------------------------
fdb Form Double Byte

(<метка>) fdb (, , ..., ) ()
(

Директива FDB может иметь один или несколько операндов, разделенных запятыми. 16-битное значение, соответствующее каждому операнду, сохраняется в два последовательных байта объектной программы. Хранение начинается на текущем программном счетчике. Метка присваивается первому 16-битное значение.Несколько операндов хранятся в последовательных байтах. Операнд может быть числовой константой, символьной константой, символ или выражение. Если присутствует несколько операндов, один или несколько из них могут быть нулевыми (две соседние запятые), и в этом случае этому операнду будут присвоены два байта нулей.

В следующем конечном автомате определения fdb используются для определения указателей состояния. Например, InitState и четыре указателя Next.
Outequ0offset для выходного значения
* 2-битный шаблон, сохраненный в младшей части 8-битного байта
Waitequ1offset для времени ожидания
Nextequ2offset для 4 следующих состояний
* Четыре 16-битных абсолютных адреса без знака
InitStatefdbS1 Начальное состояние
S1fcb% 01Output
fcb5Wa
fdbS2, S1, S2, S3
S2fcb% 10 Выход
fcb10 Время ожидания
fdbS3, S1, S2, S3
S3fcb% 11 Выход
fcb20 Время ожидания
fdbS1, S1, S2, S1

------------------------------------------------- -------------------------------------
постоянного тока.l Определить 32-битную константу

(<метка>) dc.l <выражение> (, <выражение>, ..., <выражение>) (<комментарий>)
(<метка>) dl <выражение> (, <выражение>, ... , ) ()
(

Директива dl может иметь один или несколько операндов, разделенных запятыми. 32-битное значение, соответствующее каждому операнду, сохраняется в четыре последовательных байта объектной программы (big endian).В сохранение начинается с текущего программного счетчика. Метка присвоена к первому 32-битному значению. Несколько операндов хранятся в последовательном байтов. Операнд может быть числовой константой, символьной константой, символ или выражение. Если присутствует несколько операндов, один или несколько из них могут быть нулевыми (две соседние запятые), в которых case четыре байта нулей будут присвоены этому операнду.

В следующем конечном автомате определения dl используются для определения 32-битных констант.
S1dl100000, $ 12345 678
S2.long1,10,100,1000,10000,100000,1000000,10000000
S3dc.l-1,0,1


------------------------------------------------ --------------------------------------
org Установить счетчик программ на исходную точку

org <выражение> (<комментарий>)
.org <выражение> (<комментарий>)

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

Операторы org в следующем скелете помещают переменные в ОЗУ. и программы в EEPROM MC68HC812A4
* ********** <<Имя>> ********************
org $ 800 переменные идут в ОЗУ
* << глобальные объекты, определенные с помощью rmb, идут сюда >>
org $ F000программы в EEPROM
Основная часть: lds # $ 0C00 инициализирует стек в ОЗУ
* << одноразовые инициализации идут сюда >> Цикл
:
* << повторяющиеся операции перейдите сюда >>
braloop
* << подпрограммы перейдите сюда >>
org $ FFFE
fdbMainreset vector

------------------------------------------------- -------------------------------------
rmb Резервное несколько байтов

(<метка>) rmb <выражение> (<комментарий>)
(<метка>) ds <выражение> (<комментарий>)
(<метка>) ds.b <выражение> (<комментарий>)
(<метка>) .blkb <выражение> (<комментарий>)

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

------------------------------------------------- -------------------------------------
ds.w Зарезервировать несколько слов

(<метка>) ds.w <выражение> (<комментарий>)
(<метка>) .blkw <выражение> (<комментарий>)

Директива ds.w приводит к увеличению счетчика местоположения. в 2 раза больше значения выражения в поле операнда. Этот директива резервирует блок памяти, длина которого в словах (16 бит) равно значению выражения.Блок зарезервированная память не инициализируется никаким заданным значением. Выражение не может содержать никаких прямых ссылок или неопределенных символов. Этот директива обычно используется для резервирования области блокнота или таблицы для дальнейшего использования.

------------------------------------------------- -------------------------------------
ds.l Зарезервировать несколько 32-битных слов

(<метка>) ds.l <выражение> (<комментарий>)
(<метка>) .blkl <выражение> (<комментарий>)

Модель DS.Директива l заставляет счетчик местоположения быть продвинутым в 4 раза больше значения выражения в поле операнда. Этот директива резервирует блок памяти, длина которого в словах (32 бита) равно значению выражения. Блок зарезервированная память не инициализируется никаким заданным значением. Выражение не может содержать никаких прямых ссылок или неопределенных символов. Этот директива обычно используется для резервирования области блокнота или таблицы для дальнейшего использования.


------------------------------------------------ --------------------------------------
конец Конец программы (необязательно)

конец (<комментарий>)
.конец (<комментарий>)

Директива END означает конец исходного кода. Ассемблер TExaS игнорирует эти коды псевдоопераций.

------------------------------------------------- -------------------------------------
Коды символов ASCII

БИТЫ с 4 по 6

0 1 2 3 4 5 6 7
0 NUL DLE СП 0 @ -П, ` п.
B 1 SOH DC1 : 1 А Q a q
Я 2 STX DC2 ! 2 B R б r
т 3 ETX DC3 # 3 С S с с
S 4 EOT DC4 $ 4 D Т д т
5 ENQ НАК % 5 E U e u
0 6 ACK SYN и 6 F В f v
7 БЕЛ ETB ' 7 G Вт г Вт
т 8 BS CAN ( 8 H Х ч х
O 9 HT EM ) 9 Я Y и y
А LF ПОД * : Дж Z j z
3 B VT ESC + ; К [ к {
С FF ФС , < L \ л ;
D CR GS = M ] кв.м. }
E SO RS . n ~
F S1 США / ? O _ или DEL

------------------------------------------------- -------------------------------------
S-19 Код объекта
S-запись выходной формат кодирует программу и объект данных модули в формат для печати (ASCII).Это позволяет просматривать объектный файл со стандартным инструменты и позволяет отображать модуль при переходе из от одного компьютера к другому или во время нагрузок между хостом и целью. Формат S-записи также включает информацию для использования в случае ошибки. проверка для обеспечения целостности передачи данных.
S-записи - это символьные строки, состоящие из нескольких полей, которые определить тип записи, длину записи, адрес памяти, код / ​​данные, и контрольная сумма. Каждый байт двоичных данных кодируется как 2-символьный шестнадцатеричное число: первый символ, представляющий старший 4 бита, а второй - 4 младших бита байта.

5 полей, которые составляют S-запись:
1) Тип S0, S1 или S9
2) Длина записи
3) Адрес
4) Код / данные
5) Контрольная сумма

Было определено восемь типов S-записей для различных требуется кодирование, транспортировка и декодирование, но в большинстве микроконтроллеров Motorola используются только три типа . Запись S0 - это запись заголовка, содержащая имя файла в формате ASCII в поле «Код / данные». Адресное поле этот тип обычно 0000.Запись S1 - это запись данных, содержащая информацию, которая должна быть загружена последовательно. начиная с указанного адреса. Запись S9 является маркером конца файла и иногда содержит начальную адрес для начала исполнения. Во встроенной микрокомпьютерной среде, начальный адрес должен быть запрограммирован в соответствующем месте. Для большинства микроконтроллеров Motorola вектор сброса является последним. два байта ПЗУ или EEPROM.

Длина записи содержит количество пар символов в записи длины, без учета типа и длины записи.

Для типов записей S0, S1, S9 поле Address представляет собой 4-байтовое значение. Для типа записи S1 адрес указывает где поле данных должно быть загружено в память.

В поле Code / Data содержится от 0 до n байтов. Эта информация содержит исполняемый код, загружаемую память данные или описательная информация.

Поле Checksum состоит из 2 символов ASCII, используемых для проверки ошибок. В мере значащий байт дополнения суммы значений до единицы представлен парами символов, составляющими длину записи, адрес и поля кода / данных.При генерации контрольной суммы один добавляет (назовите результат сумму ) длину записи, адрес и поле кода / данных, используя 8-битный модуль арифметика (игнорирование переполнения). Контрольная сумма вычисляется.
контрольная сумма = $ FF - сумма
При проверке контрольной суммы добавляется (назовем результат сумма ) длина записи, адресный код / ​​поле данных и контрольная сумма, используя 8-битная арифметика по модулю (без учета переполнения). Сумма должна быть $ FF.

Каждая запись может заканчиваться CR / LF / NULL.

Ниже приведен типичный модуль S-записи:

S1130000285F245F2212226A0004242

237C2A
S1130010000200080008262

53812341001813


S113002041E

4E42234300182342000824A952
S107003000144ED0000FC492
S903

Модуль состоит из четырех записей кода / данных и завершения S9. записывать.

Первый код / ​​запись данных S1 объясняется следующим образом:

S1S-запись типа S1, указывающая, что код / ​​запись данных должна быть загружен / проверен по 2-байтовому адресу.

13 Hex 13 (19 в десятичной системе), обозначающее 19 пар символов, представляющих Далее следуют 19 байт двоичных данных.

00 Четырехсимвольное 2-байтовое поле адреса: шестнадцатеричный адрес 0000, указывает место, куда должны быть загружены следующие данные.

Следующие 16 пар символов представляют собой байты ASCII фактического программный код / ​​данные

2A Контрольная сумма первой записи S1.

Вторая и третья записи кода / данных S1 также содержат 13 долларов США. пары символов и заканчиваются контрольными суммами.Четвертый код / ​​данные S1 запись содержит 7 пар символов.

Запись о завершении S9 объясняется следующим образом:

S9S-запись типа S9, указывающая на завершение записи.

03Hex 03, указывающий три пары символов (3 байта) для следить.

00 Четырехсимвольное 2-байтовое поле адреса, нули 00

FCC Контрольная сумма записи S9.

Этот документ состоит из четырех общих частей
Обзор
Синтаксис (поля, псевдооперации) (этот документ)
Локальные переменные
Примеры

Assembly - OSDev Wiki

До самого ядра компьютера каждый сигнал, посылаемый в любую часть машины, представляет собой серию электрических импульсов.Если электрический импульс высокий, например 5 вольт, это означает, что отправляется двоичная единица. Если электрический импульс низкий, например 0 вольт, это означает, что отправляется двоичная цифра 0. Сложите 4 двоичных цифры вместе, и вы получите кусочек. Складываем 8, получаем байт. Сложите 16 вместе, вы получите слово. Компьютеры понимают команды в таких сегментах, но люди этого не хотят. Таким образом, они разработали лучший способ просмотра такой информации, и это было в шестнадцатеричном формате. Во-первых, для отображения одной команды не требовалось 16 символов и в целом стало удобнее запоминать такие команды, как:

 90 - Нет работы
CC - перерыв
E9 - 16-битный переход
CD - прерывание
и т.п.

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

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

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

Синтаксис сборки

В ассемблере за каждой инструкцией (или операцией / оператором / кодом операции) следует список параметров (или операндов), разделенных запятыми. Эти операнды могут быть либо непосредственными значениями (например, числами, такими как 1, 2, 0x16, 0101b), либо регистрами, либо ячейкой памяти.Например,

Инструкция mov, операнды - eax и 123. Здесь eax - регистр, а 123 - непосредственное значение.

Существует два основных синтаксиса сборки: синтаксис Intel и синтаксис AT&T.

Синтаксис Intel

Вообще говоря, первый операнд операции является операндом-адресатом, а другой операнд (или операнды) является исходным операндом. Например:

Команда mov берет значение из исходного операнда и помещает его в целевой операнд, так что значение 123 будет помещено в регистр eax.Первоначальный синтаксис Intel - это ассемблер Intel ASM386 (позже переданный RadiSys по лицензии, но в конечном итоге умер). С тех пор многие сборщики изобрели множество его вариаций. Кроме того, он используется в большинстве онлайн-руководств по сборке, потому что большинство этих руководств было написано, когда TASM (который использует синтаксис Intel) был доминирующим ассемблером.

Синтаксис AT&T

Синтаксис AT&T является обратным синтаксису Intel. Данные, над которыми работают, перемещаются слева направо.Вот тот же оператор, что и выше, в синтаксисе AT&T.

Есть и другие отличия от операндов:

  • Буквенные значения, такие как 123, начинаются с префикса «$» (см. Пример выше).
  • Ячейки памяти не имеют префикса: mov 123,% eax перемещает значение, хранящееся в 123, в eax.
  • Регистры имеют префикс '%'
  • При использовании регистра в качестве указателя он помещается в круглые скобки: mov (% eax),% ebx перемещает значение, хранящееся в указателе, хранящемся в eax, в ebx.
  • При использовании оператора с ячейками памяти (без регистра) после инструкции необходим суффикс. Например: movl $ 123, 123. 'l' (обозначает длинное) и требуется, чтобы сообщить ассемблеру, что значения 32-битные.
  • Указатели могут быть смещены константами путем добавления к ним префикса: 4 (% eax) указывает на 4 +% eax.
  • Указатели могут быть смещены другим регистром, записав их как: (% eax,% ebx), что указывает на% eax +% ebx
  • Наконец, вы можете объединить все это и добавить шкалу, если хотите: 4 (% eax,% ebx, 2) будет 4 +% eax +% ebx * 2

См. Также

Статьи

Внешние ссылки

  • GNU Binutils - Коллекция бесплатного программного обеспечения, включая ассемблер GNU (газ)
  • gas manual - Официальное руководство для GNU ассемблера (газ)
  • NASM - Официальный сайт Netwide Assembler: NASM
  • x86_Assembly - Викибук по написанию ассемблера для компьютеров на базе x86
  • Искусство программирования на ассемблере, электронная книга, 16-битное издание для DOS.(Более поздние выпуски сосредоточены на диалекте ассемблера высокого уровня, созданном автором.)
  • PC ASM, онлайн-книга, сборка в 32-битном защищенном режиме на x86
  • x86 Opcode and Instruction Reference, база данных инструкций и кодов операций в виде бесплатных просматриваемых, доступных для поиска и загружаемых файлов XML. Они также продают печатную версию.

Синтаксис сборки AT&T | Sig9

Обновлено: 10 мая 2006 г.

Эта статья представляет собой краткое введение в сборку AT&T. синтаксис языка, реализованный в GNU Assembler как (1) .Для первого таймера синтаксис AT&T может показаться немного запутанным, но если у вас есть опыт программирования на ассемблере, это легко догнать, если у вас есть несколько правил. Я полагаю, у тебя есть некоторое знакомство с тем, что обычно называют синтаксисом INTEL для инструкций на языке ассемблера, как описано в руководствах x86. Из-за его простоты я использую вариант NASM (Netwide Assembler) INTEL-синтаксис для указания различий между форматами.

Ассемблер GNU является частью двоичных утилит GNU (binutils) и серверной частью коллекции компиляторов GNU. Хотя как не является предпочтительным ассемблером для написания достаточно большого ассемблера программы, это жизненно важная часть современных Unix-подобных систем, особенно для взлома на уровне ядра. Часто критикуют за загадочность Синтаксис в стиле AT&T, утверждается, что как был написан с акцент на использовании в качестве серверной части для GCC, мало заботясь о "удобство для разработчиков".Если вы программист на ассемблере, то приветствуете на фоне синтаксиса INTEL вы испытаете некоторую удушающую в отношении читаемости кода и генерации кода. Тем не менее, это Следует отметить, что кодовая база многих операционных систем зависит от как от в качестве ассемблера для генерации низкоуровневого кода.

Базовый формат

Структура программы в AT&T-синтаксисе аналогична любой другой ассемблер-синтаксис, состоящий из серии директив, меток, инструкции - состоящие из мнемоники, за которой следуют не более трех операнды.Наиболее заметное различие в основах синтаксиса AT и T от порядка операндов.

Например, общий формат основной инструкции перемещения данных в INTEL-синтаксисе:

 мнемоническое назначение, источник 

, тогда как в случае AT&T общий формат -

 мнемонический источник, назначение 

Некоторым (включая меня) этот формат более интуитивно понятен. В в следующих разделах описаны типы операндов ассемблера AT&T. инструкция для архитектуры x86.

Регистры

Все имена регистров архитектуры IA-32 должны иметь префикс '%', например. % al,% bx,% ds,% cr0 и т. д.

 mov% ax,% bx 

Приведенный выше пример - это инструкция mov, которая перемещает значение из 16-битного регистра AX в 16-битный регистр BX.

Буквенные значения

Все литеральные значения должны начинаться со знака «$». Например,

mov $ 100,% bx
mov $ A,% al 

Первая инструкция перемещает значение 100 в регистр AX. а второй перемещает числовое значение ascii A в AL регистр.Чтобы было понятнее, обратите внимание, что приведенный ниже пример не является действующая инструкция,

 mov% bx, $ 100 

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

Адресация памяти

В синтаксисе AT&T память упоминается следующим образом:

 переопределение сегмента: смещение со знаком (основание, индекс, масштаб) 

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

% es: 100 (% eax,% ebx, 2) 

Обратите внимание, что смещения и масштаб не должны начинаться с префикса '$'.Еще несколько примеров с их эквивалентным синтаксисом NASM, должны сделать вещи яснее,

Операнд памяти
 GAS Операнд памяти NASM
------------------ -------------------

100 [100]
% es: 100 [es: 100]
(% eax) [eax]
(% eax,% ebx) [eax + ebx]
(% ecx,% ebx, 2) [ecx + ebx * 2]
(,% ebx, 2) [ebx * 2]
-10 (% eax) [eax-10]
% ds: -10 (% ebp) [ds: ebp-10] 
Пример инструкции,
 mov% ax, 100
mov% eax, -100 (% eax)
 

Первая инструкция перемещает значение в регистре AX на смещение 100 регистра сегмента данных (по умолчанию), а второй перемещает значение в регистре eax до [eax-100].

Размеры операндов

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

 mov $ 10, 100 

только указывает, что значение 10 должно быть перемещено в смещение памяти. 100, но не размер перевода. В NASM это делается путем добавления приведение ключевого слова byte / word / dword и т. д. к любому из операндов. В Синтаксис AT&T, это делается путем добавления суффикса - b / w / l - к инструкция.Например,

 movb $ 10,% es: (% eax) 

перемещает байтовое значение 10 в ячейку памяти [ea: eax], тогда как,

 movl $ 10,% es: (% eax) 

перемещает длинное значение (двойное слово) 10 на то же место.

Еще несколько примеров,

 movl $ 100,% ebx
pushl% eax
popw% топор 

Инструкции по передаче управления

Инструкции jmp, call, ret и т. Д. Передают управление из одного часть программы в другую. Их можно отнести к контрольным. переводит в один и тот же сегмент кода (рядом) или в разные сегменты кода (далеко).Возможные типы адресации ветвей: относительное смещение. (метка), регистр, операнд памяти и указатели смещения сегмента.

Относительные смещения указываются с помощью меток, как показано ниже.

 label1:
.
.
  jmp label1
 

Адресация ветвей с использованием регистров или операндов памяти должна быть с префиксом '*'. Чтобы указать «дальние» передачи управления, необходимо указать «l». с префиксом, как в 'ljmp', 'lcall' и т. д. Например,

 Синтаксис GAS Синтаксис NASM
========== ===========

jmp * 100 jmp рядом с [100]
звоните * 100 звоните рядом [100]
jmp *% eax jmp рядом с eax
jmp *% ecx вызов около ecx
jmp * (% eax) jmp около [eax]
звонок * (% ebx) звонок рядом с [ebx]
ljmp * 100 jmp далеко [100]
lcall * 100 дальний вызов [100]
ljmp * (% eax) jmp far [eax]
lcall * (% ebx) дальний вызов [ebx]
ret retn
lret retf
lret $ 0x100 retf 0x100

 

Смещение сегмента указателей указывается в следующем формате:

 jmp $ сегмент, $ смещение 

Например:

 jmp $ 0x10, $ 0x100000 
Если вы будете помнить об этих нескольких вещах, вы наверняка наверстаете упущенное.Что касается более подробной информации об ассемблере GNU, вы можете попробовать документацию.

Модульный ассемблер Yasm Project

Yasm - это полностью переписанный ассемблер NASM под «новой» лицензией BSD (некоторые части находятся под другими лицензиями, подробности см. В разделе КОПИРОВАНИЕ).

Yasm в настоящее время поддерживает наборы инструкций x86 и AMD64, принимает синтаксисы ассемблера NASM и GAS, выводит двоичные, ELF32, ELF64, 32- и 64-разрядные объектные форматы Mach-O, RDOFF2, COFF, Win32 и Win64 и генерирует информацию об отладке исходного кода. в форматах STABS, DWARF 2 и CodeView 8.

Yasm может быть легко интегрирован в Visual Studio 2005/2008 и 2010 для сборки синтаксического кода NASM или GAS в объектные файлы Win32 или Win64.

  • Почти полное лексирование и синтаксический анализ синтаксиса NASM.
  • Базовая поддержка синтаксиса TASM.
  • Почти полное лексирование и синтаксический анализ синтаксиса GAS (ассемблер GNU).
  • Поддержка AMD64 (включается с помощью «BITS 64», «-m amd64» или выбора явно выходного формата 64-битного объекта, такого как «-f win64» или «-f elf64»)
  • Разрешены 64-битные (и более крупные) целочисленные константы (включая математические операции).
  • Оптимизатор размера быстрого перехода эквивалентен многопроходным оптимизаторам других ассемблеров или лучше их.
  • Поддержка нескольких форматов объектов:
  • Форматы отладки
  • STABS, DWARF2 и CodeView.
  • Переносимость; в настоящее время компилируется на:
    • UNIX и совместимые (32- и 64-битные FreeBSD и Linux протестированы, автоконфигурация на основе GNU configure)
    • DOS (с использованием DJGPP)
    • Windows (с использованием Visual C ++ или CygWin).
  • Поддержка интернационализации через GNU gettext.

Основное внимание в Yasm уделяется не интерфейсу командной строки yasm ; скорее, это библиотека Libyasm и связанные с ней загружаемые модули (документацию см. в справочниках программистов). Libyasm и модули предназначены для повторного использования в других программах, работающих с кодом на уровне сборки (компиляторы, отладчики и т. Д.). Когда-нибудь libyasm может быть упакован отдельно от остальной части Yasm .

  • Синтаксический анализатор рекурсивного спуска синтаксиса NASM и синтаксиса GAS.

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

  • Лексер синтаксиса NASM, написанный на re2c.Высокоэффективный генератор сканеров (почти всегда быстрее, чем lex / flex), он также легко встраивается благодаря своей методологии генерации кода, что позволяет использовать несколько сканеров re2c в различных местах в yasm, не беспокоясь о конфликтах имен.

  • Лексер синтаксиса GAS, написанный на re2c.

  • Многие модульные интерфейсы хотя бы внешне доработаны. Это все еще та область, в которой нужно много работать.

  • Небольшой набор переносимых эквивалентов полезных функций, которые являются стандартными для некоторых систем (обнаруживаются через configure), например набор функций queue (3), strdup, strcasecmp и mergesort.

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

% PDF-1.7 % 25316 0 объект > эндобдж xref 25316 277 0000000016 00000 н. 0000009201 00000 н. 0000009391 00000 п. 0000009430 00000 н. 0000009574 00000 н. 0000009721 00000 н. 0000009909 00000 н. 0000009989 00000 н. 0000010691 00000 п. 0000011881 00000 п. 0000013074 00000 п. 0000014259 00000 п. 0000014470 00000 п. 0000014631 00000 п. 0000036298 00000 п. 0000040081 00000 п. 0000040316 00000 п. 0000040542 00000 п. 0000051606 00000 п. 0000051832 00000 п. 0000062920 00000 н. 0000063151 00000 п. 0000063214 00000 п. 0000063327 00000 п. 0000063455 00000 п. 0000063542 00000 п. 0000063623 00000 п. 0000063773 00000 п. 0000063912 00000 п. 0000064068 00000 п. 0000064215 00000 н. 0000064351 00000 п. 0000064504 00000 п. 0000064647 00000 п. 0000064735 00000 п. 0000064836 00000 п. 0000064991 00000 п. 0000065095 00000 п. 0000065203 00000 п. 0000065319 00000 п. 0000065444 00000 п. 0000065565 00000 п. 0000065676 00000 п. 0000065789 00000 п. 0000065897 00000 п. 0000066013 00000 п. 0000066141 00000 п. 0000066243 00000 п. 0000066367 00000 п. 0000066529 00000 п. 0000066640 00000 п. 0000066782 00000 п. 0000066899 00000 н. 0000067031 00000 п. 0000067144 00000 п. 0000067327 00000 п. 0000067434 00000 п. 0000067539 00000 п. 0000067666 00000 п. 0000067781 00000 п. 0000067932 00000 п. 0000068052 00000 п. 0000068196 00000 п. 0000068311 00000 п. 0000068428 00000 п. 0000068520 00000 п. 0000068622 00000 п. 0000068739 00000 п. 0000068852 00000 п. 0000069027 00000 н. 0000069137 00000 п. 0000069266 00000 п. 0000069395 00000 п. 0000069542 00000 п. 0000069664 00000 п. 0000069782 00000 п. 0000069917 00000 н. 0000070087 00000 п. 0000070194 00000 п. 0000070308 00000 п. 0000070443 00000 п. 0000070588 00000 п. 0000070732 00000 п. 0000070921 00000 п. 0000071003 00000 п. 0000071150 00000 п. 0000071289 00000 п. 0000071408 00000 п. 0000071552 00000 п. 0000071698 00000 п. 0000071828 00000 п. 0000071971 00000 п. 0000072119 00000 п. 0000072265 00000 п. 0000072392 00000 п. 0000072538 00000 п. 0000072686 00000 п. 0000072833 00000 п. 0000072974 00000 п. 0000073117 00000 п. 0000073264 00000 п. 0000073399 00000 п. 0000073540 00000 п. 0000073677 00000 п. 0000073818 00000 п. 0000073964 00000 н. 0000074101 00000 п. 0000074248 00000 п. 0000074389 00000 п. 0000074513 00000 п. 0000074694 00000 п. 0000074795 00000 п. 0000074897 00000 н. 0000075034 00000 п. 0000075155 00000 п. 0000075281 00000 п. 0000075395 00000 п. 0000075574 00000 п. 0000075674 00000 п. 0000075767 00000 п. 0000075885 00000 п. 0000076007 00000 п. 0000076120 00000 п. 0000076225 00000 п. 0000076343 00000 п. 0000076462 00000 н. 0000076560 00000 п. 0000076664 00000 п. 0000076770 00000 п. 0000076892 00000 п. 0000076999 00000 п. 0000077098 00000 п. 0000077214 00000 п. 0000077334 00000 п. 0000077441 00000 п. 0000077552 00000 п. 0000077651 00000 п. 0000077758 00000 п. 0000077879 00000 п. 0000077993 00000 п. 0000078117 00000 п. 0000078238 00000 п. 0000078380 00000 п. 0000078518 00000 п. 0000078635 00000 п. 0000078741 00000 п. 0000078849 00000 п. 0000078957 00000 п. 0000079056 00000 п. 0000079154 00000 п. 0000079262 00000 п. 0000079369 00000 п. 0000079467 00000 п. 0000079570 00000 п. 0000079708 00000 п. 0000079808 00000 п. 0000079931 00000 н. 0000080082 00000 п. 0000080193 00000 п. 0000080289 00000 п. 0000080406 00000 п. 0000080527 00000 п. 0000080645 00000 п. 0000080757 00000 п. 0000080868 00000 п. 0000080979 00000 п. 0000081095 00000 п. 0000081208 00000 п. 0000081322 00000 п. 0000081432 00000 п. 0000081541 00000 п. 0000081649 00000 п. 0000081788 00000 п. 0000081918 00000 п. 0000082053 00000 п. 0000082152 00000 п. 0000082286 00000 п. 0000082404 00000 п. 0000082528 00000 п. 0000082694 00000 п. 0000082799 00000 н. 0000082918 00000 п. 0000083051 00000 п. 0000083212 00000 п. 0000083348 00000 п. 0000083461 00000 п. 0000083614 00000 п. 0000083735 00000 п. 0000083843 00000 п. 0000083982 00000 п. 0000084107 00000 п. 0000084248 00000 п. 0000084368 00000 п. 0000084470 00000 п. 0000084572 00000 п. 0000084688 00000 п. 0000084793 00000 п. 0000084949 00000 п. 0000085115 00000 п. 0000085257 00000 п. 0000085385 00000 п. 0000085495 00000 п. 0000085609 00000 п. 0000085719 00000 п. 0000085823 00000 п. 0000085925 00000 п. 0000086028 00000 п. 0000086129 00000 п. 0000086233 00000 п. 0000086336 00000 п. 0000086438 00000 п. 0000086537 00000 п. 0000086639 00000 п. 0000086741 00000 п. 0000086842 00000 н. 0000086943 00000 п. 0000087045 00000 п. 0000087134 00000 п. 0000087220 00000 п. 0000087324 00000 п. 0000087422 00000 п. 0000087526 00000 п. 0000087632 00000 п. 0000087734 00000 п. 0000087843 00000 п. 0000087949 00000 п. 0000088056 00000 п. 0000088164 00000 п. 0000088272 00000 н. 0000088371 00000 п. 0000088469 00000 н. 0000088568 00000 п. 0000088666 00000 п. 0000088764 00000 п. 0000088867 00000 п. 0000088976 00000 п. 0000089078 00000 п. 0000089178 00000 п. 0000089279 00000 н. 0000089380 00000 п. 0000089480 00000 п. 0000089590 00000 н. 0000089702 00000 п. 0000089874 00000 п. 0000089981 00000 п. 00000

00000 п. 00000 00000 н. 00000 00000 п. 00000

00000 п. 00000

00000 п. 00000 00000 п. 00000 00000 п. 00000
00000 п. 00000

00000 п. 00000
00000 п. 00000 00000 п. 00000 00000 п. 00000 00000 п. 00000 00000 п. 00000

00000 п. 00000 00000 п. 00000 00000 п. 00000

00000 п. 00000 00000 п. 0000092143 00000 п. 0000092239 00000 п. 0000092335 00000 п. 0000092431 00000 п. 0000092527 00000 н. 0000092623 00000 п. 0000092719 00000 п. 0000092815 00000 п. 0000092911 00000 п. 0000093007 00000 п. 0000093103 00000 п. 0000093199 00000 п. 0000005836 00000 н. трейлер ] >> startxref 0 %% EOF 25592 0 объект > поток xY TTU3 ›a`aP: ˁAN $ yD # 7 脭 r.Ќ [X2sēc! S>) / o3, mN ݹ sO [g

L] z | -l; c6 /jΏϙ.ĕkW$ToE{.}4Klb+cM9mIQWk\ҳҪ8;U0ptingX&-q0CY)q gίC9S4k9Yf} ݱ o> Nwg% z4sc` [gpw; WxҺNY} p` / w-, h8b> = r;]> ޯ + LkOVy '˪? -Ou8u = 6 = PFk> n; RS8_ \ R ~ yW f0tjR7Vm ~ SmH9n

iɳ qyxx @ Z: I? J: 0΁] 0XԄ5w.lWѶ $} Q1] Keire

Intel против синтаксиса AT&T

x86 (32- и 64-разрядный) имеет два альтернативных синтаксиса. Некоторые ассемблеры могут работать только с одним или другим, в то время как некоторые могут работать с оба. В этом курсе мы в первую очередь будем использовать синтаксис Intel , так как именно он в учебнике используется, но вы должны знать синтаксис AT&T , так как он стандарт для Linux, и поэтому многие онлайн-ресурсы используют его.

В этой таблице приведены основные различия между синтаксисом Intel и AT&T:

Intel AT&T
Комментарии ; //
Инструкции Без тегов прибавить Помечено размерами операндов: addq
Регистры eax , ebx и т. Д. % eax , % ebx и т. Д.
Немедленное 0x100 $ 0x100
Косвенный [eax] (% eax)
Непрямое общее [основание + рег + рег * масштаб + смещение] смещение (рег, рег, масштаб)

Обратите внимание, что в обобщенном косвенном формате синтаксис Intel будет компьютерным base + displacement для вас, так как коды операций действительно позволяют только один немедленное перемещение.В синтаксисе AT&T вы должны сделать это самостоятельно, используя результат суммы в качестве третьего значения в скобках.

Основное различие между синтаксисом Intel и AT&T состоит в том, что Intel оставляет размеров операндов команд неявно, в то время как AT&T делает их явными, добавляя суффиксы к имени инструкции. Примером может служить добавление . инструкция, которая складывает два значения вместе:

Как указано в синтаксисе Intel, это добавляет два 32-битных регистра вместе (оба eax и ebx являются 32-битными) и сохраняет результат в eax .(Инструкции Intel сначала имеют регистр назначения, а второй - регистр источника.) и источник, и место назначения 32-битные, ассемблер знает, что ему нужно для передачи в 32-битном добавьте инструкцию . В синтаксисе AT&T та же инструкция будет

Имена регистров в синтаксисе AT&T имеют префикс % , и порядок меняется местами, но самая большая разница - это суффикс q в инструкции add . q это сокращение от «quadword», т.е.е., 32-битное значение. Суффикс необходим для обозначения ассемблерный размер операндов; это не сделает вывод о правильной инструкции использовать просто из регистров размеров.

Инструкции, которые могут смешивать операнды разных размеров, будут иметь два (или иногда три) суффиксы. Например, чтобы добавить младшие 16 бит ebx в eax , мы сделал бы

в Intel, но в AT&T это будет

, где d означает «двойное слово». z указывает, что это беззнаковый сложение (нулевое расширение).Если бы мы хотели подписанное дополнение, мы бы использовали s (расширение знака).

.

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *