Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Вопросы и ответы нах / Arkhitektura_kompyutera_1.docx
Скачиваний:
22
Добавлен:
19.03.2015
Размер:
68.1 Кб
Скачать
  1. Язык программирования Ассемблер. Базовые элементы. Основные операции над регистрами.

Assembler — язык программирования низкого уровня, представляющий собой формат записи машинных команд, удобный для восприятия человеком.

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

Директивы ассемблера позволяют включать в программу блоки данных (описанные явно или считанные из файла); повторить определённый фрагмент указанное число раз; компилировать фрагмент по условию; задавать адрес исполнения фрагмента, менять значения меток в процессе компиляции; использовать макроопределения с параметрами и др.

Каждая модель процессора, в принципе, имеет свой набор команд и соответствующий ему язык (или диалект) ассемблера.

Достоинства и недостатки

  • минимальное количество избыточного кода (использование меньшего количества команд и обращений в память). Как следствие — большая скорость и меньший размер программы

  • большие объемы кода, большое число дополнительных мелких задач

  • плохая читабельность кода, трудность поддержки (отладка, добавление возможностей)

  • трудность реализации парадигм программирования и любых других сколько-нибудь сложных конвенций, сложность совместной разработки

  • меньшее количество доступных библиотек, их малая совместимость

  • непосредственный доступ к аппаратуре: портам ввода-вывода, особым регистрам процессора

  • возможность написания самомодифицирующегося кода (т.е. метапрограммирования, причем без необходимости программного интерпретатора)

  • максимальная «подгонка» для нужной платформы (использование специальных инструкций, технических особенностей «железа»)

  • непереносимость на другие платформы (кроме двоично совместимых).

Основными элементами ассемблера являются директивы ассемблера и команды МП.

Команды описывают действия МП в процессе выполнения программы и всегда порождают машинный код в памяти системы.

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

Программа на ассемблере представляет собой совокупность строк. Каждая строка содержит лишь одну команду МП или директиву ассемблера.

Формат командной строки имеет вид:

КОМАНДА

Здесь и далее фигурные скобки показывают необязательность заключенного в них элемента.

МЕТКА - это определенное программистом имя, используемое для пометки данной команды. Значением метки является адрес помеченной команды. Метки всегда заканчиваются двоеточием и используются в качестве операндов в командах передачи управления.

ПРЕФИКС - в этом поле помещается один из программных префиксов: префикс повторения REP или префикс блокировки LOCK, которые предшествуют команде и вызывают соответствующие действия.

КОМАНДА - в этом поле указывается мнемоническое имя команды, определяющее выполняемые действия.

ОПЕРАНДЫ - в этом поле описываются данные, над которыми выполняется операция, предписанная командой.

КОММЕНТАРИЙ - любая последовательность символов, начинающаяся с ;. Комментарий не влияет на выполнение команды и предназначен для пояснения выполняемых действий в контексте данной точки программы.

Формат директивной строки ассемблера имеет вид:

ДИРЕКТИВА

ИМЯ - это идентификатор каких-либо данных. Имя данных не имеет ничего общего с меткой и двоеточием не заканчивается.

ДИРЕКТИВА √ это поле содержит мнемоническое имя директивы, определяющее действия, выполняемые ассемблером в процессе трансляции программы.

Поля ОПЕРАНДЫ и КОММЕНТАРИЙ аналогичны соответствующим полям командной строки.

Все поля программной строки должны разделяться по меньшей мере одним пробелом или знаком табуляции. Программная строка может начинаться не с первой позиции. Ее длина не должна превышать 132 знака.

Перечислим основные арифметические команды, используемые для организации вычислений.

Таблица 1. Основные арифметические команды

Команда

Назначение

ADD (Сложение)

Определяет двоичную сумму двух указанных операндов.

ADC (Сложение с переносом)

Определяет двоичную сумму двух указанных операндов и содержимого флага переноса CF.

INC (Инкремент)

Увеличивает содержимое операнда на 1.

SUB (Вычитание)

Определяет разность уменьшаемого и вычитаемого.

SBB (Вычитание с заемом)

Определяет разность двух операндов, и, кроме того, из уменьшаемого вычитается содержимое флага переноса.

DEC (Декремент)

Уменьшает содержимое операнда на единицу.

MUL (Умножение)

Производит беззнаковое умножение содержимого аккумулятора (регистра AL при байтовом умножении и регистра AX при умножении слов) на указанный операнд.

IMUL (Умножение целых чисел с учетом знака)

Производит умножение аккумулятора на указанный операнд с учетом знаков.

DIV (Деление)

Осуществляет деление содержимого аккумулятора (AX при байтовом делении или пары регистров DX и AX при делении слов) на указанный операнд без учета знаков.

IDIV (Деление чисел с учетом знака)

Выполняет деление содержимого аккумулятора (AX при делении байтовых чисел или пары регистров DX и AX при делении слов) на указанный операнд с учетом знаков.

MOV (Пересылка данных)

Пересылает данные из одного операнда в другой.

XCHG (Обмен значениями)

Меняет местами содержимое двух операндов.

NEG (Получение противоположного значения)

Меняет знак операнда на противоположный.

ассмотрим более подробно перечисленные команды.

    1. ADD (Сложение). Определяет двоичную сумму двух указанных операндов. Результат помещается на место операнда-приемника, второй операнд остается без изменения. Общий вид:

ADD <1-й операнд>, <2-й операнд>

<1-й операнд> <-- <1-й операнд> + <2-й операнд> .

    Местом хранения первого операнда может быть регистр или ячейка памяти; второго операнда - регистр или ячейка памяти, либо он может быть задан константой. Не разрешается использовать для записи операндов сегментные регистры, а также ячейки памяти для одновременного хранения двух операндов. Операнды могут быть числами со знаком или без него и представлять собой байты или слова.

    Пример. Пусть регистр DL содержит число 58H, однобайтовая ячейка памяти TEST_BYTE содержит 27H. После выполнения команды ADD TEST_BYTE,DL в ячейку памяти будет записано 7FH:

содержимое регистра DL: 0101 10002 = 58H ;

содержимое ячейки TEST_BYTE: 0010 01112 = 27H;

новое содержимое ячейки TEST_BYTE: 0111 11112 = 7FH.

    Флаги, затрагиваемые операцией: OF, ZF, AF, PF, CF.

   

    2. ADC (Сложение с переносом). Определяет двоичную сумму двух указанных операндов и содержимого флага переноса CF. Результат помещается на место операнда-приемника, второй операнд остается без изменений. Общий вид:

ADC <1-й операнд>, <2-й операнд>

<1-й операнд> <-- <1-й операнд> + <2-й операнд> + <CF> .

    Команда работает с байтами и со словами, со знаковыми и беззнаковыми двоичными числами. Первый операнд может храниться в регистре или ячейке памяти. Второй операнд может быть задан в регистре, ячейке памяти или непосредственным числовым значением. Не разрешается задавать операнды в регистрах сегментов, а также хранение (запись) двух операндов одновременно в ячейках памяти. Операнды могут быть байтами или словами, представлять числа со знаком или без знака. Поскольку команда ADC использует флаг переноса CF, то она может применяться для сложения чисел, длина которых превышает 16 бит.

    Пример 1. Пусть регистр BX содержит число 4803H, регистр AX - число 2517H, а регистр флагов процессора содержит значение F047H (11110000010001112), то есть флаг переноса CF равен 1. После выполнения команды ADC AX,BX вместо 2517H в регистре AX будет записано 6D1BH:

содержимое BX: 0100 1000 0000 0011 = 4803H;

содержимое AX: 0010 0101 0001 0111 = 2517H;

флаг переноса CF: 1 ;

новое содержимое AX: 0110 1101 0001 1011 = 6D1BH.

    Пример 2. Проиллюстрируем использование этой команды при сложении так называемых "длинных" чисел, которые на помещаются в одно слово. Пусть требуется сложить два таких числа:

224810H

23E1ADH

Сначала сложим младшие слова этих чисел, используя команду ADD:

4810H

E1ADH

------

(1)29BDH

Единица в скобках - это значение флага CF. Одновременно это значение, которое должно быть перенесено в следующий разряд. Мы должны его учесть при сложении старших разрядов этих чисел. Поэтому нужно воспользоваться командой ADC:

22H

23H

1H ;Перенос от предыдущей операции.

------

46H

Таким образом, окончательный результат будет следующим:

4629BDH .

    Флаги, затрагиваемые операцией: OF, SF, ZF, AF, PF, CF.

   

    3. INC (Инкремент). Увеличивает содержимое операнда на 1. Общий вид:

INC <операнд>

<операнд> <-- <операнд> + 1 .

    Операнд может быть задан в регистре общего назначения или в ячейке памяти. Сегментные регистры не могут быть использованы для хранения операндов. Команда INC может использоваться как с однобайтовыми, так и двухбайтовыми операндами. Операнды интерпретируются как числа без знака. Команда воздействует на флаги OF, SF, ZF, AF, PF.

    Пример. Пусть регистр BX задает двухбайтовую область памяти с содержимым FE00H и выполняется команда INC WORD PTR [BX]. Новым содержимым памяти после выполнения команды будет число FE01H. Так как результатом операции является отрицательное, отличное от нуля число в дополнительном коде, то флаг SF установлен в 1, а флаг ZF - в 0. Наличие только одного отличного от нуля разряда в младшем байте слова обусловливает сброс флага PF в 0.

    Замечание. Выражение [BX] сообщает Ассемблеру, что регистр BX содержит адрес операнда, а не является операндом сам по себе. Скобки [ и ], заключающие какое-либо значение, указывают Ассемблеру, что это значение - адрес. Другая часть выражения, WORD PTR, требуется Ассемблеру для информации, что операнд является переменной типа WORD (слово).

   

    4. SUB (Вычитание). Определяет разность уменьшаемого и вычитаемого. Результат помещается на место уменьшаемого, вычитаемое остается без изменений. Общий вид:

SUB <1-й операнд>, <2-й операнд>

<1-й операнд> <-- <1-й операнд> - <2-й операнд> .

    Первый операнд может быть задан в регистре или ячейке памяти. Второй операнд может быть задан в регистре, ячейке памяти или непосредственно константой. Не допускается использование сегментных регистров или одновременная запись этих операндов в ячейках памяти. Операнды могут быть как знаковыми, так и беззнаковыми числами. Возможно выполнение 8- и 16-разрядных операций.

    Пример. Рассмотрим случай, когда регистр DL содержит число 58H, регистр DH - число 20H. После выполнения команды SUB DL,DH в регистре DL будет записано число 38H.

    Флаги, затрагиваемые операцией: OF, SF, ZF, AF, PF, CF.

   

    5. SBB (Вычитание с заемом). Определяет разность двух операндов, и, кроме того, из уменьшаемого вычитается содержимое флага переноса:

SBB <1-й операнд>, <2-й операнд>

<1-й операнд> <-- <1-й операнд> - <2-й операнд> - <CF> .

    Результат помещается на место первого операнда, предыдущее значение которого теряется. Содержимое второго операнда не изменяется.

    Первый операнд может быть задан в регистре или ячейке памяти. Второй операнд, кроме того, может быть задан константой. Не допускается использовать для записи операндов сегментные регистры или задавать оба операнда в ячейках памяти. Операнды могут быть однобайтовыми или двухбайтовыми числами со знаком или без знака. Возможность заема позволяет использовать команду SBB для организации вычитания чисел с разрядностью, превышающей 16 бит.

    Пример. Пусть регистр AX содержит число 4803H, регистр флагов - F047H, флаг CF установлен в 1. После выполнения команды SBB AX, 1500H в регистре AX будет записано 3302H. Флаги, затрагиваемые операцией: OF, SF, ZF, AF, PF, CF.

    6. DEC (Декремент). Уменьшает содержимое операнда на единицу:

DEC <операнд>

<операнд> <-- <операнд> - 1 .

    Операнд может храниться в регистре общего назначения или ячейке памяти. Не допускается задание операндов в регистрах сегментов. Операция выполняется как над однобайтовыми, так и над двухбайтовыми числами. Операнд рассматривается как беззнаковое число. Команда DEC не воздействует на флаг CF.

    Пример. Пусть в регистре BL записано 00 и выполняется команда DEC BL. Новым содержимым регистра BL будет число FFH. Так как результат является отрицательным, отличным от нуля числом в дополнительном коде, флаг знака SF устанавливается в 1, а флаг нуля ZF сбрасывается в 0. Поскольку в результате присутствует восемь отличных от нуля битов, то есть четное число, то флаг паритета PF тоже установлен в 1.

    Флаги, затрагиваемые операцией: OF, SF, ZF, AF, PF.

    7. MUL (Умножение). Производит беззнаковое умножение содержимого аккумулятора (регистра AL при байтовом умножении и регистра AX при умножении слов) на указанный операнд. Общий вид:

MUL <операнд>

    Если операнд является байтом, то он умножается на содержимое регистра AL и результат двойной длины (слово) записывается в регистр AX. Если операнд - слово, то он умножается на содержимое регистра AX и результат (двойное слово) записывается в пару регистров DX и AX, причем регистр DX содержит старшие разряды результата. Операнд может быть задан в регистре общего назначения или ячейке памяти и интерпретируется как число без знака. Описанный порядок выполнения команды умножения сведен в таблицу 2.

Таблица 2. Порядок выполнения команды MUL

Размер операнда

Аккумулятор

Местоположение результата

Один байт

AL

AX

Одно слово (два байта)

AX

DX:AX

    Если содержимое регистра AH после однобайтового умножения или содержимое регистра DX после двухбайтового умножения не равны нулю, флаги CF и OF устанавливаются в 1. В противном случае они сбрасываются в 0. Состояние флагов SF, ZF, AF, PF после команды MUL не определено.

    Пример 1. Пусть регистр AL содержит число 30H, однобайтовая ячейка памяти NEXT_L содержит 12H и выполняется команда MUL NEXT_L. Результат умножения (12H Х 30H = 360H) записывается в регистр AX. Поскольку содержимое регистра AH отлично от 0, флаги CF и OF установлены в 1.

    Пример 2. Пусть теперь регистр AX содержит число 1000H, регистр BX - число 550H. Тогда после выполнения команды MUL BX результат умножения (1000H Х 550H = 550000H) будет записан в пару регистров DX и AX. Так как новое значение регистра DX (0055H) отлично от нуля, то флаги CF и OF устанавливаются в 1.

    Флаги, затрагиваемые операцией: OF, SF, ZF, AF, PF, CF.

    8. IMUL (Умножение целых чисел с учетом знака). Производит умножение аккумулятора на указанный операнд с учетом знаков. Результатом байтового умножения является 16-битовое число, хранящееся в регистре AX. Результат умножения слов - 32-битовое число в паре регистров DX и AX, причем в DX - старшие 16 бит результата. Если старшая часть (AH при байтовом умножении или DX при длинах операндов, равных слову) содержит не знак младшей части результата, а его значащие цифры, флаги CF и OF переводятся в единичное состояние. В противном случае оба флага обнуляются. После выполнения IMUL состояние флагов AF, PF, SF и ZF становится неопределенным.

    Флаги, затрагиваемые операцией: OF, SF, ZF, AF, PF, CF.

    9. DIV (Деление). Осуществляет деление содержимого аккумулятора (AX при байтовом делении или пары регистров DX и AX при делении слов) на указанный операнд без учета знаков. Общий вид:

DIV <операнд>

    Результат выполнения команды деления приведен в таблице 3.

Таблица 3. Порядок выполнения команды DIV

Размер операнда

Аккумулятор

Частное

Остаток

Один байт

AX

AL

AH

Одно слово (два байта)

DX:AX

AX

DX

    Таким образом, при 8-битовом делении целая часть отношения помещается в регистр AL, а остаток - в регистр AH. При этом, если результат деления будет больше FFH, то генерируется прерывание типа 0 (ошибка при делении).

    Для двухбайтовых операций выполняется деление содержимого регистровой пары DX:AX на указанный операнд. Если результата деления больше FFFFH, то генерируется прерывание типа 0. При 16-битовом делении целая часть отношения размещается в регистре AX, а остаток - в регистре DX.

    Операнд может быть задан в регистре общего назначения или ячейке памяти, при этом операнд рассматривается как беззнаковый 8- или 16-битовый делитель соответственно при однобайтовом и двухбайтовом делении.

    После выполнения команды DIV состояния разрядов регистра флагов процессора не определены. Если произошло переполнение, то частное и остаток не определены.

    Пример 1. Пусть регистр AX содержит число 0047H, регистр CL - число 12H и выполняется команда DIV CL. Частное от деления (03H=47H/12H) записывается в регистр AL, а остаток 11H - в регистр AH.

    Пример 2. Рассмотрим случай, когда регистры DX и AX содержат соответственно значения 0012H и F043H, представляющие 32-разрядное шестнадцатеричное число 0012F043H, регистр BP содержит число 4320H и выполняется команда DIV BP. Частное от деления (0048H=12F043H/4320H) записывается в регистр AX, а остаток (0F43H) - в регистр DX.

    Флаги, затрагиваемые операцией: OF, SF, ZF, AF, PF, CF.

    10. IDIV (Деление чисел с учетом знака). Выполняет деление содержимого аккумулятора (AX при делении байтовых чисел или пары регистров DX и AX при делении слов) на указанный операнд с учетом знаков. При 8-битовом делении отношение размещается в регистре AL, а остаток - в регистре AH. При 16-битовом делении регистр AX содержит частное, а регистр DX - остаток. При байтовом делении максимальное положительное частное не превышает 127 (7FH), а минимальное отрицательное не может быть меньше -127 (81H). При делении чисел длиной в слово максимальное положительное отношение равно 32767 (7FFFH), а минимальное отрицательное частное равно -32767 (8001H). Если отношение меньше допустимого минимума или больше максимума или если произведена попытка деления на 0, микропроцессор автоматически генерирует прерывание типа 0 (прерывание из-за ошибки деления). Отношение всегда усекается до целой части. Флаги, затрагиваемые операцией: OF, SF, ZF, AF, PF, CF.

   

    11. Для написания простейших программ на языке Ассемблера необходима еще одна команда, непосредственно не относящаяся с арифметическим командам. Это команда MOV (Пересылка данных):

MOV <1-й операнд>, <2-й операнд>

<1-й операнд> <-- <2-й операнд> .

    Второй операнд при выполнении команды MOV занимает место хранения первого операнда. При этом первый операнд теряется.

    Первый операнд может быть задан в регистре общего назначения, регистре сегмента (кроме регистра CS) или ячейки памяти. Второй операнд, кроме того, может быть еще и константой. Команда MOV работает как с однобайтовыми, так и с двухбайтовыми словами.

    Пример. Пусть регистр CX содержит слово 04C5H, а регистр BP - слово 2312H. После выполнения команды MOV CX,BP содержимым регистра CX будет слово 2312H, а содержимое регистра BP не изменится.

    12. Команда замены XCHG меняет местами содержимое двух операндов. Эта команда может поменять местами содержимое двух регистров, или регистра и памяти. При этом в качестве операндов не могут использоваться сегментные регистры. Общий вид:

XCHG <1-й операнд>, <2-й операнд>

<1-й операнд> <--> <2-й операнд> .

        13. Иногда, зная положительное число, требуется получить противоположное ему отрицательное число. Для этого используется команда NEG, обеспечивающая преобразование знака двоичных чисел из положительного в отрицательное и наоборот. Общий вид:

NEG <операнд> .

    Пример. Пусть регистр AX содержит слово 0001H. После выполнения команды NEG AX содержимым регистра AX будет FFFFH. Таким образом, команда NEG инвертирует значения битов и прибавляет 1.

Соседние файлы в папке Вопросы и ответы нах