- Asmworld - http://asmworld.ru -

Учебный курс. Часть 24. Команды управления флагами

Posted By xrnd On 10.09.2010 @ 01:23 In Учебный курс | 13 Comments

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

Как вы, наверно, помните флаги изменяются в результате выполнения арифметических и логических команд, а также команд сдвига. Регистр флагов можно сохранить в стек с помощью команды PUSHF [1] и восстановить из стека с помощью команды POPF [2]. Кроме того, в процессоре существуют специальные команды, которые позволяют явно установить или сбросить флаги CF, DF и IF. Это очень простые команды: у них нет операндов и результатом является только изменение значения соответствующего флага.

Флаг переноса CF

Команда CLC [3] сбрасывает флаг CF.

Команда STC [4] устанавливает флаг CF в единицу.

Команда CMC [5] инвертирует значение флага CF.

Флаг направления DF

Этот флаг определяет направление обработки данных цепочечными командами (о них подробно расскажу в отдельной статье). Он должен устанавливаться или сбрасываться перед использованием этих команд.

Команда CLD [6] сбрасывает флаг DF.

Команда STD [7] устанавливает флаг DF в единицу.

Флаг прерывания IF

Этот флаг определяет, разрешены в данный момент прерывания или нет (о прерываниях тоже будет отдельная статья).

Команда CLI [8] сбрасывает флаг IF (запрещает прерывания).

Команда STI [9] устанавливает флаг IF в единицу (разрешает прерывания).

Команды LAHF и SAHF

Команда LAHF [10] загружает младший байт регистра флагов в AH. Её удобно использовать, когда нужно получить значения сразу нескольких флагов. Порядок расположения флагов представлен на рисунке:

Команда SAHF [11] выполняет обратную операцию — загружает содержимое AH в младший байт регистра флагов. Это позволяет одновременно изменить значения нескольких флагов. При этом биты 1, 3, 5 регистра AH игнорируются.

Пример программы

В качестве примера использования команды LAHF [10] я написал процедуру, которая получает и выводит на консоль значения флагов SF, ZF, AF, PF и CF. Подобную процедуру можно использовать в отладочных целях. Достаточно добавить её вызов в то место программы, где хочется проверить состояние флагов.

Чтобы выводить значения отдельных битов удобно написать отдельную процедурку для печати флага CF в виде символа. Нужный бит будет помещаться в флаг CF при помощи команды сдвига SHL [12].

;Процедура вывода значения флага CF в виде символа
print_cf:
    push ax
    push dx
    mov ah,2                ;Функция DOS 02h - вывод символа
    mov dl,'0'              ;DL = '0'
    adc dl,0                ;Если CF = 1, то в DL будет символ '1'
    int 21h                 ;Обращение к функции DOS
    pop dx
    pop ax
    ret

А вот собственно процедура вывода флагов. Как видите, здесь нет ничего сложного :) Процедура сохраняет регистр флагов и восстанавливает его перед возвратом управления, поэтому можно вызывать её где угодно, не волнуясь, что она нарушит выполнение основной программы.

;Процедура вывода состояния флагов на консоль
print_flags:
    push ax
    push cx
    push dx
    pushf                   ;Сохранение регистра флагов
    lahf                    ;Загрузка младшего байта FLAGS в AH
    mov cl,ah               ;CL = AH
    mov ah,9                ;Функция DOS 09h - вывод строки
    mov dx,s_sf             ;DX = адрес строки 'FLAGS: SF='
    int 21h                 ;Обращение к функции DOS
    shl cl,1                ;Сдвиг CL влево на 1 бит
    call print_cf           ;Печать выдвинутого бита
    mov dx,s_zf
    int 21h                 ;Вывод строки ' ZF='
    shl cl,1                ;Сдвиг CL влево на 1 бит
    call print_cf           ;Печать выдвинутого бита
    mov dx,s_af
    int 21h                 ;Вывод строки ' AF='
    shl cl,2                ;Сдвиг CL влево на 2 бита
    call print_cf           ;Печать выдвинутого бита
    mov dx,s_pf
    int 21h                 ;Вывод строки ' PF='
    shl cl,2                ;Сдвиг CL влево на 2 бита
    call print_cf           ;Печать выдвинутого бита
    mov dx,s_cf
    int 21h                 ;Вывод строки ' CF='
    shl cl,2                ;Сдвиг CL влево на 2 бита
    call print_cf           ;Печать выдвинутого бита
    mov dx,s_endl
    int 21h                 ;Вывод конца строки
    popf                    ;Восстановление регистра флагов
    pop dx
    pop cx
    pop ax
    ret

Полный исходный код примера — printflags.asm [13]. Вывод программы выглядит так:

Упражнение

Чтобы потренироваться в работе с флагами напишите следующую программу. Вычислите сумму значений флагов CF, SF, ZF и выведите на консоль результат сложения. Если результат больше 1, инвертируйте значение флага CF :)

Следующая часть » [14]


Article printed from Asmworld: http://asmworld.ru

URL to article: http://asmworld.ru/uchebnyj-kurs/024-komandy-upravleniya-flagami/

URLs in this post:

[1] PUSHF: http://asmworld.ru/spravochnik-komand/pushf

[2] POPF: http://asmworld.ru/spravochnik-komand/popf

[3] CLC: http://asmworld.ru/spravochnik-komand/clc

[4] STC: http://asmworld.ru/spravochnik-komand/stc

[5] CMC: http://asmworld.ru/spravochnik-komand/cmc

[6] CLD: http://asmworld.ru/spravochnik-komand/cld

[7] STD: http://asmworld.ru/spravochnik-komand/std

[8] CLI: http://asmworld.ru/spravochnik-komand/cli

[9] STI: http://asmworld.ru/spravochnik-komand/sti

[10] LAHF: http://asmworld.ru/spravochnik-komand/lahf

[11] SAHF: http://asmworld.ru/spravochnik-komand/sahf

[12] SHL: http://asmworld.ru/spravochnik-komand/shl

[13] printflags.asm: http://asmworld.ru/content/course/024/printflags.asm

[14] Следующая часть »: http://asmworld.ru/uchebnyj-kurs/025-peredacha-parametrov-cherez-stek/

Copyright © 2009-2010 Asmworld. All rights reserved.