Форум программистов, компьютерный форум, киберфорум
Assembler, MASM, TASM
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.63/2256: Рейтинг темы: голосов - 2256, средняя оценка - 4.63
Ушел с форума
Автор FAQ
 Аватар для Mikl___
16373 / 7685 / 1080
Регистрация: 11.11.2010
Сообщений: 13,759
10.11.2013, 18:47  [ТС]
ГЛАВА 6
СИНТАКСИС АССЕМБЛЕРА
(часть 3/3)


Директивы эквивалентности и присваивания
Директива эквивалентности
Допустим, Вы пишете на языке ассемблера компьютерную игрушку. Через какое-то время Вам понадобилось изменить правила игры и повысить или понизить порог очков (100), после превышения которого партия считается оконченной. Число 100 упоминается несколько раз в разных местах Вашего файла, и постоянно менять все операторы довольно хлопотно. Замену нельзя выполнить автоматической командой текстового редактора «найти и заменить», так как число 100 может встречаться в разных местах программы и обозначать не только предел набранных очков. Поэтому лучше всего описать число 100 как константу и в дальнейшем обращаться к ней по имени. В языке ассемблера используют константы, которые подобно переменным имеют имена. Единственное их отличие от переменных заключается в том, что им нельзя присвоить новое значение во время выполнения программы. Имя константы может быть более выразительным и в ряде случаев более коротким, чем ее значение. При многократном использовании такой константы в программе экономится время набора текста программы. Изменение значения именованной константы связано с изменением только одного оператора, тогда как в случае использования числовых значений этой константы такое исправление пришлось бы делать многократно.
Константы в языке ассемблера описывают с помощью директивы EQU (EQUAL, равно).
Синтаксис директивы: <имя> EQU <операнд>
Обязательно должны быть указаны имя и операнд, причем только один. Директивой EQU автор программы заявляет, что указанному операнду он дает указанное имя и требует, чтобы все вхождения данного имени в текст программы ассемблер заменял на этот операнд. Например, если есть директива STAR EQU ‘*’, то ассемблер будет рассматривать предложение N DB STAR как предложение N DB ‘*’, другими словами, STAR и ‘*’ — это одно и то же. Директива EQU носит чисто информационный характер и по нему ассемблер ничего не записывает в конечную программу. Поэтому директиву EQU можно ставить в любое место программы.
Операнд — имя
Если в правой части директивы указано имя регистра, переменной, константы и тому подобное, тогда имя слева объявляется синонимом данного имени и все последующие вхождения в текст программы этого имени-синонима ассемблер будет заменять на имя, указанное справа.
Пример:
Assembler
1
2
3
A DW ?
B EQU A
C DW B ; эквивалентно C DW A
Имена-синонимы обычно используются для введения более удобных и наглядных обозначений.
Операнд — константное выражение
Пример:
Assembler
1
2
3
N EQU 100
K EQU 2*N-1;К=199
P EQU ’A’
Если в правой части директивы EQU стоит константное выражение, тогда указанное слева имя принято называть именем константы. Значением этой константы объявляется значение выражения. N — это константа со значением 100, K — со значением 199, P — со значением 41h (это код буквы ‘A’ в системе ASCII). Все последующие вхождения в текст программы имени константы ассемблер будет заменять на значение этой константы.
Например, директива
X DB N DUP(?)
эквивалентна директиве
X DB 100 DUP(?)
Случаи, когда полезно применение констант, такие же, как в языках высокого уровня. Например, в качестве констант рекомендуется описывать размеры массивов, поскольку в таком случае легко настроить программу на работу с массивом любого другого размера — для этого достаточно внести изменение лишь в директиву EQU, описывающую константу. Если в константном выражении используются имена других констант, то они (эти константы) должны быть описаны раньше данной директивы EQU, иначе ассемблер, просматривающий текст программы сверху вниз, не сможет вычислить значение этого выражения.
Операнд — любой другой текст
Пример:
Assembler
1
2
3
S EQU ’Вы ошиблись’
LX EQU X+(N-1)
WP EQU WORD PTR
В данном случае считается, что указанное имя обозначает операнд в том виде, как он записан (операнд не вычисляется). Именно на этот текст и будет заменяться каждое вхождение данного имени в программе. Например, следующие предложения будут эквивалентны предложениям справа:
Assembler
1
2
3
ANS DB S,’!’ ANS DB ’Вы ошиблись!’
NEG LX NEG X+(N-1)
INC WP [BX] INC WORD PTR [BX]
Такой вариант директивы EQU обычно используется для того, чтобы ввести более короткие обозначения для часто встречающихся длинных текстов. Текст, указанный в правой части директивы EQU, должен быть сбалансирован по скобкам и кавычкам и не должен содержать вне скобок и кавычек символа «;». Поскольку текст не вычисляется, то в нем можно использовать как имена, описанные до этой директивы EQU, так и имена, описанные после нее.
Директива присваивания «=»
Синтаксис директивы: <имя> = <константное выражение>
Эта директива определяет константу с именем, указанным в левой части, и с числовым значением, равным значению выражения справа. В отличие от констант, определенных по директиве EQU, данная константа может менять свое значение, обозначая в разных частях текста программы разные числа.
Пример:
Assembler
1
2
3
4
K=10
A DW K ;эквивалентно A DW 10
K=K+4
B DW K ;эквивалентно B DW 14
Подобного рода константы используют ради «экономии имен»: если в разных частях программы используются разные константы и области использования этих констант не пересекаются, тогда, чтобы не придумывать новые имена, этим константам можно дать одно и тоже имя.
Целочисленные выражения
Операнды являются элементарными компонентами, из которых формируется часть машинной команды, обозначающая объекты, над которыми выполняется операция. В более общем случае операнды могут входить в более сложные образования, называемые выражениями. Целочисленные выражения представляют собой комбинации целочисленных значений и операторов, рассматриваемые как единое целое. Результатом целочисленных вычислений выражения может быть адрес некоторой ячейки памяти или некоторое константное (абсолютное) значение. В процессе вычисления выражения получается 32-битное число, в диапазоне от 0 до 0FFFFFFFFh.
  • Арифметические операторы с учетом порядка их выполнения — от старшего к младшему: скобки «(» и «)»; одноместные (унарные) «+» и «-» (знак числа); оператор умножения «*», целочисленного деления «/», получения остатка от деления «MOD»; двухместные (бинарные) «+» и «-» (операторы сложения и вычитания).
    Пример:
    Assembler
    1
    2
    3
    4
    
    TAB_SIZE EQU 50 ;размер массива в байтах
    SIZE_EL EQU 2 ;размер элементов
    ;вычисляется число элементов массива и заносится в CX
    MOV CX,TAB_SIZE/SIZE_EL ;оператор «/»
    Порядок выполнения операторов учитывается в сложных выражениях, состоящих из нескольких арифметических операторов.
    Assembler
    1
    2
    3
    4
    
    4 + 5 * 2 ;Сначала умножение, затем сложение
    121 MOD 5 ;Сначала остаток от деления, затем вычитание
    -5 + 2 ;Сначала унарный минус, затем сложение
    (4 + 2)* 6 ;Сначала сложение в скобках, затем умножение
    Выражение Значение, которое подставит компилятор
    16/5 3
    –(3+4)*(6–1) –35
    –3+4*6–1 20
    25 mod 3 1
    Таблица 6.2.4
  • Операторы сдвига SHL, SHR выполняют сдвиг выражения на указанное количество разрядов. Если указанное число отрицательное, то SHL будет заменен на SHR, а сдвиг произведен на модуль числа.
    Пример:
    Assembler
    1
    2
    
    MASK_B EQU 10111011B
    MOV AL,MASK_B SHR 3 ;AL=00010111B
  • Операторы сравнения EQ, NE, LT, LE, GT, GE (возвращают значение «истина» или «ложь») предназначены для формирования логических выражений.
    Пример:
    Assembler
    1
    2
    3
    4
    5
    
    TAB_SIZE EQU 30 ;размер таблицы
    MOV AL,TAB_SIZE GE 50 ;сравнение размера таблицы с 50
    ;и загрузка в AL в случае меньшего значения 0
    CMP AL,0 ;если TAB_SIZE < 50, то
    JE M1 ;переход на M1
  • Логические операторы NOT AND OR, XOR выполняют над выражениями побитовые операции.
    Пример:
    Assembler
    1
    2
    3
    
    FLAGS EQU 10010011B
    MOV AL,FLAGS XOR 01B ;AL=10010010 b; пересылка в AL
    ;поля FLAGS с инвертированным правым битом
  • Индексный оператор [ ]. Транслятор воспринимает квадратные скобки как указание сложить значение перед скобками с выражением, находящимся внутри скобок.
    Пример:
    Assembler
    1
    
    MOV EAX,MAS[ESI] ;пересылка слова по адресу MAS+[ESI] в регистр EAX
  • Оператор переопределения типа PTR применяется для временного переопределения или уточнения типа метки или переменной, определяемой выражением. Тип может принимать одно из следующих значений: BYTE, WORD, DWORD, QWORD, TBYTE, NEAR, FAR.
  • Оператор переопределения сегмента «:» (двоеточие) заставляет вычислять физический адрес относительно конкретно задаваемой сегментной составляющей: «имя сегментного регистра», «имя сегмента» из соответствующей директивы SEGMENT или «имя группы».
  • Оператор именования типа структуры «.» (точка).
  • Оператор получения сегментной составляющей адреса выражения SEG возвращает физический адрес сегмента для выражения, в качестве которого могут выступать метка, переменная, имя сегмента, имя группы или некоторое символическое имя.
  • Оператор получения смещения выражения OFFSET позволяет получить значение смещения выражения в байтах относительно того сегмента, в котором выражение определено.
Выполнение операторов ассемблера при вычислении выражений осуществляется в соответствии с их приоритетами. Операции с одинаковыми приоритетами выполняются последовательно слева направо. Изменение порядка выполнения возможно путем расстановки круглых скобок, которые имеют наивысший приоритет.
В таблице указаны операторы ассемблера в порядке убывания старшинства.
Операторы ассемблера в порядке убывания старшинства
 Операторы с равным старшинством
1 (), [], <>, LENGTH, SIZE, WIDTH, MASK
2 .
3 :
4 PTR, OFFSET, SEG, TYPE, THIS
5 HIGH, LOW
6 Одноместные (унарные) + и -
7 *, /, MOD, SHL, SHR
8 Двухместные (бинарные) + и -
9 EQ, NE, LT, LE, GT, GE
10 NOT
11 AND
12 OR, XOR
13 SHORT, TYPE
Таблица 6.2.5
Константные выражения
Значениями константных выражений всегда являются 32-битовые целые числа (исключениями являются директивы DQ, DF, DP, DT, которыми можно явно указывать 32-битовые и более числа).
К простейшим константным выражениям относятся:
  • числа от –231 до 232–1;
  • символ (значением такого выражения является код символа);
  • строка из двух символов (значением является слово-число, составленное из кодов этих символов);
  • имя константы (значением такого выражения является значение константы).
К константным выражениям применимы следующие арифметические операторы (k, k1 и k2 означают любые константные выражения):
  • одноместные плюс и минус +k, –k;
  • операторы сложения и вычитания k1+k2, k1–k2;
  • оператор умножения k1*k2, целочисленного деления k1/k2, получения остатка от деления k1 MOD k2.
Пример: K EQU 30
X DB (3*K-1)/2 DUP(?) ;массив из 44 байтов
Операндами арифметических операторов должны быть константные выражения. Язык ассемблер разрешает вычитать один адрес из другого, в результате Вы получите число, а не адрес.
Пример: X DW 1,2,3,4,5
Y DB ?
SIZE_X EQU Y-X ;SIZE_X=10
Вычитание адресов используется обычно для определения расстояния (числа байтов) между этими адресами. Результатом действия арифметических операторов на константные выражения будет 32-битное число. Например: 2*80000000h=00000000h а не 100000000h.
Адресные выражения
Значениями адресных выражений являются 32-битовые адреса.
К простейшим адресным выражениям относятся:
  • метка (имя команды) и имя переменной, описанное в директиве DB, DW или DD (значениями таких выражений являются адреса меток и имен);
  • счетчик размещения; он записывается как $ и обозначает адрес того предложения, в котором он встретился. В разных предложениях $ обозначает разные адреса. Например, если адрес переменной A равен 400100h, то имеем:
A DD $ ;эквивалентно A DD 400100h
B DD $ ;эквивалентно B DD 400104h
Чаще всего счетчик размещения используется для вычисления размера памяти занимаемой каким-то массивом.
Пример: X DW 40 DUP(?)
SIZE_X EQU $-X ;SIZE_X = 80
Здесь $ обозначает адрес первого байта за массивом X, из этого адреса и вычитается начальный адрес массива.

Мнемоника команд MMX, SSE, SSE2
Когда разберёшься как по какому принципу строятся мнемонические команды — тогда всё станет легко. Вот что присутствует в мнемонике:
SIMD для работы с вещественными числами:
[h] — horizontal операции
op — код операции
[op] — код операции2 для сложных инструкций
[L|h] — обозначает какая часть приёмника/источника подвержена операции op: low|high
[[L|h]] — если присутствует, то обозначает куда будет помещён результат операции op в зависимости от предыдущей мнемоники.
Возможно: L->h, h->L
[a|u] — aligned|unaligned. Говорит о требованиях к выравниванию операнда(ов) в памяти: a — выравнивание на границу в 16 байт требуется, u — не требуется
[nt] — non temporal. Говорит о некэшируемости операндов в памяти
[s|p] — scalar/packed операция op над данными (для h префикса только p)
s|d — single/double precision. Размерность данных в операндах.
(float/double)
[2] — «to». Возникает при операциях op конвертации.
[s|p] — scalar/packed вид данных операнда. Возникает 2-й раз в операциях конвертации после «2»
[s|d] — single/double precision. Размерность данных в операндах.
(float/double). Возникает 2-й раз в операциях конвертации после «2» и вида данных операции op
[[h|L]] — high|low. Присутствует, если используется мнемоника DUP
(смотри ниже). Указывает расположение данных в операндах источниках для выполнения операции op
[dup] — duplicate. Может возникнуть при дублировании частей операндов источников в операнде приёмнике после выполнении операции op
Примеры: addps, haddps, addsubpd, movhlps, andps, movaps, movntpd, movshdup...
SIMD для работы с целыми числами:
[p] — packed. Присутствует всегда за исключением малого количества некоторых операций op
[h] — horizontal операции
op — код операции
[op] — код операции2 в сложных операциях
[s|us] — signed|unsigned saturation. Тип насыщение при операции op: знаковое|беззнаковое. Если отсутствует, то без насыщения (wrap around арифметика)
[L|h] — low|high. Обозначает, какая часть приёмника/источника подвержена операции op
[nt] — non temporal. Говорит о некэшируемости операндов в памяти
[b|w|d|q|dq] — byte|word|dword|qword|dqword. Размер упакованных операндов источников
[[2]] — «to». Может возникнуть при операции op над данными при разных типах операндов источника и приёмника: MMX и XMM регистров. «2» говорит о направлении действия операции op над данными. Возможно: Q2DQ, DQ2Q
[[b|w|d|q|dq]] — byte|word|dword|qword|dqword. Размер упакованных данных операции op. Осуществляется преобразование от меньшей разрядности операций (смотри предыдущую мнемонику) к большей (см. эту). Возможно от b->w, w->d, d->q... Если отсутствует, то размер результата упакованных данных остаётся неизменным (т.е. см. предыдущую мнемонику)
[a|u] — aligned|unaligned. Говорит о требованиях к выравниванию операнда(ов) в памяти: a — выравнивание на границу в 16 байт требуется, u — не требуется
Примеры: paddb, phsubw, psubusb, punpckhbw, pand, movntdqa, movdqu...
Контрольные вопросы
  1. Какие из следующих имен не могут быть идентификатором?:
    1. C,
    2. $50,
    3. @$_Z,
    4. 34B7,
    5. AX
  2. Какова длина в байтах для элементов данных, определенных директивами:
    1. DW,
    2. DD,
    3. DT,
    4. DB,
    5. DQ?
  3. Перечислите допустимые спецификаторы, которые могут встречаться при описании чисел в ассемблере.
  4. Определите символьную строку по имени TITLE1, содержащую константу RGB Electronics.
  5. Является ли запись A5h правильным шестнадцатеричным числом?
  6. Как временно исключить какой-либо фрагмент программы из общего текста программы не удаляя этот фрагмент?
  7. Запишите константное выражение, в котором вычисляется остаток от деления 10 на 3.
  8. Почему при написании программ на языке ассемблер не стоит использовать числовые адреса памяти для доступа к переменным?
  9. Определите следующие числовые значения в элементах данных от FLDA до FLDE:
    1. четырёхбайтного элемента, содержащего шестнадцатеричный эквивалент десятичного числа 115,
    2. однобайтового элемента, содержащего шестнадцатеричный эквивалент десятичного числа 25,
    3. двухбайтового элемента, содержащего неопределенное значение,
    4. однобайтового элемента, содержащего двоичный эквивалент десятичного числа 25,
    5. директивы DW, содержащей последовательные значения 16, 19, 20, 27, 30.
  10. Приведите пример правильной вещественной константы, содержащей показатель степени.
  11. Нужно ли заключать строковую константу в одинарные кавычки?
  12. В чем разница между DB ‘26’ и DB 26.
  13. Назовите максимальную длину идентификатора.
  14. Определите ассемблерный шестнадцатеричный объектный код для:
    1. DB –26,
    2. DW 2645,
    3. DD 25733,
    4. DQ –2573300.
  15. Представьте следующие символьные цепочки в шестнадцатеричном коде:
    1. SAM JONES;
    2. –75.61;
    3. Hello, how are you?
  16. Верно ли, что название идентификаторов в языке ассемблер не зависят от регистра символов?
  17. Приведите пример многострочного комментария.
  18. Как сохраняется в памяти строка символов? Как подсчитать размер занимаемой памяти для отдельной строки?
  19. Верно ли, что для записи директив можно использовать как прописные, так и строчные латинские буквы, а также их сочетание?
  20. Что такое константа? Чем константа отличается от переменной?
  21. Назовите основные части ассемблерной команды. Верно ли, что метка в коде программы должна заканчиваться двоеточием, а метка данных нет?
Изображения
 
6
Закрытая тема Создать тему
Новые блоги и статьи
Нейросеть на алгоритме "эстафета хвоста" как перспектива.
Hrethgir 06.05.2026
На десерт, когда запущу сервер. Статья тут https:/ / habr. com/ ru/ articles/ 1030914/ . Автор я сам, нейросеть только помогает в вопросах которые мне не известны - не знаю людей которые знали-бы. . .
Асинхронный приём данных из COM-порта
Argus19 01.05.2026
Асинхронный приём данных из COM-порта Купил на aliexpress термопринтер QR701. Он оказался странным. Поключил к Arduino Nano. Был очень удивлён. Наотрез отказывается печатать русские буквы. Чтобы. . .
попытка написать игровой сервер на C++
pyirrlicht 29.04.2026
попытка написать игровой сервер на плюсах с открытым бесконечным миром. возможно получится прикрутить интерпретатор питон для кастомизации игровой логики. что есть на текущий момент:. . .
Контроль уникальности выбранного документа-основания при изменении реквизита
Maks 28.04.2026
Алгоритм из решения ниже разработан на примере нетипового документа "ЗаявкаНаРемонтСпецтехники", разработанного в КА2. Задача: уведомлять пользователя, если указанная заявка (документ-основание). . .
Благородство как наказание
Maks 24.04.2026
У хорошего человека отношения с женщинами всегда складываются трудно. А я человек хороший. Заявляю без тени смущения, потому что гордиться тут нечем. От хорошего человека ждут соответствующего. . .
Валидация и контроль данных табличной части документа перед записью
Maks 22.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в КА2. Задача: контроль и валидация данных табличной части документа перед записью с учетом регламента компании. . .
Отчёт о затраченных материалах за определенный период с макетом печатной формы
Maks 21.04.2026
Отчёт из решения ниже размещён в конфигурации КА2. Задача: разработка отчёта по затраченным материалам за определённый период, с возможностью вывода печатной формы отчёта с шапкой и подвалом. В. . .
Отчёт о спецтехнике находящейся в ремонте
Maks 20.04.2026
Отчёт из решения ниже размещен в конфигурации КА2. Задача: отобразить спецтехнику, которая на данный момент находится в ремонте. Есть нетиповой документ "Заявка на ремонт спецтехники" который. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru