Синтаксис объявления меток. — it-black.ru
Синтаксис объявления меток. — it-black.ru Перейти к содержимомуМетка в ассемблере – это символьное имя, обозначающее ячейку памяти, которая содержит некоторую команду. Метка может содержать следующие символы:
- Буквы (от A до Z и от a до z),
- Цифры (от 0 до 9, не первым символом),
- Знак вопроса (?)
- Точка (.) (только первый символ),
- Знак (@),
- Подчеркивание (_),
- Доллар ($)).
Примеры меток: COUNT, PAGE25, $E10.
Cинтаксис FASM не ограничивается объявлением простых меток. Сегодня мы рассмотрим дополнительную директиву для создания меток, а также научимся использовать локальные и анонимные метки. В синтаксисе FASM существует 3 основных способа объявления меток:
1. Имя метки, после которого ставится двоеточие. Это самый простой способ. Обычно так объявляются метки в коде.
exit_app: mov ax,4C00h int 21h
2. Использование директив объявления данных. Имя переменной является по сути той же меткой. Отличие от первого способа в том, что дополнительно с именем метки связывается размер переменной.
x db 5 y dw 34,1200,? z rd 1
3. Объявление метки с помощью специальной директивы label. Более сложный, но зато самый гибкий способ. Директива label имеет следующий формат:
label [размер] [at адрес]
У директивы может быть 3 параметра. Обязательным является только первый параметр — имя метки. Второй параметр — оператор размера (byte, word, dword). Он связывает с меткой размер переменной, аналогично тому, как это делают директивы объявления данных. Далее может быть указан оператор at и адрес метки. Адрес может представлять собой константу, числовое выражение или имя другой метки. Если адрес не указан, то для создания метки используется адрес того места, где она объявлена.
Пример:label m1 ;То же самое, что 'm1:' label m2 byte ;Похоже на 'm2 db ?', но память не резервируется label m3 dword ;Похоже на 'm3 dd ?', но память не резервируется ;Все 3 метки указывают на один и тот же адрес!
Локальные метки
Локальная метка — это метка, имя которой начинается с точки. Во время генерации кода FASM автоматически добавляет к имени локальной метки имя последней объявленной «глобальной» метки. Таким образом, имена локальных меток могут повторяться, если между ними есть хотя бы одна «глобальная» метка.
Локальные метки удобно использовать внутри процедуры. Можно дать им простые, понятные имена и не беспокоиться, что где-то в коде уже объявлена метка с таким именем.
Анонимные метки
Анонимная метка — это метка с именем @@. В программе можно объявлять сколько угодно анонимных меток, но обратиться получится только к ближайшей. Для этого существуют специальные имена: вместо @b (или @r) FASM подставляет адрес предыдущей анонимной метки, а вместо @f — адрес следующей анонимной метки. Этого, как правило, достаточно, чтобы реализовать простой цикл, переход или проверку условия. Таким образом можно избавиться от большого количества «неанонимных» меток. Вот пример процедуры с использованием анонимных меток:
;Процедура преобразования десятичной строки в слово без знака ; вход: AL - длина строки ; DX - адрес строки, заканчивающейся символом CR(0Dh) ; выход: AX - слово (в случае ошибки AX = 0) ; CF = 1 - ошибка str_to_udec_word: push cx ;Сохранение всех используемых регистров push dx push bx push si push di mov si,dx ;SI = адрес строки mov di,10 ;DI = множитель 10 (основание системы счисления) movzx cx,al ;CX = счётчик цикла = длина строки jcxz . error ;Если длина = 0, возвращаем ошибку xor ax,ax ;AX = 0 xor bx,bx ;BX = 0 @@: mov bl,[si] ;Загрузка в BL очередного символа строки inc si ;Инкремент адреса cmp bl,'0' ;Если код символа меньше кода '0' jl .error ; возвращаем ошибку cmp bl,'9' ;Если код символа больше кода '9' jg .error ; возвращаем ошибку sub bl,'0' ;Преобразование символа-цифры в число mul di ;AX = AX * 10 jc .error ;Если результат больше 16 бит - ошибка add ax,bx ;Прибавляем цифру jc .error ;Если переполнение - ошибка loop @b ;Команда цикла jmp @f ;Успешное завершение (здесь всегда CF = 0) .error: xor ax,ax ;AX = 0 stc ;CF = 1 (Возвращаем ошибку) @@: pop di ;Восстановление регистров pop si pop bx pop dx pop cx ret
Советую локальные и анонимные метки использовать везде, где только возможно. Они делают код программы более понятным и не захламляют пространство имён.
- Виктор Черемных
- 26 декабря, 2017
- No Comments
Группа в VK
Обнаружили опечатку?
Сообщите нам об этом, выделите текст с ошибкой и нажмите Ctrl+Enter, будем очень признательны!
Свежие статьи
Облако меток
Похожие статьи
Команды работы с битами.
Работать с отдельными битами операндов можно, используя логические операции и сдвиги. Также в системе команд x86 существуют специальные команды для работы с битами: это команды
Основы создания макросов в Assembler.
Макросы — это шаблоны для генерации кода. Один раз создав макрос, можно использовать его во многих местах в коде программы. Макросы делают процесс программирования на
Локальные переменные.
Локальные переменные в Assembler используются для хранения промежуточных результатов во время выполнения процедуры. В отличие от глобальных, эти переменные являются временными и создаются при запуске
Передача параметров через стек.
В предыдущих уроках все параметры передавались процедурам через регистры. В этой статье мы рассмотрим другой способ — передачу параметров через стек. Часто этот способ оказывается
Instagram Vk Youtube Telegram OdnoklassnikiПолезно знать
Рубрики
Авторы
ассемблер — Метки в ассемблере
в ассемблере пока что новичок. Вот возникло пару вопросов.
- Как идет исполнение программы при встрече метки, допустим идет какие-нибудь команды, затем попадается метка, будет ли заход в нее?
- Как узнать где конец метки, как это понимает компилятор. Вот есть у меня переход по метке, перешел, а до какого времени будет исполнятся команды, если я хочу за этой меткой разместить какой-то код который не должен быть исполнен при переходе на метку
- И как вообще правильно размещать метки. Если я хочу в нее попасть только в одном случае, а если не исполняется условие, то не попадать.
- Покажите пожалуйста пример простенькой программы с меткой и объясните как поэтапно будет выполнятся программа.
- ассемблер
- В результирующем коде меток нет. Нет меток — нет проблем.
Никак. Меток то нет. Метки это просто имена для адресов. Не более. То есть, можно было бы использовать непосредственно адреса, но в случае меток, компилятор сделает много работы самостоятельно.
а до какого времени будет исполнятся команды
могут быть такие варианты
- встретится другая команда перехода
- выключиться питание
- команда halt (или ей подобная).
- то, что не может быть интерпретированно как команда.
Меткам побоку, будет ли код возле них исполнятся. Если дойдет очередь — будет. Если нужно, что бы код не исполнялся — воспользуйтесь командой условного/безусловного перехода
Ещё раз, метки — это адреса. Можно наставить хоть для каждой строки по метке, от этого процесс исполнения кода не поменяется.
jmp test add_label: add .. sub_label: sub .. test: mov ..
Вот в этом примере sub и add не будут исполнятся, хотя возле них и есть метки. Но какой то другой код может сделать на них переход.
Какой ассемблер Вы изучаете я не знаю, поэтому код схематический.
2
Зарегистрируйтесь или войдите
Регистрация через Google
Регистрация через Facebook
Регистрация через почту
Отправить без регистрации
Почта
Необходима, но никому не показывается
Отправить без регистрации
Почта
Необходима, но никому не показывается
Нажимая на кнопку «Отправить ответ», вы соглашаетесь с нашими пользовательским соглашением, политикой конфиденциальности и политикой о куки
8051 — «Ярлык» на ассемблере
Задавать вопрос
спросил
Изменено 2 года, 9 месяцев назад
Просмотрено 22к раз
У меня есть несколько примеров, которые довольно просты, за исключением концепции LABEL. Пример 1 добавляет 25 10 раз сам по себе, тогда как пример 2 использует дополнение регистра A 700 раз.
Пример 1: MOV A,#0 ДВИГАТЕЛЬ R2, №10 СНОВА: ДОБАВИТЬ A, # 25 DJNZ R2, СНОВА ДВИГАТЕЛЬ R5,А Пример-2: ДВИГАТЕЛЬ А, # 55H ДВИГАТЕЛЬ R3, №10 СЛЕДУЮЩИЙ: ДВИЖЕНИЕ R2, # 70 СНОВА: CPL A DJNZ R2, СНОВА DJNZ R3, СЛЕДУЮЩИЙ
Я не могу понять концепцию LABEL. В примере-1, когда программа запускается в первый раз, A получает значение 25, а затем, когда R2 уменьшается с 10 до 1, вывод равен 275 вместо 250. Но если я предполагаю, что LABEL игнорируется, если он не вызывается, тогда все в порядке. и я получаю результат 250. Но если я предполагаю то же самое (обход LABEL при пошаговом выполнении) в Примере-2, то LABEL NEXT будет пропущен. И будет исполнено «DJNZ R2,ОПЯТЬ». Поскольку NEXT был пропущен, то как R2 получит значение #70? Итак, мой вопрос о выполнении LABEL. МЕТКИ выполнены или обойдены?
- в сборе
- 8051
4
и когда 10 раз DJNZ добавляет 25 в A, должно получиться 275
Нет, 250 — правильный ответ. После 10-й инструкции добавления, регистр R2
все еще содержит 1
— затем он уменьшается до 0 и , затем инструкция DJNZ больше не переходит к метке , а переходит к следующей инструкции.
Вы можете рассматривать DJNZ
как две инструкции, аналогичные
DEC R2 JNZ СНОВА; ПРИМЕЧАНИЕ. 8051 не имеет флага Zero — его необходимо ; используйте для этого ACC, так что относитесь к этому как к псевдокоду!
Вы можете использовать симулятор, такой как http://www.edsim51.com/, чтобы выполнить инструкции и посмотреть, как регистры меняются на каждом этапе. Это очень полезно для изучения поведения конкретных инструкций.
Метка не обойдена. Если вы посмотрите на работу цикла, вы увидите, что сначала DJNZ уменьшает значение регистра, а затем, если результат не равен нулю, он выполняет метку. В 1-м примере, начиная сверху:
1) A получает ноль, затем
2) R2 получает 10, затем
3) A получает 25, затем
4) DJNZ уменьшает значение R2, делая его равным 9, и, поскольку результат не равен нулю, выполняет СНОВА и добавляет 25 в А, получается 50 и так далее.
Когда значение R2 достигает 1, DJNZ уменьшает его, и результат равен нулю, поэтому он больше не будет выполняться. Следовательно, DJNZ выполняется 9 раз, что дает результат 25*9=225. Но так как перед выполнением цикла DJNZ в A было сохранено 25, результат равен 250. Надеюсь, это поможет вам.
1
Зарегистрируйтесь или войдите в систему
Зарегистрируйтесь с помощью Google
Зарегистрироваться через Facebook
Зарегистрируйтесь, используя электронную почту и пароль
Опубликовать как гость
Электронная почта
Требуется, но никогда не отображается
Опубликовать как гость
Электронная почта
Требуется, но не отображается
ретро-вычислений — Как метки выполняются в сборке?
Метки — это адреса (и обратите внимание, что имена функций в языках высокого уровня — это в основном метки).
цикл: нет нет прыжковая петля
это позволяет вам писать код, который имеет две функции. Во-первых, каков адрес цикла, 0x12345 или 0x8000 и т. д. Во-вторых, если моя инструкция псевдокода, установленная здесь, инструкция перехода работает с фиксированными адресами, поэтому для полного кодирования нужно знать 0x12345 или 0x8000. Инструкция или это относительно, где без меток программисту пришлось бы считать байты инструкции. Если бы nops были одним байтом каждый, а сам переход относителен, и, скажем, три байта, а смещение pc относительно конца инструкции, тогда вам нужно было бы сказать jump -5 в вашем коде, тогда, если вы добавили или удалили инструкции в loop вам придется пересчитывать смещения прыжка без ошибок.
Другой случай, опять же адресный, для внешних ссылок:
fun: позвони more_fun ...
Если вы живете в наше время, когда вы можете сделать более одного файла исходного кода объектами, а затем связать их. (некоторые инструменты все еще поддерживают это, это было более распространено, когда я начал иметь один ассемблерный файл с . org и т. Д., И никаких внешних ссылок, только прямые и обратные ссылки). Затем вы можете иметь внешние ссылки, независимо от того, использует ли набор инструкций абсолютная или относительная адресация, чтобы завершить создание машинного кода для этого вызова, этот адрес необходимо разрешить. Таким образом, использование метки значительно упрощает работу программиста, и, как и в случае с локальными ссылками, инструменты могут вычислить все эти смещения или адреса для вас.
.большой палец нет нет нет петля: нет нет нет б петля Разборка раздела .text: 00000000 <цикл-0x6>: 0: 46c0 нет ; (движение r8, r8) 2: 46c0 нет; (движение r8, r8) 4: 46c0 нет; (движение r8, r8) 00000006 <цикл>: 6: 46c0 нет; (движение r8, r8) 8: 46c0 нет; (движение r8, r8) а: 46c0 нет; (движение r8, r8) c: e7fb b.n 6 <петля>
, поэтому второй столбец чисел (оба столбца в шестнадцатеричном формате) — это машинный код. Вы можете видеть, что на этикетке нет машинного кода, это просто этикетка, маркировка на коробке, она описывает вещь на коробке, а не содержимое своей коробки.
И я просто скажу вам, что переход к циклическому кодированию младших битов является смещением, и в этом значении много единиц, потому что это отрицательное число (относительно pc-перехода назад).
Указанные выше адреса не связаны.
Один файл:
.thumb нет нет петля: бл more_fun б петля
Другое:
.thumb .thumb_func .globl more_fun Больше удовольствия: бх л
unlinked мы видим, что дизассемблированный вызов (ссылка ветвления bl в этом наборе инструкций) имеет в основном заполнитель для смещения.
Разборка раздела .text: 00000000 <цикл-0x4>: 0: 46c0 нет ; (движение r8, r8) 2: 46c0 нет; (движение r8, r8) 00000004 <цикл>: 4: f7ff fffe bl 08: e7fc б.н 4 <петля>
однократно связанный
Разборка раздела .text: 00001000 <цикл-0x4>: 1000: 46c0 нет; (движение r8, r8) 1002: 46c0 нет; (движение r8, r8) 00001004 <цикл>: 1004: f000 f801 бл 100а1008: e7fc b.