Главная Случайная страница


Полезное:

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


Категории:

АрхитектураАстрономияБиологияГеографияГеологияИнформатикаИскусствоИсторияКулинарияКультураМаркетингМатематикаМедицинаМенеджментОхрана трудаПравоПроизводствоПсихологияРелигияСоциологияСпортТехникаФизикаФилософияХимияЭкологияЭкономикаЭлектроника






Архитектура уровня команд





 

Рассуждая об архитектуре любого процессора, всегда следует понимать разницу между его внутренним устройством как таковым (регистры, АЛУ, блок управления, внутренняя шина, конвейер и т. д.) и архитектурой уровня команд ассемблера. Строго говоря, термин "архитектура x86" относится как раз к уровню команд Ассемблера. Это значит, что программист, используя ассемблер, будет всегда иметь дело с одной и той же абстрактной архитектурой x86 вне зависимости от того, какой процессор установлен на конкретной машине. Сразу оговорюсь: каждая модель процессора обладает собственным, уникальным расширением базового набора команд. Например, во многом отличие камней Intel от камней AMD заключается в наборе команд для мультимедиа.

Чипы Intel Pentium поддерживают комплекс мультимедиаинструкций SSE и SSE2 (с базовым набором команд MMX). А AMD Athlon и Duron не поддерживают наборы SSE и SSE2, зато имеют собственный набор аналогичных инструкций - 3DNow! и Enhanced 3DNow!. В этом смысле их архитектуры существенно различаются на уровне команд. Но в основе набора команд у процессоров Intel, AMD, Cyrix, да и у любого другого процессора архитектуры x86 лежат инструкции самого первого процессора семейства - Intel 8086. Именно поэтому на любом процессоре x86 может быть запущена программа, написанная для Intel 8086.

Теория - это хорошо, но давайте на практике пощупаем эти команды x86. Заставим процессор по нашей прихоти выполнить что-нибудь эдакое. Для чего вооружимся одним из лучших хакерских инструментов - программой debug.exe, или дебагером. Причем не просто вооружимся ей, а сварганим на коленке самую настоящую COM-утилиту. Мы сваяем работоспособный COM-файл, имеющий размерность всего 15 байт. Да, это не описка, сейчас мы изготовим работающую программу размерностью всего 15 байт!

Итак, нажмите кнопку "Пуск" на панели главного меню, выберите режим "Выполнить" и в окне "Запуск программы" введите debug, после чего, нажав, Enter, запустите дебагер. Не пугайтесь, оно так и выглядит - просто черное окно с мигающим курсором. Чтобы вам было не так неуютно, введите: R <ENTER>. На экране появится нечто вроде этого:

AX=0000 BX=0000 CX=0000 DX=
0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=149D ES=149D SS=149D CS=
149D IP=0100 NV UP EI PL NZ NA PO NC
149D:0100 BFBFBF MOV DI,BFBF.

Дебагер показал состояние регистров процессора. Значение сегментных регистров на моей машине равняется 149D, на вашей может быть другое значение, но это никакой роли не играет. Теперь введите A <ENTER> и начинайте набор нижеследующих команд (слева автоматически будет отображаться комбинация вида 149D:0100 - не обращайте внимания, просто вводите команды): MOV AH,02 <ENTER> MOV DL,41 <ENTER> MOV CX,001A <ENTER> INT 21 <ENTER> INC DL <ENTER> LOOP 0107 <ENTER> INT 20 <ENTER><ENTER>. В итоге на экране вы увидите следующее:

149D:0100 MOV AH,02
149D:0102 MOV DL,41
149D:0104 MOV CX,001A
149D:0107 INT 21
149D:0109 INC DL
149D:010B LOOP 0107
149D:010D INT 20
149D:010F.

Это, доложу вам, самая настоящая законченная программа. Что она делает? Введите G <ENTER> и узнаете. На экране появятся две строки:
ABCDEFGHIJKLMNOPQRSTUVWXYZ

Нормальное завершение работы программы. Программа просто выводит латинский алфавит (вторая строка - сообщение системы). Ну а вы чего хотели от программы размерностью в 15 байт? Откуда я знаю, что ее размерность составляет 15 байт? А вот откуда. Первая строка, с которой вы начинали ввод, выглядела вот так: 149D:0100, а последняя, пустая, вот так: 149D:010F. Или, отбрасывая номер сегмента (149D), получаем следующее: первая команда началась с адреса 0100, а последняя закончилась перед адресом 010F. Если вычесть из шестнадцатеричного числа 010F число 0100, получим шестнадцатеричное число F, или десятичное 15. Это и есть искомый размер программы.

Теперь нужно сохранить программу на диске. Сперва дадим ей имя. Введите N ALFABET.COM <ENTER>. Укажем дебагеру размерность сохраняемой программы (он данного значения пока не знает). Для этого ее размер мы занесем в регистр CX (счетчик) командой R. Введите R CX <ENTER>. На экране появится текущее состояние регистра (CX 0000), а на следующей строке - промпт в виде двоеточия. Введите F <ENTER> (напомню, F - это размерность программы в шестнадцатеричном виде, поскольку десятичных чисел дебагер не понимает). Теперь командой W <ENTER> осуществим запись на диск. Дебагер подтвердит, что правильно вас понял. Запись: 0000F байт. Все, можно выйти из дебагера: Q <ENTER>.

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

Для изготовления этой утилиты мы использовали программные прерывания (команда INT), представляющие собой специальные системные подпрограммы, которые программист может вызвать, когда ему угодно. Прерывание INT 20 - это стандартное средство завершения любой программы. Поэтому мы его поставили в самом конце. Гораздо интереснее прерывание INT 21. Это обращение к целой куче системных функций. Чтобы указать, какая именно функция нам нужна, мы занесли ее номер (02) в регистр AH посредством самой первой команды нашей программы (заметьте, нам понадобился не AX, не AL, а именно AH). Функция 02 прерывания 21h выводит на экран символ, ASCII-код которого хранится в регистре DL. Так что вторая команда программы как раз и заносит в регистр DL ASCII-код литеры A (41 в шестнадцатеричном представлении).

Но нам нужно вывести не один символ, а все символы латинского алфавита, то есть целых 26 литер. Как же нам быть? Можно, конечно, 26 раз продублировать команду MOV с новым кодом и вызовом прерывания INT 21. Но мы поступили хитрее - организовали цикл. Для этого занесли количество повторов цикла в регистр-счетчик CX (шестнадцатеричное 1A - это десятичное 26). И в команде циклического перехода LOOP явно указали смещение команды INT 21 (0107), на которую нужно переходить до тех пор, пока значение регистра CX не станет равным нулю (оно автоматически уменьшается на единицу при каждом выполнении команды LOOP).

Наконец, последний штрих: между вызовом прерывания INT 21 и командой LOOP мы поставили команду INC DL, увеличивающую значение регистра DL на единицу. Таким образом, при каждом последующем проходе функция 02 прерывания 21h выводит новый символ, ASCII-код которого на единицу больше, чем код предыдущего выведенного символа. После того как будет выведен последний символ - Z, значение регистра CX станет равным нулю и управление перейдет на команду INT 20. То есть программа благополучно завершит свою работу.

Вот и все, что можно рассказать о процессоре Intel 8086 и его работе в рамках одной статьи. Так все работало 15 лет назад, но, в принципе, точно так же работает и сегодня. Ну, разве чуть побыстрее. Впрочем, кое-какие отличия имеются. Но об этом мы поговорим в следующих статьях.

 

Date: 2015-10-18; view: 268; Нарушение авторских прав; Помощь в написании работы --> СЮДА...



mydocx.ru - 2015-2024 year. (0.006 sec.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав - Пожаловаться на публикацию