Попов И.И., Матвеев А.А., Максимов Н.В. Архитектура электронно-вычислительных машин и систем (2004) (1186255), страница 91
Текст из файла (страница 91)
"Поймать"такое искажение суммы можно только последующим анализом флагаCF.Искажение результата происходит и при вычитание из меньшегочисла большего. И здесь не фиксируется ошибка, однако первомучислу дается "заем единицы" (в случае байтов это число увеличиваетсяна 256, для слов - на 216), после чего и производится вычитание.Например, вычитание байтов 2 и 3 сводится к вычитанию чисел256+2=258 и 3, в результате чего получается неправильная разность255 (а не -1).
Для того чтобы можно было обнаружить такую ситуацию,флаг переноса CF переключается на 1 (если «заема» не было, в CFзаписывается 0).Сложение и вычитание целых чисел со знаком производится потем же алгоритмам, что и для чисел без знака (в этом одно из достоинствдополнительного кода):числа со знаком рассматриваются каксоответствующие числа без знака, производится операция над этимибеззнаковыми числами и полученный результат интерпретируется какчисло со знаком. Например,сложение байтовых чисел 1 и -2происходит так: берутся их дополнительные коды 1 и (256-2)=254,вычисляется сумма этих величин 1+254=255 и она трактуется как числосо знаком -1 (255=256-1).Если при таком сложении возникла единица переноса, то она, какобычно, отбрасывается, а флаг CF получает значение 1.
Однако в464данном случае это отсечение не представляет интерес - результатоперации будет правильным, например: 3+(-2) => 3+254(mod 256) =257(mod 256) = 1. Зато здесь возможна иная неприятность: модульсуммы (ее мантисса) может превзойти допустимую границу и "залезть"в знаковый разряд, испортив его. Например, при сложении байтовыхчисел 127 и 2 получается величина 129 = 100001001b, представляющаядополнительный код числа -127 (=256-129).Хотя результат здесь получился и неправильным, процессор нефиксирует ошибку, но зато заносит 1 в флаг переполнения OF (если"переполнения мантиссы" не было, в OF записывается 0).
Анализируязатем этот флаг, можно "поймать" такую ошибку.Таким образом, сложение (вычитание) знаковых и чисел без знакапроизводится по одному и тому же алгоритму. При этом I80Х86 не"знает", какие числа (со знаком или без) он складывает; в любом случаеон складывает их как числа без знака и в любом случае формируетфлаги CF и OF. А вот как интерпретировать слагаемые и сумму, накакой из этих флагов обращать внимание - это личное дело авторапрограммы.Что касается умножения и деления знаковых и чисел без знака, тоони выполняются по разным алгоритмам, разными машиннымикомандами. Однако и у этих операций есть ряд особенностей. Приумножении байтов (слов) первый сомножитель обязан находиться врегистре AL (AX), результатом же умножения является слово (двойноеслово), которое заносится в регистр AX (регистры DX и AX).
Тем самымпри умножении сохраняются все цифры произведения. При делениибайтов (слов) первый операнд (делимое) должен быть словом (двойнымсловом) и обязан находиться в регистре AX (регистрах DX и AX).Результатом деления являются две величины размером в байт (слово) неполное частное (div) и остаток от деления (mod); неполное частноезаписывается в регистр AL (AX), а остаток - в регистр AH (DX).Представление символов и строк. На символ отводится один байтпамяти, в который записывается код символа - целое от 0 до 255. ВI80Х86 используется система кодировки ASCII (American Standard Codefor Information Interchange).
Она, естественно, не содержит кодоврусских букв, поэтому в нашей стране применяется некоторый вариантэтой системы с русскими буквами(обычно это альтернативнаякодировка ГОСТа).Некоторые особенности этих систем кодировки:— -код пробела меньше кода любой буквы, цифры и вообще любогографически представимого символа;— коды цифр упорядочены по величине цифр и не содержатпропусков, т.е. из неравенства код('0')<=код(c)<=код('9') следует,что c - цифра;465— коды больших латинских букв упорядочены согласно алфавиту и несодержат пропусков; аналогично с малыми латинскими буквами;— (в альтернативной кодировке ГОСТа) коды русских букв (какбольших, так и малых) упорядочены согласно алфавиту, но междуними есть коды других символов.Строка (последовательность символов) размещается в соседнихбайтах памяти (в неперевернутом виде): код первого символа строкизаписывается в первом байте, код второго символа - во втором байте ит.п.
Адресом строки считается адрес ее первого байта.В I80Х86 строкой считается также и последовательность слов(обычно это последовательность целых чисел). Элементы таких строкрасполагаются в последовательных ячейках памяти, но каждый элементпредставлен в "перевернутом" виде.Представление адресов. Адрес - это порядковый номер ячейкипамяти, т.е.
неотрицательное целое число, поэтому в общем случаеадреса представляются так же, как и числа без знака. Однако в I80Х86есть ряд особенностей в представлении адресов.Дело в том, что в I80Х86 термином "адрес" обозначают разныевещи. Часто под адресом понимается 16-битовое смещение (offset) адрес ячейки, отсчитанный от начала сегмента (области) памяти,которому принадлежит эта ячейка.
В этом случае под адрес отводитсяслово памяти, причем адрес записывается в "перевернутом" виде (как ичисла-слова вообще).В другом случае под "адресом" понимается 20-битовый абсолютныйадрес некоторой ячейки памяти. В силу ряда причин в I80Х86 такойадрес задается не как 20-битовое число, а как пара "сегмент:смещение",где "сегмент" (segment) - это первые 16 битов начального адресасегмента памяти, которому принадлежит ячейка, а "смещение" (offset) 16-битовый адрес этой ячейки, отсчитанный от начала данного466сегмента памяти (величина 16*сегмент+смещение дает абсолютныйадрес ячейки).Такая пара записывается в виде двойного слова, причем (как и длячисел) в "перевернутом" виде: в первом слове размещается смещение, аво втором - сегмент, причем каждое из этих слов в свою очередьпредставлено в "перевернутом" виде.
Например, пара 1234h:5678h будетзаписана так:78563412смещениесегментДирективы определения данных. Для того чтобы в программе наMASM зарезервировать ячейки памяти под константы и переменные,необходимо воспользоваться директивами определения данных - сназваниями DB (описывает данные размером в байт), DW (размером вслово) и DD (размером в двойное слово). (Директивы, или командыассемблеру, - это предложения программы, которыми ее автор сообщаеткакую-то информацию ассемблеру или просит что-то сделатьдополнительно, помимо перевода символьных команд на машинныйязык.)В простейшем случае в директиве DB, DW или DD описываетсяодна константа, которой дается имя для последующих ссылок на нее.По этой директиве ассемблер формирует машинное представлениеконстанты (в частности, если надо, "переворачивает" ее) и записывает вочередную ячейку памяти.
Адрес этой ячейки становится значениемимени: все вхождения имени в программу ассемблер будет заменять наэтот адрес.Имена, указанные в директивах DB, DW и DD, называютсяименами переменных (в отличие от меток - имен команд).В MASM числа записываются в нормальном (неперевернутом)виде в cистемах счисления с основанием 10, 16, 8 или 2. Десятичныечисла записываются как обычно, за шестнадцатеричным числомставится буква h (если число начинается с "цифры" A, B, ., F, то вначалеобязателен 0),за восьмеричным числом - буква q или o, за двоичнымчислом - буква b.Примеры:A DB 162 ;описать константу-байт 162 и дать ей имя AB DB 0A2h ;такая же константа, но с именем BС DW -1 ;константа-слово -1 с именем СD DW 0FFFFh ;такая же константа-слово, но с именем DE DD -1;-1 как двойное словоКонстанты-символы описываются в директиве DBдвояко:указывается либо код символа (целое от 0 до 255), либо сам символ вкавычках (одинарных или двойных); в последнем случае ассемблер сам467заменитсимвол на его код.
Например, следующие директивыэквивалентны (2A - код звездочки в ASCII):CH DB 02AhCH DB '*'CH DB "*"Константы-адреса, как правило, задаются именами. Так, подирективеADR DW CHбудет отведено слово памяти, которому дается имя ADR и в котороезапишется адрес (смещение), соответствующий имени CH.
Если такоеже имя описать в директиве DD, то ассемблер автоматически добавит ксмещению имени его сегмент и запишет смещение в первую половинудвойного слова, а сегмент - во вторую половину.По любой из директивDB, DW и DDможно описатьпеременную, т.е. отвести ячейку, не дав ей начального значения. В этомслучае в правой части директивы указывается вопросительный знак:F DW ? ;отвести слово и дать ему имя F, ничего в этот байт незаписывать.В одной директиве можно описать сразу несколько констант и/илипеременных одного и того же размера, для чего их надо перечислитьчерез запятую. Они размещаются в соседних ячейках памяти.