Ассемблер как сделать программу

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

_DATA SEGMENT ExitCode dd 0 dwNum_1 dd 0 dwNub_2 dd 0 dwResult dd 0 _DATA ENDS

Первая переменная ExitCode используется для передачи в функцию выхода из программы ExitProcess, ноль означает корректное закрытые. Переменные dwNum_1 и dwNum_2 — это наши входные параметры, переменная dwResult — для хранения результата работы функции. dd — обозначает тип создаваемых переменных (double word) что соответствует 32 битам. Типы данных в masm32 рассмотрены в статье Двоичные числа в Assembler. Все 4 переменные, созданные в примере выше инициализированы значением 0, если начальное значение переменной не имеет значения, то можно инициализировать переменную значением ?.

Создание тела функции в Assembler masm32

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

АССЕМБЛЕР в 2023? Что такое «Reverse Engineering» и «Cyber Security». Показываю как ломают софт.


Процедуры определяются с помощью директывы proc. Конец тела функции определяются с помощью директывы endp:

AddProc proc AddProc endp

В примере AddProc — это имя процедуры, которую мы создаем.

Передача параметров в функцию через стек

Параметры в функции в Assembler передаются через стек. Параметры помещаются в стек в обратном порядке (от последнего к первому), делается это потому, что получение значений из стека идет по принципу «первый пришел — последний ушел». После каждого помещения параметра в стек значение регистра ESP уменьшается на 4 байта (регистр ESP указывает на вершину стекa):

Добавление параметра функции в стек

После каждого добавления параметра в стек происходит сдвиг регистра ESP на 4 байта, т.е. команду PUSH можно представить как совокупность двух команд:

sub ESP, 4 mov [ESP], arg

Первой командой значение регистра ESP уменьшается на 4 байта, а второй командой происходит помещение в стек (квадратные скобки означают помещение значения по указанному в скобках адресу) значения аргумента arg:

В стек добавлены все аргументы функции

Как мы уже узнали, параметры функции помещаются в стек в обратном порядке. После команд push следует команда вызова функции call:

В отладчике этот кусочек кода будет выглядет так:

Помещение параметров в стек в отладчике

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

Пишем тетрис на ассемблере под DOS (x86)

В стек помещается адрес возврата из функции

Команду CALL можно представить как совокупность двух команд: сначала в стек помещается адрес возврата командой push, а после этого происходит переход на адрес вызванной процедуры.

Извлечение значений параметров в функции

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

push ebp mov ebp, esp

Далее в стек могу помещаться значения локальных переменных для функции (что соответственно приведет к изменению значения регистра ESP), но с помощью значения регистра EBP мы сможем получить доступ как к параметрам функции, так и к значениям локальных переменных. Если к значению регистра EBP прибавить смещение 8, то мы получим указатель на первый параметр функции, если прибавить 12, то получим указатель на второй параметр функции и т.д. Если из значения регистра EBP вычесть 4, то получим указатель на первую локальную переменную функции, если вычесть 8, то получим указатель на вторую локальную переменную функции и т.д.:

Доступ к параметрам функции

Восстановление значений регистров ESP и EBP

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

mov esp, ebp pop ebp

С помощью первой команды восстанавливается значение регистра ESP и он начинает указывать на вершину стека, как на рисунке:

Восстановление значения регистра ESP

Команда pop ebp вытаскивает из стека значение регистра EBP до вызова процедуры и кладет его в регистр EBP, кроме этого происходит смещение значения регистра ESP на 4 байта и он начинает указывать на адрес возврата из функции:

Восстановление значения регистра EBP

Возврат из функции

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

Возврат из функции

Инструкция RET осуществляет переход на адрес возврата из стека и одновременно смещает значение регистра ESP на N*4 байт, где N — это количество параметров, переданных в функцию. После этого регистр ESP начинает вновь указывать на дно стека, как было до вызова функции.
В нашем случае инструкция RET будет выглядеть как ret 8 , т.к. мы передавали два параметра, по 4 байта каждый.

Наполнение тела функции

  • Помимо регистров ESP и EBP необходимо следить за сохранностью значений еще трех регистров: EBX, ESI, EDI. Для этой цели значения этих регистров прячутся в стек, подобно регистру EBP и восстанавливаются из стека перед выходом из функции.
  • По стандарту для возвращения значения из функции используется регистр EAX (это не является обязательным условием).

AddProc proc push ebp mov ebp, esp push ebx push esi push edi ;————————— mov eax, dword ptr[ebp+8] mov ebx, dword ptr[ebp+0ch] add eax, ebx ;————————— pop edi pop esi pop ebx mov esp, ebp pop ebp ret 8 AddProc endp

В теле функции в регистры EAX и EBX перемещаются значения параметров, полученные из стека с помощью смещений на 8 и 12 байт. После чего результат сложения этих двух значений помещается в регистр EAX. Заготовку тела функции (без сложения чисел) сразу добавляю в свой список сниппетов для файлов расширения .asm редактора vim.

Читайте также:
Пин код для программы 1с

Полный листинг программы

.586P .model flat, stdcall ;————————————- includelib C:masm32libkernel32.lib extern [email protected]:near ;————————————- _DATA SEGMENT ExitCode dd 0 dwNum_1 dd 0 dwNum_2 dd 0 dwResult dd 0 _DATA ENDS _TEXT SEGMENT START: mov dwNum_1, 5 mov dwNum_2, 10 push dwNum_2 push dwNum_1 call AddProc mov dwResult, eax push [ExitCode] call [email protected] ;————————————- AddProc proc push ebp mov ebp, esp push ebx push esi push edi ;—————————— mov eax, dword ptr[ebp+8] mov ebx, dword ptr[ebp+0ch] add eax, ebx ;—————————— pop edi pop esi pop ebx mov esp, ebp pop ebp ret 8 AddProc endp _TEXT ENDS END START

В отладчике программа будет выглядеть вот так:

Функция сложения в отладчике

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

Болтовня ничего не стоит. Покажите мне код.

Источник: rate1.site

19. Простые процедуры в ассемблер

Для работы с процедурами предназначены команды CALL и RET . С помощью команды CALL выполняется вызов процедуры. Эта команда работает почти также, как команда безусловного перехода (JMP), но с одним отличием — одновременно в стек сохраняется текущее значение регистра IP. Это позволяет потом вернуться к тому месту в коде, откуда была вызвана процедура.

В качестве операнда указывается адрес перехода, который может быть непосредственным значением (меткой), 16-разрядным регистром (кроме сегментных) или ячейкой памяти, содержащей адрес. Возврат из процедуры выполняется командой RET . Эта команда восстанавливает значение из вершины стека в регистр IP. Таким образом, выполнение программы продолжается с команды, следующей сразу после команды CALL. Обычно код процедуры заканчивается этой командой. Команды CALL и RET не изменяют значения флагов (кроме некоторых особых случаев в защищенном режиме). Небольшой пример разных способов вызова процедуры:

use16 ;Генерировать 16-битный код org 100h ;Программа начинается с адреса 100h mov ax,myproc mov bx,myproc_addr xor si,si call myproc ;Вызов процедуры (адрес перехода — myproc) call ax ;Вызов процедуры по адресу в AX call [myproc_addr] ;Вызов процедуры по адресу в переменной call word [bx+si] ;Более сложный способ задания адреса 😉 mov ax,4C00h ; int 21h ;/ Завершение программы ;———————————————————————- ;Процедура, которая ничего не делает myproc: nop ;Код процедуры ret ;Возврат из процедуры ;———————————————————————- myproc_addr dw myproc ;Переменная с адресом процедуры

Ближние и дальние вызовы процедур

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

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

Передача параметров

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

Возвращаемое значение

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

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

Сохранение регистров

Хорошим приёмом является сохранение регистров, которые процедура изменяет в ходе своего выполнения. Это позволяет вызывать процедуру из любой части кода и не беспокоиться, что значения в регистрах будут испорчены. Обычно регистры сохраняются в стеке с помощью команды PUSH, а перед возвратом из процедуры восстанавливаются командой POP. Естественно, восстанавливать их надо в обратном порядке. Примерно вот так:

myproc: push bx ;Сохранение регистров push cx push si . ;Код процедуры pop si ;Восстановление регистров pop cx pop bx ret ;Возврат из процедуры

Пример

Для примера напишем процедуру для вывода собщения в рамке и протестируем её работу, выведя несколько сообщений. В качестве параметра ей будет передаватся адрес строки в регистре BX.

Строка должна заканчиваться символом ‘$’ . Для упрощения процедуры можно разбить задачу на подзадачи и написать соответствующие процедуры. Прежде всего нужно вычислить длину строки, чтобы знать ширину рамки. Процедура get_length вычисляет длину строки (адрес передаётся также в BX) и возвращает её в регистре AX.

Для рисования горизонтальной линии из символов предназначена процедура draw_line. В DL передаётся код символа, а в CX — количество символов, которое необходимо вывести на экран. Эта процедура не возвращает никакого значения. Для вывода 2-х символов конца строки написана процедура print_endline. Она вызывается без параметров и тоже не возвращает никакого значения.

Коды символов для рисования рамок можно узнать с помощью таблицы символов кодировки 866 или можно воспользоваться стандартной программой Windows «Таблица символов», выбрав шрифт Terminal.

use16 ;Генерировать 16-битный код org 100h ;Программа начинается с адреса 100h jmp start ;Переход на метку start ;———————————————————————- msg1 db ‘Hello!$’ msg2 db ‘asmworld.ru$’ msg3 db ‘Press any key. $’ ;———————————————————————- start: mov bx,msg1 call print_message ;Вывод первого сообщения mov bx,msg2 call print_message ;Вывод второго сообщения mov bx,msg3 call print_message ;Вывод третьего сообщения mov ah,8 ;Ввод символа без эха int 21h mov ax,4C00h ; int 21h ;/ Завершение программы ;———————————————————————- ;Процедура вывода сообщения в рамке ;В BX передаётся адрес строки print_message: push ax ;Сохранение регистров push cx push dx call get_length ;Вызов процедуры вычисления длины строки mov cx,ax ;Копируем длину строки в CX mov ah,2 ;Функция DOS 02h — вывод символа mov dl,0xDA ;Левый верхний угол int 21h mov dl,0xC4 ;Горизонтальная линия call draw_line ;Вызов процедуры рисования линии mov dl,0xBF ;Правый верхний угол int 21h call print_endline ;Вызов процедуры вывода конца строки mov dl,0xB3 ;Вертикальная линия int 21h mov ah,9 ;Функция DOS 09h — вывод строки mov dx,bx ;Адрес строки в DX int 21h mov ah,2 ;Функция DOS 02h — вывод символа mov dl,0xB3 ;Вертикальная линия int 21h call print_endline ;Вызов процедуры вывода конца строки mov dl,0xC0 ;Левый нижний угол int 21h mov dl,0xC4 ;Горизонтальная линия call draw_line mov dl,0xD9 ;Правый нижний угол int 21h call print_endline ;Вызов процедуры вывода конца строки pop dx ;Восстановление регистров pop cx pop ax ret ;Возврат из процедуры ;———————————————————————- ;Процедура вычисления длины строки (конец строки — символ ‘$’). ;В BX передаётся адрес строки. ;Возвращает длину строки в регистре AX. get_length: push bx ;Сохранение регистра BX xor ax,ax ;Обнуление AX str_loop: cmp byte[bx],’$’ ;Проверка конца строки je str_end ;Если конец строки, то выход из процедуры inc ax ;Инкремент длины строки inc bx ;Инкремент адреса jmp str_loop ;Переход к началу цикла str_end: pop bx ;Восстановление регистра BX ret ;Возврат из процедуры ;———————————————————————- ;Процедура рисования линии из символов. ;В DL — символ, в CX — длина линии (кол-во символов) draw_line: push ax ;Сохранение регистров push cx mov ah,2 ;Функция DOS 02h — вывод символа drl_loop: int 21h ;Обращение к функции DOS loop drl_loop ;Команда цикла pop cx ;Восстановление регистров pop ax ret ;Возврат из процедуры ;———————————————————————- ;Процедура вывода конца строки (CR+LF) print_endline: push ax ;Сохранение регистров push dx mov ah,2 ;Функция DOS 02h — вывод символа mov dl,13 ;Символ CR int 21h mov dl,10 ;Символ LF int 21h pop dx ;Восстановление регистров pop ax ret ;Возврат из процедуры

Читайте также:
В каких дошкольных программах есть нравственное воспитание

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

Отладчик Turbo Debugger

Небольшое замечание по поводу использования отладчика. В Turbo Debugger нажимайте F7 («Trace into»), чтобы перейти к коду вызываемой процедуры. При нажатии F8(«Step over») процедура будет выполнена сразу целиком.

Упражнение

Объявите в программе 2-3 массива слов без знака. Количество элементов каждого массива должно быть разным и храниться в отдельной 16-битной переменной без знака. Напишите процедуру для вычисления среднего арифметического массива чисел. В качестве параметров ей будет передаваться адрес массива и количество элементов, а возвращать она будет вычисленное значение.

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

Предыдущий урок Список уроков Следующий урок

Источник: pro-prof.com

Справочник по командам ассемблера AVR

avr commands

Справочник по системе команд микроконтроллеров AVR основан на переводе документации от Atmel. Помимо этого сюда добавлено больше примеров из практики, в частности, примеры для ассемблера AVR GCC.

Чтобы быстро перейти к нужной команде достаточно ввести её имя. Также можно выбрать команду из списка внизу.

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

Введите имя команды в поле выше

Логические операции

Мнемоника Описание Операция Флаги
AND Rd, Rr Логическое «И» двух регистров Rd ← Rd and Rr Z, N, V
ANDI Rd, K Логическое «И регистра и константы Rd ← Rd and K Z, N, V
EOR Rd, Rr Исключающее «ИЛИ» двух регистров Rd ← Rd xor Rr Z, N, V
OR Rd, Rr Логическое «ИЛИ» двух регистров Rd ← Rd or Rr Z, N, V
ORI Rd, K Логическое «ИЛИ» регистра и константы Rd ← Rd or K Z, N, V
COM Rd Перевод в обратный код Rd ← 0xFF — Rd Z, C, N, V
NEG Rd Перевод в дополнительный код Rd ← 0 — Rd Z, C, N, V, H
CLR Rd Очистка регистра Rd ← Rd xor Rd Z, N, V
SER Rd Установка всех разрядов регистра Rd ← 0xFF
TST Rd Проверка регистра на отрицательное (нулевое) значение Rd ← Rd and Rd Z, N, V

Арифметические операции

Мнемоника Описание Операция Флаги
ADD Rd, Rr Сложение двух регистров Rd ← Rd + Rr Z, C, N, V, H
ADC Rd, Rr Сложение двух регистров с переносом Rd ← Rd + Rr + С Z, C, N, V, H
SUB Rd, Rr Вычитание двух регистров Rd ← Rd — Rr Z, C, N, V, H
SBC Rd, Rr Вычитание двух регистров с заёмом Rd ← Rd — Rr — С Z, C, N, V, H
ADIW Rd, K Сложение регистровой пары с константой R(d+1):Rd ← R(d+1):Rd + K Z, C, N, V, S
SBIW Rd, K Вычитание константы из регистровой пары R(d+1):Rdl ← R(d+1):Rd — K Z, C, N, V, S
SUBI Rd, K Вычитание константы из регистра Rd ← Rd — K Z, C, N, V, H
SBCI Rd, K Вычитание константы из регистра с заёмом Rd ← Rd — K — С Z, C, N, V, H
INC Rd Инкремент регистра Rd ← Rd + 1 Z, N, V
DEC Rd Декремент регистра Rd ← Rd – 1 Z, N, V
MUL Rd, Rr Умножение чисел без знака R1:R0 ← Rd * Rr Z, C
MULS Rd, Rr Умножение чисел со знаком R1:R0 ← Rd * Rr Z, C
MULSU Rd, Rr Умножение числа со знаком с числом без знака R1:R0 ← Rd * Rr Z, C
FMUL Rd, Rr Умножение дробных чисел без знака R1:R0 ← (Rd * Rr) Z, C
FMULS Rd, Rr Умножение дробных чисел со знаком R1:R0 ← (Rd * Rr) Z, C
FMULSU Rd, Rr Умножение дробного числа со знаком с числом без знака R1:R0 ← (Rd * Rr) Z, C

Битовые операции

Мнемоника Описание Операция Флаги
CBR Rd, K Очистка разрядов регистра Rd ← Rd and (0FFH – K) Z, N, V
SBR Rd, K Установка разрядов регистра Rd ← Rd or K Z, N, V
CBI P, b Сброс разряда I/O-регистра P.b ← 0
SBI P, b Установка разряда I/O-регистра P.b ← 1
BCLR s Сброс флага SREG SREG.s ← 0 SREG.s
BSET s Установка флага SREG SREG.s ← 1 SREG.s
BLD Rd, b Загрузка разряда регистра из флага T Rd.b ← T
BST Rr, b Запись разряда регистра во флаг T T ← Rd.b T
CLC Сброс флага переноса C ← 0 C
SEC Установка флага переноса C ← 1 C
CLN Сброс флага отрицательного числа N ← 0 N
SEN Установка флага отрицательного числа N ← 1 N
CLZ Сброс флага нуля Z ← 0 Z
SEZ Установка флага нуля Z ← 1 Z
CLI Общий запрет прерываний I ← 0 I
SEI Общее разрешение прерываний I ← 1 I
CLS Сброс флага знака S ← 0 S
SES Установка флага знака S ← 1 S
CLV Сброс флага переполнения дополнительного кода V ← 0 V
SEV Установка флага переполнения дополнительного кода V ← 1 V
CLT Сброс пользовательского флага T T ← 0 T
SET Установка пользовательского флага T T ← 1 T
CLH Сброс флага половинного переноса H ← 0 H
SEH Установка флага половинного переноса H ← 1 H
Читайте также:
Как работает программа плов в мультиварке

Операции сравнения

Мнемоника Описание Операция Флаги
CP Rd, Rr Сравнение двух регистров Если (Rd – Rr) Z, N, V, C, H
CPC Rd, Rr Сравнение регистров с учётом переноса Если (Rd – Rr — C) Z, N, V, C, H
CPI Rd, K Сравнение регистра с константой Если (Rd – K) Z, N, V, C, H
CPSE Rd, Rr Сравнение регистров и пропуск следующей команды если они равны Если (Rd = Rr) PC ← PC + 2 (или 3)

Операции сдвига

Мнемоника Описание Операция Флаги
ASR Rd Арифметический сдвиг вправо Rd(i) ← Rd(i+1) (n=0..6), C ← Rd(0) Z, C, N, V
LSL Rd Логический сдвиг влево Rd(i+1) ← Rd(i), Rd(0) ← 0, C ← Rd(7) Z, C, N, V
LSR Rd Логический сдвиг вправо Rd(i) ← Rd(i+1), Rd(7) ← 0, C ← Rd(0) Z, C, N, V
ROL Rd Сдвиг влево через перенос Rd(i+1) ← Rd(i), Rd(0) ← C, C ← Rd(7) Z, C, N, V
ROR Rd Сдвиг вправо через перенос Rd(i) ← Rd(i+1), Rd(7) ← C, C ← Rd(0) Z, C, N, V
SWAP Rd Обмен местами тетрад Rd(3..0) ↔ Rd(7..4)

Операции пересылки данных

Мнемоника Описание Операция Флаги
MOV Rd, Rr Пересылка между регистрами Rd ← Rr
MOVW Rd, Rr Пересылка между парами регистров R(d +1):Rd ← R(r+1):Rr
LDI Rd, K Загрузка константы в регистр Rd ← K
LD Rd, X Косвенное чтение Rd ← [X]
LD Rd, X+ Косвенное чтение с пост-инкрементом Rd ← [X], X ← X + 1
LD Rd, -X Косвенное чтение с пред-декрементом X ← X — 1, Rd ← [X]
LD Rd, Y Косвенное чтение Rd ← [Y]
LD Rd, Y+ Косвенное чтение с пост-инкрементом Rd ← [Y], Y ← Y + 1
LD Rd, -Y Косвенное чтение с пред-декрементом Y ← Y — 1, Rd ← [Y]
LDD Rd, Y+q Косвенное чтение со смещением Rd ← [Y+q]
LD Rd, Z Косвенное чтение Rd ← [Z]
LD Rd, Z+ Косвенное чтение с пост-инкрементом Rd ← [Z], Z ← Z + 1
LD Rd, -Z Косвенное чтение с пред-декрементом Z ← Z — 1, Rd ← [Z]
LDD Rd, Z+q Косвенное чтение со смещением Rd ← [Z+q]
LDS Rd, A Непосредственное чтение из ОЗУ Rd ← [A]
ST X, Rr Косвенная запись [X] ← Rr
ST X+, Rr Косвенная запись с пост-инкрементом [X] ← Rr, X ← X + 1
ST -X, Rr Косвенная запись с пред-декрементом X ← X — 1, [X] ← Rr
ST Y, Rr Косвенная запись [Y] ← Rr
ST Y+, Rr Косвенная запись с пост-инкрементом [Y] ← Rr, Y ← Y + 1
ST -Y, Rr Косвенная запись с пред-декрементом Y ← Y — 1, [Y] ← Rr
STD Y+q, Rr Косвенная запись со смещением [Y+q] ← Rr
ST Z, Rr Косвенная запись [Z] ← Rr
ST Z+, Rr Косвенная запись с пост-инкрементом [Z] ← Rr, Z ← Z + 1
ST -Z, Rr Косвенная запись с пред-декрементом Z ← Z — 1, [Z] ← Rr
STD Z+q, Rr Косвенная запись со смещением [Z+q] ← Rr
STS A, Rr Непосредственная запись в ОЗУ [A] ← Rr
LPM Загрузка данных из памяти программы R0 ←
LPM Rd, Z Загрузка данных из памяти программы в регистр Rd ←
LPM Rd, Z+ Загрузка данных из памяти программы с пост-инкрементом Z Rd ← , Z ← Z + 1
ELPM Расширенная загрузка данных из памяти программы R0 ←
ELPM Rd, Z Расширенная загрузка данных из памяти программы в регистр Rd ←
ELPM Rd, Z+ Расширенная загрузка данных из памяти программы с пост-инкрементом Z Rd ← , Z ← Z + 1
SPM Запись в программную память ← R1:R0
IN Rd, P Пересылка из I/O-регистра в регистр Rd ← P
OUT P, Rr Пересылка из регистра в I/O-регистр P ← Rr
PUSH Rr Сохранение регистра в стеке STACK ← Rr
POP Rd Извлечение регистра из стека Rd ← STACK

Безусловные переходы

Мнемоника Описание Операция Флаги
RJMP A Относительный безусловный переход PC ← PC + A + 1
JMP A Длинный безусловный переход PC ← A
IJMP Непрямой безусловный переход PC ← Z
EIJMP Расширенный непрямой безусловный переход PC ← Z:EIND
RCALL A Относительный вызов подпрограммы PC ← PC + A + 1
CALL A Длинный вызов подпрограммы PC ← A
ICALL Непрямой вызов подпрограммы PC ← Z
EICALL Расширенный непрямой вызов подпрограммы PC ← Z:EIND
RET Возврат из подпрограммы PC ← STACK
RETI Возврат из подпрограммы обработки прерываний PC ← STACK I

Условные переходы

Все команды этой группы выполняют переход (PC ← PC + A + 1) при разных условиях.

Мнемоника Описание Условие Флаги
BRBC s, A Переход если флаг S сброшен Если SREG(S) = 0
BRBS s, A Переход если флаг S установлен Если SREG(S) = 1
BRCS A Переход по переносу Если C = 1
BRCC A Переход если нет переноса Если C = 0
BREQ A Переход если равно Если Z = 1
BRNE A Переход если не равно Если Z = 0
BRSH A Переход если больше или равно Если C = 0
BRLO A Переход если меньше Если C = 1
BRMI A Переход если отрицательное значение Если N = 1
BRPL A Переход если положительное значение Если N = 0
BRGE A Переход если больше или равно (со знаком) Если (N и V) = 0
BRLT A Переход если меньше (со знаком) Если (N или V) = 1
BRHS A Переход по половинному переносу Если H = 1
BRHC A Переход если нет половинного переноса Если H = 0
BRTS A Переход если флаг T установлен Если T = 1
BRTC A Переход если флаг T сброшен Если T = 0
BRVS A Переход по переполнению дополнительного кода Если V = 1
BRVC A Переход если нет переполнения дополнительного кода Если V = 0
BRID A Переход если прерывания запрещены Если I = 0
BRIE A Переход если прерывания разрешены Если I = 1
SBRC Rd, K Пропустить следующую команду если бит в регистре очищен Если Rd[K] = 0
SBRS Rd, K Пропустить следующую команду если бит в регистре установлен Если Rd[K] = 1
SBIC A, b Пропустить следующую команду если бит в регистре ввода/вывода очищен Если I/O(A, b) = 0
SBIS A, b Пропустить следующую команду если бит в регистре ввода/вывода установлен Если I/O(A, b) = 1

Управление устройством

Мнемоника Описание Операция Флаги
NOP Нет операции
SLEEP Переход в «спящий» режим
WDR Сброс сторожевого таймера
BREAK Приостановка программы (используется отладчиком)

Источник: trolsoft.ru

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru