ПЕРЕЛІК ДИСЦИПЛІН:
  • Адміністративне право
  • Арбітражний процес
  • Архітектура
  • Астрологія
  • Астрономія
  • Банківська справа
  • Безпека життєдіяльності
  • Біографії
  • Біологія
  • Біологія і хімія
  • Ботаніка та сільське гос-во
  • Бухгалтерський облік і аудит
  • Валютні відносини
  • Ветеринарія
  • Військова кафедра
  • Географія
  • Геодезія
  • Геологія
  • Етика
  • Держава і право
  • Цивільне право і процес
  • Діловодство
  • Гроші та кредит
  • Природничі науки
  • Журналістика
  • Екологія
  • Видавнича справа та поліграфія
  • Інвестиції
  • Іноземна мова
  • Інформатика
  • Інформатика, програмування
  • Юрист по наследству
  • Історичні особистості
  • Історія
  • Історія техніки
  • Кибернетика
  • Комунікації і зв'язок
  • Комп'ютерні науки
  • Косметологія
  • Короткий зміст творів
  • Криміналістика
  • Кримінологія
  • Криптология
  • Кулінарія
  • Культура і мистецтво
  • Культурологія
  • Російська література
  • Література і російська мова
  • Логіка
  • Логістика
  • Маркетинг
  • Математика
  • Медицина, здоров'я
  • Медичні науки
  • Міжнародне публічне право
  • Міжнародне приватне право
  • Міжнародні відносини
  • Менеджмент
  • Металургія
  • Москвоведение
  • Мовознавство
  • Музика
  • Муніципальне право
  • Податки, оподаткування
  •  
    Бесплатные рефераты
     

     

     

     

     

     

         
     
    IBM PC
         

     

    Інформатика
    МОВА МАКРОАССЕМБЛЕРА IBM PC (Довідковий посібник) Укладач: В. Н. Пильщиків (МДУ, ВМК) (січень 1992 р.) У посібнику розглядається мова макроассеблера для персональних ЕОМ типу IBM PC (мова MASM, версія 4.0). Посібник складається з 4 розділів. У главі 1 розглянуто особливості персональні комп'ютерів типу IBM PC і наведені початкові відомості про мову MASM. У главі 2 описується система команд цих комп'ютерів. Глава 3 присвячена присвячена власне мови MASM. У розділі 4 наведено приклади фрагментів програм та повних програм на MASM для вирішення раз-особистих завдань. У посібнику не розглядаються питання, пов'язані з обробкою дво-ічно-десяткових чисел і роботою арифметичного співпроцесора 8087 або 80287. Під терміном "ПК" в посібнику розуміється персональний комп'ютер типу IBM PC c мікропроцесором 8088/8086, 80186 або 80286. Розділ 1. ОСОБЛИВОСТІ ПК. ВСТУП У MASM. 1.1. ОПЕРАТИВНА ПАМ'ЯТЬ. РЕГІСТРИ. 1.1.1 Оперативна пам'ять Об'єм оперативної пам'яті ПК - 2 ^ 20 байт (1 Мб). Байти нумеруються починаючи з 0, номер байта називається його адресою. Для посилань на байти пам'яті використовуються 20-розрядні адреси: від 00000 до FFFFF (в 16-річ-ний системі). Байт містить 8 розрядів (бітів), кожен з яких може прини-мати значення 1 або 0. Розряди нумеруються справа наліво від 0 до 7: 7 6 5 4 3 2 1 0 Байт - це найменша адресуемая комірка пам'яті. У ПК використовуються і більш великі осередки - слова і подвійні слова. Слово - це два сусід-них байтів, розмір слова - 16 бітів (вони нумеруються справа наліво від 0 до 15). Адресою слова вважається адреса її першого байта (з меншим ад-ресом); ця адреса може бути парним і непарним. Подвійне слово - це будь-які чотири сусідніх байти (два сусідніх слова), розмір такої комірки - 32 біта; адресою подвійного слова вважається адреса її першого байта. Байти використовуються для зберігання невеликих цілих чисел і символів, слова - для зберігання цілих чисел і адрес, подвійні слова - для зберігати-ня "довгих" цілих чисел і т.зв. адресних пар (сегмент: зсув). 1.1.2 Регістри Крім комірок оперативної пам'яті для зберігання даних (правда, крат-ковременного) можна використовувати і регістри - комірки, що входять в сос-тав процесора і доступні з машинної програми. Доступ до регістрів здійснюється значно швидше, ніж до комірок пам'яті, тому ис-користування регістрів помітно зменшує час виконання програм. Всі регістри мають розмір слова (16 бітів), за кожним з них зак-реплено певне ім'я (AX, SP і т.п.). За призначенням і способом використання регістри можна розбити на наступні групи: - регістри загального призначення (AX, BX, CX, DX, BP, SI, DI, SP); - сегментні регістри (CS, DS, SS, ES); - лічильник команд (IP); - регістр прапорів (Flags). (Розшифровка цих назв: A - accumulator, акумулятор; B - base, база; C - counter, лічильник; D - data, дані; BP - base pointer, ука-затель бази; SI - source index, індекс джерела; DI - destination index, індекс приймача; SP - stack pointer, покажчик стека; CS - code segment, сегмент команд; DS - data segment, сегмент даних; SS - stack segment, сегмент стека; ES - extra segment, додатковий сег-мент; IP - instruction pointer, лічильник команд.) Регістри загального призначення можна використовувати в усіх аріфметічес-ких і логічних командах. У той же час кожен з них має визна-ленну спеціалізацію (деякі команди "працюють" тільки з певними регістрами). Наприклад, команди множення і ділення вимагають, щоб один з операндів знаходився в регістрі AX або в регістрах AX і DX (залежно від розміру операнда), а команди управління циклом викорис-зуются регістр CX в якості лічильника циклу. Регістри BX і BP дуже час-то використовуються як базові регістри, а SI і DI - як індексні. Ре-гістр SP зазвичай вказує на вершину стека, апаратно підтримуваного в ПК. Регістри AX, BX, CX і DX конструктивно влаштовані так, що можливий незалежний доступ до їх старшої та молодшої половин; можна сказати, що кожен з цих регістрів складається з двох байтових регістрів, обо-значущих AH, AL, BH і т.д. (H - high, старший; L - low, молодший): ----------- ----------- ----------- --- -------- AX | AH | AL | BX | BH | BL | CX | CH | CL | DX | DH | DL | ----------- ------- ---- ----------- ----------- 15 8 7 0 Таким чином, з кожним із цих регістрів можна працювати як з єдиним цілим, а можна працювати і з його "половинками". Наприклад, можна запи-описати слово в AX, а потім вважати тільки частину слова з регістру AH або замінити тільки частину в регістрі AL і т.д. Такий пристрій регістрів дозволяє використовувати їх для роботи і з числами, і з символами. Всі інші регістри не діляться на "половинки", тому вважати чи записати їх вміст (16 бітів) можна тільки цілком. Сегментні регістри CS, DS, SS і ES не можуть бути операндами ника-ких команд, крім команд пересилання і стекові команд. Ці регістри ис-користуються тільки для сегментації адрес (див. 1.4). Лічильник команд IP завжди містить адреса (зміщення від початку про-грами) тієї команди, яка повинна бути виконана наступної (початок програми зберігається в регістрі CS). Вміст регістра IP можна вимірюв-нить тільки командами переходу. 1.1.3 Прапори І, нарешті, в ПК є особливий регістр прапорів. Прапор - це біт, що приймає значення 1 ( "прапор встановлений"), якщо виконано деякий умова, і значення 0 ( "прапор скинутий") в іншому випадку. У ПК ис-користується 9 прапорів, кожному з них присвоєно певне ім'я (ZF, CF і т.д.). Всі вони зібрані в регістрі прапорів (кожен прапор - це один з розрядів регістра, частина його розрядів не використовується): --------------------------- ---------------------- Flags | x | x | x | x | OF | DF | IF | TF | SF | ZF | x | AF | x | PF | x | CF | -------------------------------------------- ----- 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 Деякі прапори прийнято називати прапорами умов; вони автоматичні-ки змінюються при виконанні команд і фіксують ті чи інші властивості їх результату (наприклад, дорівнює чи він нулю). Інші прапори називаються ФЛА-гами станів; вони змінюються з програми і впливають на по-дальшої поведінка процесора (наприклад, блокують переривання). Прапори умов: CF (carry flag) - прапорець перенесення. Приймає значення 1, якщо при складанні цілих чисел з'явилася одиниця переносу, не "влазити" в раз-рядну сітку, або якщо при віднімання чисел без знака перший з них б-ло менше другий. У командах зрушення в CF заноситься біт, що вийшов за розрядну сітку. CF фіксує також особливості команди множення. OF (overflow flag) - прапорець переповнення. Встановлюється в 1, якщо при складання або віднімання цілих чисел зі знаком вийшов результат, по модулю перевершує допустиму величину (сталося переповнення мантиси і вона "залізла" в знаковий розряд). ZF (zero flag) - прапор нуля. Встановлюється в 1, якщо результат команди виявився рівним 0. SF (sign flag) - прапор знаку. Встановлюється в 1, якщо в операції над знаковими числами вийшов негативний результат. PF (parity flag) - прапорець парності. Дорівнює 1, якщо результат чергу-ної команди містить парна кількість двійкових одиниць. Враховується звичайно тільки при операціях вводу-виводу. AF (auxiliary carry flag) - прапорець додаткового переносу. Фікс-рілої особливості виконання операцій над двійковій-десятковими числами. Прапори станів: DF (direction flag) - прапорець напрямку. Встановлює напрямок перегляду рядків у строкових командах: при DF = 0 рядки проглядаються "вперед" (від початку до кінця), при DF = 1 - у зворотному напрямку. IF (interrupt flag) - прапорець переривань. При IF = 0 процесор переста-і реагувати на що надходять до нього переривання, при IF = 1 блокування переривань знімається. TF (trap flag) - прапорець трасування. При TF = 1 після виконання каж-дой команди процесор робить переривання (з номером 1), чим можна вос-користуватися при налагодженні програми для її трасування. 1.2. ПРЕДСТАВЛЕННЯ ДАНИХ. Арифметичні операції Тут розглядається машинне подання цілих чисел, рядків і адрес. Представлення двійковій-десяткових чисел, що використовуються достатньо точно рідко, не розглядається. Що стосується дійсних чисел, то в ПК немає команд речової арифметики (операції над цими числами реа-лізуются програмним шляхом або виконуються співпроцесором) і тому немає стандартного подання дійсних чисел. Крім того, розглядає-вають деякі особливості виконання арифметичних операцій. Шістнадцяткові числа записуються з буквою h на кінці, двійкові числа - з буквою b (так прийнято в MASM). 1.2.1 Представлення цілих чисел. У загальному випадку під ціле число можна відвести будь-яке число байтів, проте система команд ПК підтримує тільки числа розміром в байт і слово і частково підтримує числа розміром в подвійне слово. Саме ці формати і будуть розглянуті. У ПК робиться відмінність між цілими числами без знаку (неотріца-них) і зі знаком. Це пояснюється тим, що в осередках одного і то-го ж розміру можна уявити більший діапазон беззнакових чисел, ніж невід'ємних знакових чисел, і якщо відомо заздалегідь, що неко-торая числова величина є невід'ємне, то вигідніше розглядають Ріва її як беззнакові, ніж як знакову. Цілі числа без знака. Ці числа можуть бути представлені у вигляді байта, слова чи подвійного слова - в залежності від їх розміру. У вигляді байти представляються цілі від 0 до 255 (= 2 ^ 8-1), у вигляді слова - цілі від 0 до 65535 (= 2 ^ 16-1), у вигляді подвійного слова - цілі від 0 до 4 294 967 295 ( = 2 ^ 32-1). Числа за-пісиваются в двійковій системі числення, займаючи всі розряди осередки. Наприклад, число 130 записується у вигляді байтів 10000010b (82h). Числа розміром в слово зберігаються в пам'яті в "перевернутому" вигляді: молодшого (праві) 8 бітів числа розміщуються в першому байті слова, а старші 8 бітів - у другому байті (у 16-річної системі: дві праві цифри - в першому байті, два ліві цифри - у другому байті). Наприклад, число 130 (= 0082h) у вигляді слова зберігається в пам'яті так: ----------- | 82 | 00 | ----------- (Зазначимо, однак, що в регістрах числа зберігаються в нормальному вигляді: ----------- AX | 00 | 82 | ----------- AH AL) "перевернути" подання використовується і при зберіганні в пам'яті цілих чисел розміром в подвійне слово: у першій його байті розміщуються молодші 8 бітів числа, у другому байті - попередні 8 бітів і т.д. На-приклад, число 12345678h зберігається в пам'яті так: --------------------- | 78 | 56 | 34 | 12 | --------- ------------ Іншими словами, в першому слові подвійного слова розміщуються молодші (праві) 16 бітів числа, а в другому слові - старші 16 бітів, причому в кожному з цих двох слів в свою чергу використовується " перевернуте "подання. Таке незвичайне подання чисел пояснюється тим, що в перших моделях ПК за раз можна було вважати з пам'яті тільки один байт і що всі арифметичні операції над багатозначними числами починаються з дій над молодшими цифрами, тому з пам'яті в першу чергу треба зчитувати молодші цифри, якщо відразу не можна вважати всі цифри. З огляду на це, в першу ПК і стали розміщувати молодші цифри числа перед старшими ціфраммі, а заради наступності таке подання чисел зберегли в наступних моделях ПК. Звичайно, "перевернуте" подання незручно для людей, однак при використанні мови асемблера цю незручність не відчувається: в MASM всі числа записуються в нормальному, неперевернутом вигляді (див. ні-же). Цілі числа зі знаком. Ці числа також подаються у вигляді байти, слова та подвійного сло-ва. У вигляді байти записуються числа від -128 до 127, у вигляді слова - числа від -32768 до 32767, а у вигляді подвійного слова - числа від -2147483648 до 2147483647. При цьому числа записуються в додаткових паном коді: невід'ємне число записується так само, як і беззнакові число (тобто в прямому коді), а негативне число-x (x> 0) представля-ється беззнакові числом 2 ^ 8-x (для байтів), 2 ^ 16-x (для слів) або 2 ^ 32-x (для подвійних слів). Наприклад, додатковим кодом числа -6 яв-ний байт FAh (= 256-6), слово FFFAh або подвійне слово FFFFFFFAh. При цьому байт 10000000b (= 80h) трактується як -128, а не як +128 (слово 8000h розуміється як -32678), тому лівий біт додаткового коду завжди грає роль знакового: для невід'ємних чисел він дорівнює 0, для негативних - 1. Знакові числа розміром в слово і подвійне слово записуються в па-мяті в "перевернутому" вигляді (при цьому знаковий біт виявляється в пос-Ледней байті комірки). Але в MASM ці числа, як і беззнакові, записи-вають в нормальній формі. Іноді число-байт необхідно розширити до слова, тобто потрібно полу-чить таке ж за величиною число, але розміром в слово. Існує два способи такого розширення - без знаку і зі знаком. У будь-якому разі ви-Ходна число-байт потрапляє в другій (до "перевертання") байт сло-ва, а от перший байт заповнюється по-різному: при розширенні без знака в нього записуються нульові біти (12h -> 0012h), а при розширення зі знаком в перший байт записуються нулі, якщо число-байт було неотріца-тельно, і записується вісім двійкових одиниць у противному випадку (81h -> FF81h). Іншими словами, при розширенні зі знаком в першому байті слова копіюється знаковий розряд числа-байти. Аналогічно відбувається розширення числа-слова до подвійного слова. 1.2.2 Особливості виконання арифметичних опреацій У ПК є команди додавання і віднімання цілих чисел розміром в слово і байт. Спеціальних команд для додавання і віднімання подвійних слів немає, ці операції реалізуються через команди додавання і віднімання слів. Додавання і віднімання беззнаковаих чисел проводиться за модулем 2 ^ 8 для байтів і 2 ^ 16 для слів. Це означає, що якщо в результаті склалася-ня з'явилася одиниця переносу, не вміщаються в розрядну сітку, то вона відкидається. Наприклад, при складанні байтів 128 і 130 виходить число 258 = 100000010b, тому ліва двійкова одиниця відкидається і залишається число 2 = 10b, яке і оголошується результатом складання. Помилка тут не фіксується, але в прапор переносу CF записується 1 (ес-ли переносу не було, в CF заноситься 0). "Зловити" таке спотворення сум-ми можна тільки подальшим аналізом прапора CF. Спотворення результату відбувається і при віднімання від меншого числа більшого. І тут не фіксується помилка, однак перші числа дається "позика одиниці" (у разі байтів це число збільшується на 256, для слів - на 2 ^ 16), після чого і проводиться віднімання. Наприклад, вичі-таніе байтів 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. Проте в даному випадку це від-розтин не представляє інтерес - результат операції буде правильним, наприклад: 3 + (-2) => 3 +254 (mod 256) = 257 (mod 256) = 1. Зате тут віз-можна інша неприємність: модуль суми (її мантиса) може перевершити допустиму межу і "залізти" в знаковий розряд, зіпсували його. Напри-мер, при складанні байтових чисел 127 і 2 виходить величина 129 = = 100001001b, що представляє додатковий код числа -127 (= 256-129). Хоча результат тут вийшов і неправильним, процесор не фіксує помилку, але зате заносить 1 в прапор переповнення OF (якщо "переповнення мантиси" не було, в OF записується 0). Аналізуючи потім цей прапор, можна "зловити" таку помилку. Таким чином, додавання (віднімання) знакових і беззнакових чисел здійснюється за одним і тим же алгоритмом. При цьому ПК не "знає", які числа (зі знаком чи без) він складає; в будь-якому випадку він скла-дивает їх як беззнакові числа і в будь-якому випадку формує прапори CF і OF. А ось як інтерпретувати складові і суму, на якій з цих прапорів звертати увагу - це особиста справа автора програми. Що стосується множення і ділення знакових і беззнакових чисел, то вони виконуються за різними алгоритмами, різними машинними командами. Од-нако і у цих операцій є ряд особливостей. При збільшенні байтів (слів) перший співмножники зобов'язаний знаходитися в регістрі AL (AX), ре-Результатом же множення є слово (подвійне слово), яке Зано-сітся в регістр AX (регістри DX і AX). Тим самим при збільшенні збереженні-няются всі цифри твори. При розподілі байтів (слів) перший опе-ранд (ділене) повинен бути словом (подвійним словом) і зобов'язаний знаходитися в регістрі AX (регістрах DX і AX). Результатом поділу є дві величини розміром в байт (слово) - неповна приватне (div) і залишок від ділення (mod); неповне приватне записується в регістр AL (AX), а ос-таток - в регістр AH (DX). 1.2.3 Представлення символів і рядків На символ відводиться один байт пам'яті, в який записується код символу - ціле від 0 до 255. У ПК використовується система кодування ASCII (American Standard Code for Information Interchange). Вона, природний-но, не містить кодів російських букв, тому в нашій країні застосовується деякий варіант цієї системи з російськими літерами (зазвичай це альтер-нативних кодування ГОСТу). Деякі особливості цих систем кодування: - код пробілу меньше коду будь-якої букви, цифри і взагалі будь-якої графи-но представимо символу; - коди цифр впорядковані за величиною цифр і не містять пропусків, тобто з нерівності код ('0 ') +; наприклад, для доступу до байту з числом -5 треба вказати вираз G 1, для доступу до байту з 10h - вираз G 2 і т.д. Якщо у директиві DB перераховані тільки символи, наприклад: S DB 'a','+',' b' тоді цю директиву можна записати коротше, уклавши всі ці символи в одні лапки: S DB 'a + b' І, нарешті, якщо в директиві описується кілька однакових кон-стант (змінних), то можна скористатися конструкцією повторення k DUP (a, b ,..., c) що еквівалентна повтореної k раз послідовності a, b ,..., c. Наприклад, директиви V1 DB 0,0,0,0,0 V2 DW ?,?,?,?,?,?,?,?,?,' a ', 1,2,1,2,1,2, 1,2 можна записати більш коротко таким чином: V1 DB 5 DUP (0) V2 DW 9 DUP (?), 'a', 4 DUP (1,2) 1.3. ПОДАННЯ КОМАНД. Модифікація адреси. 1.3.1 Структура команд. Виконавчі адреси Машинні команди ПК займають від 1 до 6 байтів. Код операції (КОП) займає один або два перших байтів команди. У ПК настільки багато різних операцій, що для них не вистачає 256 различ-них КОПів, які можна представити в одному байті. Тому деякі операції об'єднуються в групи і їм дається один і той же КОП, у дру-ром ж байті цей КОП уточнюється. Крім того, у другому байті вказуючи-ются типи і спосіб адресації операндів. Решта байти команди укази-вають на операнди. Команди можуть мати від 0 до 3 операндів, у більшості команд - один або два операнда. Розмір операндів - байт або слово (рідко - подвійне слово). Операнд має бути зазначено у самій команді (це т.зв. безпосередній операнд), або може перебувати в одному з регістрів ПК і тоді в команді вказується цей регістр, або може перебувати в комірці пам'яті і тоді в команді той чи інший спосіб вказується ад - рес цього осередку. Деякі команди вимагають, щоб операнд знаходився у фіксованому місці (наприклад, в регістрі AX), тоді операнд явно не вказується в команді. Результат виконання команди поміщається в ре-гістр або комірку пам'яті, з якого (яку), як правило, береться перший операнд. Наприклад, більшість команд з двома операндами реалі-зуются дію op1: = op1? op2 де op1 - регістр або комірка, а op2 - безпосередній операнд, ре-гістр або осередок. Адреса операнда дозволено модифіковані з одного або двох РЕГИСТ-рам. У першому випадку як регістра-модифікатора дозволено ис-пользовать регістр BX, BP, SI або DI (і ніякий інший). У другому слу-чай один з модифікаторів зобов'язаний бути регістром BX або BP, а інший - регістром SI або DI; одночасна модифікація з BX і BP або SI і DI неприпустима. Регістри BX і BP зазвичай використовуються для зберігання бази (початкової адреси) деякої ділянки пам'яті (скажімо, масиву) і по-тому називаються базовими регістрами, а регістри SI і DI часто містять індекси елементів масиву і тому називаються індексними регістрами. Однак такий розподіл ролей необов'язково, і, наприклад, в SI мо-жет знаходитися база масиву, а в BX - індекс елемента масиву. У MASM адреса в командах записуються у вигляді однієї з наступних конструкції: A, A [M] або A [M1] [M2], де A - адреса, M - регістр BX, BP, SI або DI, M1 - регістр BX або BP , а M2 - регістр SI або DI. Під второрм і третьому варіанті A може відсутність про-ствовать, в цьому випадку вважається, що A = 0. При виконанні команди процесор насамперед обчислює т.зв. ис-полнітельний (ефективний) адреса - як суму адреси, заданого в ко-команді, і поточних значень зазначених регістрів-модифікаторів, причому всі ці величини розглядаються як невід'ємні і підсумовування ведеться по модулю 2 ^ 16 ([r] означає вміст регістра r) : A: Aісп = AA [M]: Aісп = A + [M] (mod 2 ^ 16) A [M1] [M2]: Aісп = A + [M1] + [M2] (mod 2 ^ 16) Отриманий таким чином 16 -розрядний адреса визначає т.зв. зміщений-гом - адреса, відраховувати від початку деякого сегмента (області) пам'я-ти. Перед зверненням до пам'яті процесор ще додає до зсуву на-чільного адресу цього сегменту (він зберігається в деякому сегментному регі-стре), в результаті чого виходить остаточний 20-розрядний ад-рес, за яким і відбувається реальне звернення до пам'яті (див. 1.4 ). 1.3.2 Формати команд У ПК формати машинних команд досить різноманітні. Для прикладу наведемо лише основні формати команд з двома операндами. 1) Формат "регістр-регістр" (2байта): ------------- ---------------- | КОП | d | w | | 11 | reg1 | reg2 | ------------- ---------------- 7 2 1 0 7 6 5 3 2 0 Команди цього формату описують зазвичай дію reg1: = reg1? reg2 або reg2: = reg2? reg1. Поле КОП першого байта вказує на операцію (?), Ко-торую треба виконати. Біт w визначає розмір операндів, а біт d ука-показують, в якій із регістрів записується результат: w = 1 - слова d = 1 - reg1: = reg1? Reg2 = 0 - байти = 0 - reg2: = reg2? Reg1 У другому байті два лівих біта фіксовані (для даного формату), а трехбітовие поля reg1 і reg2 вказують на регістри, що беруть участь в опе-рації, згідно наступної таблиці: reg w = 1 w = 0 reg w = 1 w = 0 ----- ------------ ----------------- 000 AX AL 100 SP AH 001 CX CL 101 BP CH 010 DX DL 110 SI DH 011 BX BL 111 DI BH 2) Формат "регістр-пам'ять" (2-4 байти): ------------- ------------- ------ ------------- | КОП | d | w | | mod | reg | mem | | адреса (0-2 байти) | ------------- -- ------------ ------------------- Ці команди описують операції reg: = reg? mem або mem: = mem? reg. Біт w першого байта визначає розмір операндів (див. вище), а біт d вказуючи-і, куди записується результат: в регістр (d = 1) або в комірку пам'яті (d = 0). Трехбітовое поле reg другому байти вказує операнд-регістр (див. вище), двухбітовое поле mod визначає, скільки байтів в команді займає операнд-адреса (00 - 0 байтів, 01 - 1 байт, 10 - 2 байти), а трехбітовое поле mem вказує спосіб модифікації цієї адреси. В сле-дме таблиці вказані правила обчислення виконавчого адреса в за-лежно від значень полів mod і mem (a8 - адреса розміром в байт, a16 - адреса розміром в слово): mem mod | 00 01 10 -------- ----------------------------------------------- 000 | [ BX] + [SI] [BX] + [SI] + a8 [BX] + [SI] + a16 001 | [BX] + [DI] [BX] + [DI] + a8 [BX] + [DI] + a16 010 | [BP] + [SI] [BP] + [SI] + a8 [BP] + [SI] + a16 011 | [BP] + [DI] [BP] + [DI] + a8 [BP] + [DI] + a16 100 | [SI] [SI] + a8 [SI] + a16 101 | [DI] [DI] + a8 [DI] + a16 110 | a16 [BP] + a8 [BP] + a16 111 | [BX] [BX] + a8 [BX] + a16 Зауваження. Якщо в команді не задано адресу, то він вважається нульовим. Якщо адреса задано у вигляді байт (a8), то він автоматично розширюється зі знаком до слова (a16). Випадок mod = 00 і mem = 110 вказує на відсутність регістрів-модифікаторів, при цьому адреса должет мати розмір слова (ад-РЕКН вираз [BP] асемблер транслює в mod = 01 і mem = 110 при a8 = 0). Випадок mod = 11 відповідає формату "регістр-регістр". 3) Формат "регістр-безпосередній операнд" (3-4 байти): ----------- ------------- ---------- ---------------- | КОП | s | w | | 11 | КОП "| reg | | непосред.операнд (1-2 б) | -------- --- ------------- -------------------------- Команди цього формату описують операції reg: = reg? immed (immed - не-посередній операнд). Біт w вказує на розмір операндів, а поле reg - на регістр-операнд (див. вище). Поле КОП в першому байті визначаються-і лише клас операції (наприклад, клас додавання) , уточнює ж опера-цію поле КОП "з другого байта. Безпосередній операнд може зани-мати 1 або 2 байти - залежно від значення біта w, при цьому опе-ранд-слово записується в команді в "перевернутому" вигляді. Задля економії пам'яті в ПК передбачений випадок, коли в операції над словами Непос-редственний операнд може бути заданий байтом (на цей випадок вказує 1 в бите s при w = 1), і тоді перед виконанням операції байт автомати-но розширюється (зі знаком) до слова. 4) Формат "пам'ять-безпосередній операнд" (3-6 байт): ----------- -------------- --------- ----- ------------------ | КОП | s | w | | mod | КОП "| mem | | адреса (0-2б) | | непоср.оп (1-2б) | ----------- -------------- -------------- ----- ------------- Команди цього формату описують операції типу mem: = mem? immed. Сенс всіх полів - той же, що і в попередніх форматах. Крім розглянутих в ПК використовуються й інші формати команди з двома операндами; так, передбачений спеціальний формат для команд, один з операндів яких фіксований (зазвичай це регістр AX). Мають свої формати і команди з іншим числом операндів. 1.3.3 Запис команд в MASM Зі сказаного ясно, що одна й та сама операція в залежно від ти-пов операдов записується у вигляді різних машинних команд: наприклад, у ПК є 28 команд пересилання байтів і слів. У той же час в MASM всі ці "родинні" команди записуються однаково: наприклад, всі команди пересилання мають одну і ту ж символьну форму запису: MOV op1, op2 (op1: = op2) Аналізуючи типи операндів, асемблер сам вибирає потрібну машинну команду. У загальному випадку команди записуються в MASM наступним чином: мітка: мнемокод операнди; коментар Мітка з двокрапкою, а також крапку з комою і коментар можуть відсутність про-ствовать. Мітка грає роль імені команди, її можна використовувати в ко-Манда переходу на цю задачу. Коментар не впливає на зміст ко-мих фахівців, а лише пояснює її. мнемонічні назви операцій повністю перераховані в розділі 2. Операнд, якщо є, перераховуються через кому. Основні правила запису операндів наступні. Регістри вказуються своїми іменами, наприклад: MOV AX, SI; обидва операнда - регістри Безпосередні операнди задаються константними виразами (їх значеннями є константи-числа), наприклад: MOV BH, 5; 5 - безпосередній операнд MOV DI, SIZE X; SIZE X (число байтів, займаних змін-; ної X) - безпосередній операнд Адреса описуються адресними виразами (наприклад, іменами пере-сних), які можуть бути модифіковані з одного або двох РЕГИСТ-рам ; наприклад, у таких командах перший операнди задають адреса: MOV X, AH MOV X [BX] [DI], 5 MOV [BX], CL Під час запису команд в символьної формі необхідно уважно сле-дить за правильним зазначенням типу (розміру) операндів , щоб не було помилок. Тип звичайно визначається за зовнішнім виглядом одного з них, напри-мер: MOV AH, 5; пересилка байта, тому що AH - байтовий регістр MOV AX, 5; пересилання слова, тому що AX -- 16-бітовий регістр; (операнд 5 може бути байтом і словом, за ним, не можна визначити розмір пересилається величини) MOV [BX], 300; пересилання слова, тому що число 300 не може бути; байтом Якщо за зовнішнім виглядом можна однозначно визначити тип обох опе-рандів, тоді ці типи повинні збігатися, інакше асемблер зафіксує помилку. Приклади: MOV DS, AX; обидва операнда мають розмір слова MOV CX, BH; помилка: регістри CX і BH мають різні розміри MOV DL, 300; помилка : DL - байтовий регістр, а число 300 не; може бути байтом Можливі ситуації, коли за зовнішнім виглядом операндів не можна визна-лити тип жодного з них, як, наприклад, у команді MOV [BX], 5 Тут число 5 може бути і байтом, і словом, а адреса з регістра BX може вказувати і на байт пам'яті, і на слово. У подібних ситуаціях ас-семблер фіксує помилку. Щоб уникнути її, треба уточнити тип одного з операндів за допомогою оператора з назвою PTR: MOV BYTE PTR [BX], 5; пересилка байта MOV WORD PTR [BX], 5; пересилання слова (Оператори - це різновид виразів мови MASM, аналогічні функ-ціям.) Оператор PTR необхідний і в тому випадку, коли треба змінити тип, запропонований імені при його описі. Якщо, наприклад, X описано як ім'я змінної розміром в слово: X DW 999 і якщо треба записати в байтовий регістр AH значення тільки першого байта цього слова, тоді скористатися командою MOV AH, X не можна, тому що її операнди мають різний розмір. Цю команду слід за-писати трохи інакше: MOV AH, BYTE PTR X Тут конструкція BYTE PTR X означає адреса X, але вже розглядається не як адресу слова, а як адреса байта. (Нагадаємо, що з одного і того ж адреси може починатися байт, слово і подвійне слово; оператор PTR уточнює, осередок якого розміру ми маємо на увазі.) І ще одне зауваження. Якщо в символьної команді, що оперує зі словами, вказаний безпосередній операнд розміром в байт, як, напри-мер, в команді MOV AX, 80h то виникає деяка неоднозначність: що буде записано в регістр AX - число 0080h (+128) або 0FF80h (-128)? У подібних ситуаціях Ассем-Блер формує машинну команду, де операнд-байт розширений до слова, причому розширення відбувається зі знаком, якщо операнд був записаний як від'ємне число, і без знака в інших випадках. Наприклад: MOV AX, -128; => MOV AX, 0FF80h (A: =- 128) MOV AX, 128; => MOV AX, 0080h (A: = +128) MOV AX, 80h; => MOV AX, 0080h (A: = +128) 1.4. СЕГМЕНТІРОВНІЕ 1.4.1 Сегменти пам'яті. Сегментні регістри. Перші моделі ПК мали оперативну пам'ять об'ємом 2 ^ 16 байт ( 64Кб) і тому використовували 16-бітові адреси. У подальших моделях пам'ять була збільшена до 2 ^ 20 байт (1Мб = 1000Кб), для чого вже необ-ходимо 20-бітові адреси. Однак у цих ПК заради збереження спадкоємства-ності були збережені 16 -бітові адреси: саме такі адреси зберігаються в регістрах і вказуються в командах, саме такі адреси виходять в результаті модмфікаціі з базових та індексних регістрів. Як же вдається-ся 16-бітовими адресами посилатися на 1Мб пам'яті? Ця проблема вирішується за допомогою сегментації адрес ( неявного базування адрес). У ПК вводиться поняття "сегмент пам'яті". Так на-ни опиняються будь-яку ділянку пам'яті розміром до 64Кб і з початковим адресою, кратним 16. Абсолютний (20-бітовий) адреса A будь-якої комірки пам'яті можна представити як суму 20-бітового початкового адреси (бази) B сегмента, якому належить комірка, і 16-бітового зміщення D - адреси цього осередку, відраховувати від початку сегменту: A = B + D. (Неоднозначність вибо-ра сегмента не відіграє суттєвої ролі, головне - щоб сума B і D давала потрібну адресу.) Адреса B заноситься в деякий регістр S, а в ко-команді, де має бути вказана адреса A, замість нього записується пара з регістра S і зміщення D (в MASM така пара, яка називається адресної па-рій або покажчиком, записується як S: D). Процесор ж влаштований так, що при виконанні команди він перш за все по парі S: D обчислює абсо-лютень адреса A як суму вмісту регістра S і зміщення D і тільки потім звертається до пам'яті за цією адресою A . Ось так, замінюючи в коман-дах абсолютні адреси на адресні пари, і вдається адресувати всю па-м'яти 16-бітовими адресами (зміщеннями). Як регістра S дозволяється використовувати не будь-який регістр, а тільки один з 4 регістрів, званих сегментними: CS, DS, SS і ES. У зв'язку з цим одночасно можна працювати з 4 сегментами пам'яті: початок одного з них завантажується в регістр CS і всі посилання на комірки цього сегмента вказуються у вигляді пар CS: D, початок іншого заноситься в DS і все посилання на його осередку задаються у вигляді пар DS: D і т.д. Якщо одночасним-обелівську треба працювати з великим числом сегментів, тоді потрібно вчасно-обелівську рятувати вміст сегментних регістрів і записувати в них на-чільного адреси п'ятого, шостого і т. д. сегментів. Відзначимо, що використовуються сегменти можуть бути розташовані в пам'яті довільним чином: вони можуть не перетинатися, а можуть перетинатися і навіть збігатися. Які сегменти пам'яті використовувати, в яких сегмент-них регістрах зберігати їх початкові адреси - все це особиста справа автора машинної програми. Як і всі регістри ПК, сегментні регістри мають розмір слова. Тому виникає питання: як вдається розмістити в них 20-бітові на-чільного адреси сегментів пам'яті? Відповідь такий. Оскільки всі ці адреси кратні 16 (див. вище) , то в них молодші 4 біта (остання 16-ковий цифра) завжди нульові, а тому ці біти можна не зберігати явно, а лише мати на увазі. Саме так і робиться: у сегментному регістрі завжди зберігаються тільки перші 16 бітів (перші чотири 16-ковий цифри) на-чільного адреси сегмента (ця величина називається номером сегмента або просто сегментом). При обчисленні ж повної адреси A по парі S: D процесор спочатку приписує справа до вмісту регістра S чотири нульових біта (іншими словами, множить на 16) і лише потім додає зсув D, причому підсумовування ведеться по модулю 2 ^ 20: Aабс = 16 * [S] + D (mod 2 ^ 20) Якщо, наприклад, в регістрі CS зберігається величина 1234h, тоді адресна пара 1234h: 507h визначає абсолютний адреса, рівний 16 * 1234h +507 h = 12340h +507 h = 12847h. 1.4.2 Сегментні регістри за замовчуванням Згідно з описаною схемою сегментації адрес, заміну абсолют-них адрес на адресні пари треба проводити у всіх командах, имею-щих операнд-адресу. Однак розробники ПК придумали спосіб, дозволяю-щий уникнути виписування таких пар у більшості команд. Суть його в тому, що заздалегідь домовляються про те, який сегментний регістр на ка-кой сегмент пам'яті буде вказувати, і що в командах задається тільки зсув: не вказаний явно сегментний регістр автоматично віднов-встановлюються відповідно до цієї домовленості. І тільки при необхідності порушити цю домовленість треба повністю вказувати адресну пару. Що це за домовленість? Вважається, що регістр CS завжди вказує на початок області пам'я-ти, в якій розміщені команди програми (ця область називається сег - ментом команд або сегментом кодів), і тому при посиланнях на клітинки цієї області регістр CS можна не вказувати явно, він мається на увазі за умовчанням. (Відзначимо попутно, що абсолютний адреса чергової команди, що підлягає виконанню, завжди задається парою CS: IP: в лічильнику команд IP завжди знаходиться зміщення цієї команди щодо адреси з регі-стра CS.) Аналогічно передбачається, що регістр DS вказує на сег-мент даних (область пам'яті з константами, змінними та іншими вели-чинами програми), і тому у всіх посиланнях на цей сегмент регістр DS можна явно не вказувати, тому що він мається на увазі за умовчанням. Регістр SS, вважається, вказує на стек - область пам'яті, доступ до якої здійснюється за принципом "останнім записаний - перша з?? Ітан "(див. 1.7), і тому всі посилання на стек, в яких явно не вказано сегментний регістр, за замовчуванням сегментуються за регістром SS. Регістр ES вва-ся вільним, він не прив'язаний ні до якого сегменту пам'яті і його можна використовувати на свій розсуд; найчастіше він застосовується для дос-тупа до даних, які не помістилися або свідомо не були размеще-ни в сегменті даних. З урахуванням такого розподілу ролей сегментних регістрів машинні програми зазвичай будуються так: всі команди програми розміщуються в од-ном сегменті пам'яті, початок якого заноситься в регістр CS, а всі дані розміщуються в іншому сегменті, початок якого заноситься до ре-гістр DS; якщо потрібен стек, то під нього відводиться третій сегмент пам'я-ти, початок якого записується в регістр SS. Після цього практично у всіх командах можна вказувати не повні адресні пари, а лише кош-вання, тому що сегментні регістри в цих парах будуть відновлюватися автоматично. Тут, правда, виникає таке питання: як по зміщенню визначити, на який сегмент пам'яті воно вказує? Точну відповідь наведено нижче (див. 1.4.3), а в загальних рисах він такий: посилання на сегмент команд можуть бути тільки в командах переходу, а посилання практично в усіх інших коман-дах (крім строкових і стекові) - це посилання на сегмент даних. Нап-Рімера, в команді пересилання MOV AX, X ім'я X сприймається як посилання на даний, а тому автоматично вос-особи встановлюється до адресної пари DS: X. У команді ж безумовного пере-ходу за адресою, що знаходиться в регістрі BX, JMP BX абсолютний адреса переходу визначається парою CS: [BX]. Отже, якщо в посиланні на якусь комірку пам'яті не вказаний явно сег-ментний регістр, то цей регістр береться за замовчуванням. Явно ж сегм-тні регістри треба вказувати, тільки якщо за якихось причин регістр за замовчуванням не підходить. Якщо, наприклад, у команді пересилання нам треба послатися на стек (скажімо, треба записати в регістр AH байт стека, по-мічений ім'ям X), тоді нас уже не буде влаштовувати домовленість про те, що за замовчуванням операнд команди MOV сегментується за регістром DS, і тому ми зобов'язані явно вказати інший регістр - у нашому випадку ре-гістр SS, тому що саме він вказує на стек: MOV AH, SS: X Однак такі випадки зустрічаються рідко і тому в командах, як прави-ло, вказуються тільки зміщення. Відзначимо, що в MASM сегментний регістр записується в самій коман-де безпосередньо перед зсувом (ім'ям змінної, міткою тощо), однак на рівні машинної мови ситуація дещо інша. Є 4 спеціальні однобайтові команди, які називаються префіксами заміни сегм-та (що позначаються як CS:, DS:, SS: і ES:). Вони ставляться перед коман-дой, операнд-адресу якої має бути просегментірован за регістром, відмінному від регістра, маємо на увазі за умовчанням. Наприклад, приве-денная вище символічна команда пересилання - це насправді два машинні команди: SS: MOV AH, X 1.4.3 Сегментування, базування та індексування адрес Оскільки сегментування адрес - це різновид модифікації адрес, то в ПК адреса, що указується в команді, в загальному випадку модиф-ціруется по трьох рег
         
     
         
    Реферат Банк
     
    Рефераты
     
    Бесплатные рефераты
     

     

     

     

     

     

     

     
     
     
      Все права защищены. Reff.net.ua - українські реферати ! DMCA.com Protection Status