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


Лексемы
Лексема — смысловая единица языка ассемблер. К лексемам относятся имена или идентификаторы, числа, константы, зарезервированные слова, операторы и строки.
Каждая единица информации, хранимая в ячейках памяти компьютера, имеет свой адрес. На практике заранее неизвестно, в каких конкретно ячейках памяти во время работы программы будут записаны ее данные, поэтому в языках программирования введено понятие переменной, позволяющее отвлечься от конкретных адресов и обращаться к содержимому памяти с помощью идентификатора или имени. Имена указывают на значение, о реальном адресе и способе хранения которого можно забыть. В процессе работы содержимое соответствующих ячеек можно менять, обращаясь к переменной по имени. Кроме имени и значения, переменная обычно имеет тип, определяющий, какая информация хранится в данной переменной (число, адрес и т.д.). В зависимости от объема памяти, отведенного для
хранения переменной, оно (значение) должно укладываться в допустимый диапазон. Например, значение типа байт имеет диапазон от –128 до 255. Максимальное беззнаковое число равно 28 – 1=255 (8 по количеству битов в байте), минимальное беззнаковое число 0. Максимальное число со знаком равно 127, минимальное число со знаком –128 (1 бит для знака и 7 бит для значения).
Идентификаторы
Идентификаторы — последовательность из латинских букв, цифр и знаков «?», «.», «@» «_», «$». Ограничение набора символов восходит к ранним языкам программирования, которые возникли еще в эпоху 6-битной кодировки символов.
При записи идентификатора придерживаются следующих правил:
  • длина идентификатора, не может быть длиннее 247 символов;
  • идентификатор не должен начинаться с цифры;
  • точка может быть только первым символом идентификатора
    (внутри идентификатора точка может использоваться только для разделения полей структуры);
  • в идентификаторах большие и малые одноименные буквы при использовании ключа /Cp считаются неэквивалентными;
  • в идентификаторах нельзя использовать буквы кириллицы и символы псевдографики;
  • знак «$» и «?» имеют самостоятельное значение, поэтому их не рекомендуют к использованию в идентификаторе.
Идентификаторы делятся на служебные слова и имена. Служебные слова имеют заранее определенный смысл, они используются для обозначения таких объектов, как регистры, названия команд и так далее. Все остальные идентификаторы называются именами. Именами обозначаются переменные, метки и другие объекты программы.
Целые числа
Целые числа могут быть записаны в десятичной, двоичной, восьмеричной и шестнадцатеричной системах счисления. Десятичная форма записи числа записываются как обычно, а вот при записи вида чисел в других системах счисления в конце записи числа ставится спецификатор — буква, которая указывает, в какой системе счисления записано это число. В конце двоичного вида числа ставится буква b или буква y (binary), в конце восьмеричного — o (octal) или буква q, в конце шестнадцатеричного вида числа — буква h (hexadecimal), в конце десятичного вида числа можно поставить букву d (decimal) или букву t (ten), хотя употребление спецификатора в этом случае и не обязательно.
При записи шестнадцатеричных чисел соблюдают следующие правила:
  • если число начинается с шестнадцатеричной цифры от «A» до «F», то в начале числа ставят ноль;
  • хотя при записи числа строчные и прописные одноименные буквы считаются эквивалентными, шестнадцатеричной цифры от «A» до «F» записывают большими буквами, а спецификатор «h» маленькой.
Символьные и строковые константы
Для записи текстов, которые программа в последствие выведет на экран/файл/принтер, используют либо систему ASCII (American Standard Code for Information Interchange), либо Windows-кодировку. Символьная константа состоит просто из одного символа ASCII. Символьные константы заключаются либо в одинарные, либо в двойные кавычки. Открывающая и закрывающая кавычки должны быть одинаковы. Строковые константы содержат два или более символов ASCII. Строковые константы также заключаются либо в одинарные, либо в двойные кавычки.
  • В качестве символьных констант можно использовать буквы кириллицы и символы псевдографики.
  • В строковых константах (также как и в символьных константах) строчные и прописные одноименные буквы не отождествляются.
  • Если в качестве символьных констант или внутри строковых константах надо указать кавычку, то, если символьная или строковая константа заключены в одинарные кавычки, одинарную кавычку надо удваивать, а двойную не надо, и наоборот, если внешние кавычки двойные, то двойная кавычка должна удваиваться, а одинарная не удваивается. Можно также просто указать ASCII код кавычек: 27h код апострофа «’», 22h код двойных кавычек «”».
Примеры:
  • ”внутри строки допустим вот такой символ ’ ”
  • ’строки ”могут быть вложены” таким образом’
Слова типа can’t или don’t можно записать вот так:
  • ’can’’t’, здесь два апострофа, хотя визуально это выглядит как двойная кавычка
  • ’can’,27h,’t’,
  • ”can’t” а здесь использованы кавычки, а не два апострофа
Предложения
Программа на языке ассемблера — это последовательность предложений, каждое из которых записывается в отдельной строке. Переносить предложение на следующую строку можно используя символ «\», записывать два предложения в одной строке нельзя. Если в предложении более 255 символа, то 256-ой и все следующие за ним символы игнорируются.
Правила расстановки пробелов в предложении:
  • пробел обязателен между двумя стоящими рядом идентификаторами и/или числами;
  • внутри идентификаторов и чисел пробелы не допустимы;
  • там где допустим один пробел, можно ставить любое число пробелов.
Эти правила не относятся к пробелам внутри строк, где пробел — обычный значащий символ.
По смыслу все предложения делятся на три группы:
  1. комментарии;
  2. команды;
  3. директивы (приказы ассемблеру).
Комментарии предназначены не для микропроцессора, а для людей, они поясняют смысл и детали реализации программы.
Команды управляют работой микропроцессора. Для команд транслятор с языка ассемблера всегда генерирует код машинных команд.
Директивы управляют работой компилятора по компоновке программы, а не работой микропроцессора. Директивы используются для сообщения компилятору, какие константы и переменные применяются в программе. Как они должны быть расположены в памяти компьютера. Большинство директив не генерирует код машинных команд.
Комментарии
Комментарии не влияют на смысл программы, при трансляции ассемблер игнорирует строки комментария. Комментарием считается любое предложение, начинающееся со знака «точка с запятой». Перед знаком «точка с запятой» может быть любое количество пробелов. В комментариях можно использовать буквы кириллицы и символы псевдографики. Предложения-комментарии используются для пояснения не одной команды, а целой группы команд, следующих за этим комментарием. Старайтесь комментировать задачу, а не инструкции ассемблера. Пустые строки используют для отделения одной части программы от другой — для наглядности. В языке ассемблера допустим и многострочный комментарий. Многострочный комментарий должен начинаться со строчки COMMENT. В качестве маркера
многострочного комментария берется первый за словом COMMENT символ, отличный от пробела; этот символ начинает комментарий. Концом многострочного комментария является конец первой из последующих строк программы, в которой в любой позиции снова встретился этот же маркер. Такой вид комментария обычно используется, когда, например, при отладке программы необходимо временно исключить какой-либо фрагмент программы.
Команды
Предложения-команды — символьная форма записи машинных команд. Общий синтаксис предложения-команды таков:
[<метка>:] <мнемокод> [<операнды>] [;<комментарий>]
Метка
Метка — это имя. Каждая метка может быть определена только однажды и будет доступна из любой части текущего файла (даже перед местом, где она была определена). Существуют разные способы определения меток. Простейший из них — двоеточие после названия метки. За этой директивой на той же строке даже может следовать другая инструкция. Она определяет метку, значение которой равно смещению точки, в которой она определена. Этот метод обычно используется, чтобы пометить места в коде. Другой способ — это следование за именем метки (без двоеточия) какой-нибудь директивы описания данных. Метка является адресом начала определенных в директиве данных и запоминается компилятором как адрес данных.
Метка может быть обработана как константа со значением, равным смещению помеченного кода или данных. Например, если вы определяете данные, используя помеченную директиву «char db 224», для того, чтобы поместить адрес начала этих данных в регистр EBX, вам нужно использовать инструкцию «mov ebx,offset char», а для того, чтобы поместить в регистр DL значение байта, на который ссылается «char», нужно использовать «mov dl,char». Последний и самый гибкий способ задания меток — это использование директивы «label». Перед этой директивой должно следовать имя метки, далее, размер оператора, и далее, числовое выражение, определяющее адрес, на который данная метка должна ссылаться. Метка нужна для ссылок на команду из других мест программы, например, для перехода на команду, перед которой стоит метка.
Мнемокод
Мнемокод («легко запоминающийся код») является обязательной частью команды. Это служебное слово, указывающее в символьной форме операцию, которую должна выполнить команда.
Операнды
Операнды команды, если они есть, отделяются друг от друга запятыми. Операнды обычно записываются в виде выражений. Частными случаями выражений являются числа и имена переменных.
Операнды, которые используются в командах ассемблера, могут быть регистром reg, адресом памяти mem, непосредственным значением, задаваемым прямо в команде imm, сегментным регистром sreg.
Машинные коды для всех возможных сочетаний
операторов команды
Описание машинного кода производится в шестнадцатеричном виде. При описании машинного кода используются следующие обозначения:
/цифра — (цифра от 0 до 7) показывает, что байт mod r/m кода операции использует только операнд r/m. Поле reg содержит цифры которые обеспечивает расширение опкода;
/r — показывает, что байт mod r/m команды содержит как регистровый операнд, так и операнд r/m;
cb, cw, cd, cp, cq — одно-, двух-, четырех, шести-, восьмибайтное значение, следующее за полем код операции и используемое для смещения
сегменте кода и возможно задает новое значение для регистра;
ib, iw, id, iq — одно-, двух-, четырех-, восьмибайтное непосредственное значение (число). Следует за опкод, Mod R/M или SIB (если таковые есть), при этом код операции определяет, является ли непосредственный операнд знаковым значением, а все слова, двойные и четверные слова приводятся в порядке «младший байт по младшему адресу»;
+rb, +rw, +rd, +rq, +i — код регистра от 0 до 7. Добавляется к байту слева от знака «+». В результате получается окончательный опкод.
Коды регистров
  w=0w=1     
decbinrbrwrdrqisegmentdebugcontroltest
0 000 AL AX EAX RAX ST(0) ES DR0 CR0
1 001 CL CX ECX RCX ST(1) CS DR1
2 010 DL DX EDX RDX ST(2) SS DR2 CR2
3 011 BL BX EBX RBX ST(3) DS DR3 CR3 TR3
4 100 AH SP ESP RSP ST(4) FSCR4 TR4
5 101 CH BP EBP RBP ST(5) GSTR5
6 110 DH SI ESI RSI ST(6)DR6 TR6
7 111 BH DI EDI RDI ST(7)DR7TR7
Таблица 6.2.1
Машинные коды команды сопровождаются описанием синтаксиса команды для соответствующего сочетания операндов. При описании синтаксиса используются следующие обозначения:
  • rel8 — относительный адрес (смещение). Задаёт смещение от 128 байт перед концом инструкции до 127 байт после конца инструкции. Иными словами, смещение от -128 до 127 байт относительно адреса после конца инструкции;
  • rel16, rel32, rel64 — относительные адреса в пределах сегмента кода, содержащего данную команду, используемые для операндов с размером операнда 16 (use16), 32 (use32) и 64 (use64) бита соответственно;
  • ptr16:16, ptr16:32, ptr 16:64 — непосредственное значение 20-, 48- и 80-разрядного адреса памяти, задаваемое прямо в команде, дальний указатель (обычно на адрес в сегменте кода, отличном от текущего), используется при установленном атрибуте размера операнда 16, 32 или 64 бита (первая часть указателя является селектором или значением сегментного регистра кода, вторая — смещением в целевом сегменте кода);
  • reg — операнд в одном из регистров размером в байт, слово, двойное слово, четверное слово;
  • r8 — операнд в одном из регистров размером в байт: AH, AL, BH, BL, CH, CL, DH, DL, BPL, SPL, DIL, SIL или один байт регистров (R8L — R15L) доступный, когда используется REX.R и 64-битный режим;
  • r16 — операнд в одном из регистров размером в слово: AX, BX, CX, DX, BP, SP, SI, DI или одно слово регистров (R8 — R15) доступный, когда используется REX.R и 64-битный режим;
  • r32 — операнд в одном из регистров размером в двойное слово: EAX, EBX, ECX, EDX, EBP, ESP, ESI, EDI или одно двойное слово регистров (R8D — R15D) доступный, когда используется REX.R и 64-битный режим;
  • r64 — операнд в одном из регистров размером в четверное слово RAX, RBX, RCX, RDX, RBP, RSP, RSI, RDI, R8 — R15 доступные, когда используется REX.R и 64-битный режим;
  • imm, imm8, imm16, imm32, imm64 — непосредственный одно-, двух-, четырех-, восьмибайтовый операнд команды;
  • mem, m8, m16, m32, m48, m64, m128 — операнд в памяти размером в байт, слово, двойное слово, 48/64/128 бит;
  • m8 — адрес однобайтной ячейки памяти в регистре (E)SI или (E)DI. Используется только со строковыми инструкциями;
  • m16 — адрес двухбайтной ячейки памяти в регистре (E)SI или (E)DI. Используется только со строковыми инструкциями;
  • m32 – адрес четырёхбайтной ячейки памяти в регистре (E)SI или (E)DI. Используется только со строковыми инструкциями;
  • m64 — адрес 64-битной (учетверённое слово) ячейки памяти. Используется только с инструкцией CMPXCHG8B;
  • m128 — адрес 128-битной (увосьмерённое слово) ячейки памяти. Используется только с инструкциями SSE и SSE2;
  • r/m8 — байтовый операнд, который содержится либо в одном из регистров размером один байт, либо в ячейке памяти размером один байт;
  • r/m16 — операнд в регистре размером в слово или в ячейке памяти размером в слово (используется в командах, для которых размер операнда равен 16 бит);
  • r/m32 — операнд в регистре размером в двойное слово или в ячейке памяти размером в двойное слово (используется в командах, для которых размер операнда равен 32 битам);
  • m16:16, m16:32, m16:64 — операнд в памяти, содержащий дальний указатель, находящийся по данному адресу;
  • m16&32, m16&16, m32&32 — адрес ячейки памяти, состоящей из нескольких элементов, чьи размеры задаются справа и слева от амперсанда. Доступны все режимы адресации памяти. Операнды m16&16 и m32&32 используются инструкцией BOUND (в них задаются верхние и нижние границы массива). Операнд m16&32 используется LIDT и LGDT.
  • moffs8, moffs16, moffs32, moffs64 — переменная (смещение в памяти), типа байт, слово, двойное, четверное слово, требующая для выполнения некоторых вариантов команды mov (байт mod r/m не используется, адрес задается простым смещением относительно базы сегмента). Используется некоторыми вариантами инструкции MOV;
  • sreg — сегментный регистр. Номера сегментных регистров в поле Reg байта ModR/M: ES=0, CS=1, SS=2, DS=3, FS=4, GS=5;
  • port8 — 8-разрядный адрес в пространстве ввода/вывода;
  • m32fp, m64fp, m80fp — адрес в памяти операнда с плавающей точкой одинарной точности, двойной точности или расширенной точности. Используется инструкциями FPU;
  • m16int, m32int, m64int, m80int — целочисленный операнд в памяти, используемый в командах сопроцессора;
  • ST или ST(0) — верхний элемент стека сопроцессора;
  • ST(i) — i-ый элемент стека сопроцессора (i=0…7);
  • rmmx0…rmmx7 — операнд в одном из регистров целочисленного расширения MMX;
  • rmmx/m32 — младшая часть (32 бита) MMX-регистра или 32-разрядный операнд в памяти;
  • rmmx/m64 — MMX-регистр или 64-разрядный операнд в памяти;
  • rxmm0…rxmm7 — операнд в одном из 128-битный XMM-регистров расширения MMX с плавающей точкой;
  • [b]rxmm/m32 — XMM-регистр (от XMM0 до XMM7) или адрес 32-битной ячейки памяти;
  • rxmm/m64 — XMM-регистр (от XMM0 до XMM7) или адрес 64-битной ячейки памяти;
  • rxmm/m128 — XMM-регистр (от XMM0 до XMM7) или адрес 128-битной ячейки памяти.
В таблице указывается, какие типы процессоров поддерживают данную мнемонику:
Сокращенное наименованиеПолное наименование
 Intel
P Pentium
PII Pentium II (MMX)
SSE SSE (Katmai NI)
SSE2 SSE2
SSE3 SSE3 (Prescott NI)
E64T 64-bit Memory
 AMD
K6 K6
3D! 3DNow!
3Mx+ 3DNow! and MMX Ext.
A64 AMD64
Комментарий
В конце команды можно поместить комментарий, для чего надо поставить точку с запятой и выписать любой текст, который будет рассматриваться как комментарий. Такой комментарий, в отличие от комментариев-предложений, обычно используется для пояснений именно данной команды.
Изображения
 
0
Закрытая тема Создать тему
Новые блоги и статьи
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга, Ты же видел моря и метели. Как сменялись короны и стяги, Как эпохи стрелою летели. - Этот мир — это крылья и горы, Снег и пламя, любовь и тревоги, И бескрайние. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru