Как стать программистом Как устроен компьютер. Что такое программа. Как написать свою программу. И многое другое узнаете вы из этой книги. Получить бесплатно! |
Как узнать состояние флага
Лучшие книги по Ассемблеру
Сделал подборку не новых, но проверенных книг по программированию на языке ассемблера. Если вы также как и я любите погружаться на низкий уровень, в те закоулки мира программирования, куда не всем путь открыт, то посмотрите. Возможно, что-то вам понравится. Подробнее... |
Как-то один из подписчиков моего канала на Ютуб спросил о том, как можно узнать состояние бита в регистре флагов, то есть состояние отдельного флага. Поскольку ответить на этот вопрос в полной мере в комментариях довольно сложно, я решил посвятить этому отдельную статью.
Вообще это требуется редко. Обычно флаги проверяются после выполнения таких команд, как CMP, инструкциями перехода, такими, например, как JB.
В языках ассемблера для микроконтроллеров могут быть специальные команды или глобальные переменные, с помощью которых можно получить или установить значение отдельного флага.
Но в наборе команд процессора Intel таких инструкций нет, поэтому, если вам очень захотелось узнать состояние отдельного флага, то придётся подойти к решению этой задачи творчески…
Итак, в языках Ассемблера INTEL есть по крайней мере три способа получить состояние отдельного флага. Далее мы их рассмотрим.
Использование команд перехода
Этот способ вы наверняка уже использовали, сами того не подозревая. Суть его проста - почти все команды условного перехода проверяют какие-то флаги. Соответственно, с их помощью можно узнать состояние этих флагов. Правда, некоторые команды перехода проверяют не один, а несколько флагов. Такие команды для нас не подойдут. А вот те, которые проверяют только один флаг - это то, что нам нужно. Вот они:
Команда | Условие перехода |
JZ, JE | ZF = 1 |
JC, JB, JNAE | CF = 1 |
JS | SF = 1 |
JO | OF = 1 |
JPE, JP | PF = 1 |
JNZ, JNE | ZF = 0 |
JNC, JNB, JAE | CF = 0 |
JNS | SF = 0 |
JNO | OF = 0 |
JPO, JNP | PF = 0 |
Как видно из таблицы, с помощью команд перехода можно проверить почти все основные флаги.
А теперь о том, как это использовать. Поясню на примере:
.model tiny .code ORG 100h start: MOV AH, 7 CMP AH, 7 ;ZF = 1 JZ ZF_1 JMP ZF_0 ZF_1: ;Если ZF = 1, то MOV AH, 1 ;в AH запишем 1 ZF_0: ;Если ZF = 0, то MOV AH, 0 ;в AH запишем 0 RET END start
Если флаг ZF = 1, то мы переходим к метке ZF_1 и записываем в регистр АН число 1. Если флаг ZF = 0, то мы переходим к метке ZF_0 и записываем в регистр АН число 0. Таким образом мы узнаём состояние флага ZF и записываем его в регистр AH.
Чтение флагов в регистр
Имеется также особая команда, которая позволяет загрузить младшие 8 битов регистра флагов в регистр AH. Это команда LAHF. Пример:
.model tiny .code ORG 100h start: LAHF ;AH = 02h = 00000010 (ZF = 0) MOV BH, 7 CMP BH, 7 LAHF ;AH = 46h = 01000110 (ZF = 1, PF = 1) RET END start
Разряды регистра АН и флаги, которые в них загружает команда LAHF | |||||||
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
SF | ZF | 0 | AF | 0 | PF | 1 | CF |
То есть в разряд 1 всегда загружается единица (поэтому в примере выше первый вызов LAHF загрузил в АН число 2), в разряды 3 и 5 всегда загружается 0. В остальные разряды загружаются состояния соответствующих флагов на момент вызова команды LAHF.
Чтение флагов через стек
Есть также команда PUSHF, которая загружает регистр флагов в стек. Преимущество этой команды в том, что она загружает все флаги (даже если регистр флагов 32-разрядный). Однако её не советуют использовать без крайней необходимости, потому что она выполняется довольно медленно (иногда это важно).
Ещё одно удобство этой команды заключается в том, что она загружает именно регистр флагов. И если потом выгрузить стек, например, в регистр АХ, то все биты регистра АХ будут установлены в том же порядке, что и биты регистра флагов. Пример:
.model tiny .code ORG 100h start: PUSHF ;Получить регистр флагов в стек POP AX ;Выгрузить из стека а АХ (АХ = 0202h) STC ;Установить флаг CF PUSHF ;Получить регистр флагов в стек POP AX ;Выгрузить из стека а АХ (АХ = 0203h) RET END start
Команда STC устанавливает флаг CF. Но об этом как-нибудь в другой раз...
Подписаться на канал в РУТуб
Вступить в группу "Основы программирования" Подписаться на рассылки по программированию |