В.Н. Пильщиков - Программирование на языке ассемблера IBM PC (1110551), страница 4
Текст из файла (страница 4)
Если можно определить размеры обоих операндов, тогда эти размеры должны совпадать (либо байты, либо слова), иначе ассеыблер зафиксирует ошибку. Например: ИОЧ 01 ЕВ иоч се,х ипч вх,ле МОЧ ВЕ,З00 парасылка слова пересылка байта оввбка (ВХ - слово, ЛГ. - байт) оввбка (ВЛ - байт, а 300 ва молот бать байтом) Отметим, что при пересылках иикаких преобразований байта в слово или слова в байт ис производится. 3.2.2. Оператор указаиия типа (РТК) А теперь рассмотрим ситуацию, когда по операндам команды МО'1) нельзя определить размер пересылаемой величины. Забегая вперед, отметим, что если некоторый адрес А надо ьюдифицировать, скажем, по регистру Б1, то в ЯА это записывается' тюг: А[БЦ. Испазиительиый адрес в этом случае вычисляется по формуле АиспмА+[БЦ. В частности, при Амй эта запись имеет вид [БЦ (О ие указывается) и задает исполнительный адрес, равиый содержимому регистра Б1: Аиспм[БЦ.
С учетоы этого рассыотрим такую задачу. Пусчь в регистре Б1 находится адрес некоторой ячейки памяти и требуется записать О в эту ячейку. Тогда, казалось бы, такое обиулеиие ыожио сделать с помощью команды иоч (ах),0 Однако это ие так. Лево в тои, что по этой команде нельзя понять, какого размера ноль пересылается, поскольку второй операнд может обозначать ноль как разыером в байт (ОО))), так и размером в слово (ООООЬ), а что касается перво- Как правило, в команде МОУ легко у)лается тип (размер) одного из операидов, ои и определяет размер пересылаемой величины.
Например: Пересылки. Арифметические комеиди 4В го операнда, то адрес из регистра Я ьюжет быть адресом ячейки каК размером в байт, так и размером в слово (напоыннм, что с одного и того же адреса ыогуг начинаться ячейкн разных разыеров). Итак, в этой коыанде нн по первоыу, нн по второму операнду нельзя опредедить размер пересылаеьшй величины, а потому ассемблер не сможет определить, на какую конкретную машинную коьганзу эюченять зту снывольную коыанду. В подобных снтуывих ассемблер фиксирует ошибку, сообщая, что типы операндов нензвестны. Чтобы не было этой ошибки, автор программы должен явно указать тип хотя бы одного из операндов команды. Для этого в ЯА введен оператор указания типа РТК (от ро[пгег, указатель), который записывается следующим образом: <теп> РТВ <ввравевие> где <тнп> - зто ВУТЕ, 'т[ГОК[Э нлн [)%ОК[) (есть и лругне варианты, но ыы нх пока не рассматриваем), а выраженне ыожет быть константным нлн адресным.
Еслн указано константное выражение, то оператор "говорит", что значение этого выражения (чнсло) должно рассыатриваться ассемблером кзк величина указанного типа (рэзыера); напрюгер, ВУТЕ РТК 0 - это но)гь как баГп; а %ОКО РТК 0 - зто ноль как слово (запнсь ВУТЕ РТК 300 ошибочна, т. к. число 300 не ыожет быть баГпоы). Отыетны, что в этом случае оператор РТК относится к констангным выраженняы. Если же в РТК указано адресное выражение, то оператор "говорит", что адрес, являющийся значением выражения, должен восприниматься ассемблером как адрес ячейки указанного типа (размера); напрныер: МОК[Э РТК А - адрес А обозначает слово (байгы с адресамн А н А+[).
В данном случае оператор РТК относятся к адресным выражением. С использованием оператора РТК паша задача решается тэк: еслн ыы имеем в виду обнуление байта по адресу из регистра 3[, то дчя этого надо попользовать команду НОЗ ВХТЕ РТВ [В1[,0 ивв МОЧ [ВХ[, ВТТЕ РТВ О а если надо переслать нулевое слово, то команду ноз вовп Ртд [в1[,О ивв ыоз [вх[, вовв Ртд О Отыетиы, что обычно принято уточнять тнп операнда-адреса, а не тнп непосредственного операнда.
Оператор РТК полезен еще в одной ситуации - когда надо не угочннть тнп операнда, а изменить его. Пусть, к прнчеру, 2 - переыенная разыероы в слово: З ВВ ХЗЗЗВ Гг: ЗЗВ, и+Хг Хдь и надо записать ноль не во все это слово, а только в его первый баГгг - в тот, где находится велнчина 34Ь. Так вот, сделать это кавщндой ноч з,в ЛИХЛОГ-МИФИ 48 Программирование нв язмяе ассемблера )ВМ рС Такое сумл)ирование с отбрасыванием единицы переноса в матеыатике называется суммированием по модулю 21 ()г - размер ячейки), при этом в флаге СР фиксируется, был ли перенос: х+у, если х+у< 2, СРмО сумма(х,у)м(х+у) пюй 2гм ~я+у-2, если х+у>м2; СРм1 При вычитании беззнаковых целых чисел также возникает проблема: что делать, если при вычитании х-у число х меньше числа у? Ведь в этом случае получится отрицательная разность, а это уже вне области беззнаковых чисел.
В ПК посгупают следующим образом: при х>=у выполняется обычное вычитание, но если х<у, тогда числу х дается "засы" единицы (к числу х прибэ)ьтяется величина 21) и только после этого производится вычитание. Полученное таким образом число и обьявляется разностью. Например, при )см8 вычитание 1-2 происходит таким образом: 1-2 > 12 +1)-2 = 1256+1)-2 2З7-2 2ЗЗ в (в двоичной системе замена 1 на 256+1 - это замена 00000001 на 100000001, т. е. приписывание 1 слева) и именно число 255 объявляется результатом вычитания 1-2.
При этом ошибка не фиксируется, зато в флаг переноса СР заносится 1, что сигнализирует о заеме единицы, о неправильном результате (при х>=у в СР заносится 0). Выполняемое так вычитание в математике называют вычитанием по модулю 2", при этоы фиксируется, был ли заем: 8е х-у, если х>му, СРмО ратисетЬ(Х,у)м(Х-у) ШОГ) 2 и (2+х)-у если х<у, Срм1 Итак, в ПК сложение и вычитание беззнаковых целых чисел - это на самом деле сложение и вычитание по ьгцдулю 2", где к - размер ячеек.
Причем появление после операции значения 1 в флаге переноса СР свидетельствует о том, что выданный ответ неправильный. Теперь рассмотрим сложение и вычитание знаковых чисел. Оказывается, если целые со знаком представлены в дополнительном коде, то складывать и вычитать их можно по алгоритмам для беззнаковых чисел.
Делается зто так: дополнительные коды знаковых операндов рассматривают квк числа без знака и в таком виде их складывают или вычитают, а полученный результат затем рассматривают как дополнительный код знакового ответа. Пример (при ячейке в 8 битов). Пусть надо сложить +3 и -1. Их дополнительные коды - зто 3 и (256-1)м255. Складываем их как числа без знака: 3+255 (шой 256) = 258 (шой 256) = 2. Теперь величина 2 рассматривается как дополнительный код ответа, поэтому получается ответ +2. Пересылки.
арифмвтичвокио команды аэ Другой пример. Пусп надо сложить -3 и +1. Дополнительные коды этих знаковых чисел: (256-3)=253 и 1. Складываем их как беззнаковые числа: 253+1 (щи 256) = 254. Теперь, рассматривая эгу величину кэк дополнительный код ответа, получаем результат -2 (254=256-2). Из сказанного следует, что в ЭВМ, где знаковые числа представляются в допс.чнительном коде, не нужны разные машинные команды для сложения и вычитания беззнаковых и знаковых чисел, достаточно и одного набора этих коыанд. (В этом важное преимущество дополнительного кода над другими способами прелставления знаковых чисел.) Однако не все так просто при сложении и вычитании знаковых чисел, здесь есть свои неприятности.
Напомним, что при размере ячеек в 8 бытов в дополнитедьном коде представляются только числа от -128 до +127. Рассмотрим, к примеру, сложение знаковых чисел +127 и +2. Складывая их как беззнаковые числа 127 и 2, пачучаезг величину 129, которую теперь надо рассмотреть как дополнительный код ответа: поскольку 129=256-127, то суммой должно быть признано число -127. Таким образом, складывая два положительных числа, мы получили отрицательное число! Почему так произошло? При представлении чисел (размером в байт) в дополнительном коде левый разряд является знаковым, а на модуль числа отводигся 7 правых разрядов.
У нас же получился ответ 129м10000001Ъ, модуль которого не вмещается в эти 7 разрядов, поэтому модуль и "залез" в знаковый разряд, изменив его на противоположный. Такое начезание модуля (ыантиссы, цифровой части) числа на знаковый разряд называют "переполнением мантиссы". В общем случае оно происходит, если складываются числа одного знака и настоящая сумма оказывается вне диапазона представимых знаковых чисел ([-128, +127] при )сы8). Переполнение мантиссы фиксируется в флаге переполнения ОР: он получает значение 1, если было переполнение, и значение 0 иначе.
Таким образом, при ОР=О результат правильный, а при ОР=1 - неправильный, однако эта ошибка не фиксируется и "пойпгать" ее можно только последующим анализом флага ОР. Аналогичное переполнение мантиссы воъюжно и при вычитании. Например, при вычитании (+127)-(-2) = 127+2 получаеы 129, а это дополнительный код числа -127, которое и выдается как результат вычитания, хотя истинной разностью якчяется число 129. В общем случае переполнение мантиссы происходит, если вычитаются числа разных знаков и настоящая разность оказалась вне диапазона представимых знаковых чисел. И здесь факт переполнения фиксируется в флаге ОР: он получает значение 1, если было переполнение мантиссы и результат операции неправильный, и значение О, если не было переполнения и ответ правильный.