Системное программирование

Автор: Пользователь скрыл имя, 10 Марта 2013 в 15:44, курс лекций

Описание работы

Один из основных принципов машины фон Неймана — то, что и программы, и данные хранятся в одной и той же памяти. Сохраняемая в памяти программа представляет собой некоторые коды, которые могут рассматриваться как данные. Возможно, с точки зрения программиста программа — активный компонент, она выполняет некоторые действия. Но с точки зрения процессора команды программы — это данные, которые процессор читает и интерпретирует. С другой стороны программа — это данные с точки зрения обслуживающих программ, например, с точки зрения компилятора, который на входе получает одни данные — программу на языке высокого уровня (ЯВУ), а на выходе выдает другие данные — программу в машинных кодах.

Работа содержит 1 файл

Системное программирование 15 лекций.doc

— 946.00 Кб (Скачать)

4

Сегмент стека

Ниже буду рассмотрены  только две команды, использующие стек, — это команды PUSH в начале сегмента кодов, которые обеспечивают возврат в DOS, когда EXE-программа завершается.

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

Таким образом, команды PUSH записывают в стек двухбайтовые адреса или другие значения. Команды POP обычно выбирают из стека записанные в него слова. Эти операции изменяют относительный адрес в регистре SP (то есть, в указатели стека) для доступа к следующему слову. Данное свойство стека требует чтобы команды RET и CALL соответствовали друг другу. Кроме того, вызванная процедура может вызвать с помощью команды CALL другую процедуру, а та в свою очередь — следующую. Стек должен иметь достаточные размеры для того, чтобы хранить все записываемые в него адреса. Как правило, стек объемом в 32 слова является достаточным.

Команды PUSH, PUSHF, CALL, INT, и INTO заносят в стек адрес  возврата или содержимое флагового  регистра. Команды POP, POPF, RET и IRET извлекают  эти aдреса или флаги из стека.

При передаче управления в EXE-программу система устанавливает  в регистрах следующие значения:

DS и ES

Адрес префикса программного сегмента — область  в 256 (шест. 100) байт, которая предшествует выполняемому программному модулю в  памяти.

CS

Адрес точки  входа в программу (адрес первой выполняемой команды).

IP

Нуль.

SS

Адрес сегмента стека.

4

Команды логических операций: AND, OR, XOR, TEST, NOT

Логические операции являются важным элементом в проектировании микросхем и имеют много общего в логике программирования. Команды AND, OR, XOR и TEST — являются командами  логических операций. Эти команды  используются для сброса и установки  бит и для арифметических операций в коде ASCII. Все эти команды обрабатывают один байт или одно слово в регистре или в памяти, и устанавливают флаги CF, OF, PF, SF, ZF.

AND

В случае, если оба  из сравниваемых битов равны 1, то результат  равен 1; во всех остальных случаях  результат — 0.

OR

В случае, если хотя бы один из сравниваемых битов равен 1, то результат равен 1; если сравниваемые биты равны 0, то результат — 0.

XOR

В случае, если один из сравниваемых битов равен 0, а  другой равен 1, то результат равен 1; если сравниваемые биты одинаковы (оба — 0 или оба — 1) то результат — 0.

TEST

Действует как AND — устанавливает флаги, но не изменяет биты. 

 

Первый операнд  в логических командах указывает  на один байт или слово в регистре или в памяти и является единственным значением, которое может изменятся после выполнения команд. В следующих командах AND, OR и XOR используются одинаковые битовые значения:

AND OR XOR 0101 0101 0101 0011 0011 0011

Результат:

0001 0111 0110

Для следующих  несвязанных примеров, предположим, что AL содержит 1100 0101, а BH содержит 0101 1100:

1. AND AL,BH ;Устанавливает в AL 0100 0100

2. OR BH,AL ;Устанавливает в BH 1101 1101

3. XOR AL,AL ;Устанавливает в AL 0000 0000

4. AND AL,00 ;Устанавливает в AL 0000 0000

5. AND AL,0FH ;Устанавливает в AL 0000 0101

6. OR CL,CL ;Устанавливает флаги SF и ZF

Примеры 3 и 4 демонстрируют  способ очистки регистра. В примере 5 обнуляются левые четыре бита регистра AL. Хотя команды сравнения CMP могут  быть понятнее, можно применить команду OR для следующих целей:

1. OR CX,CX ;Проверка CX на нуль JZ ... ;Переход, если нуль

2. OR CX,CX ;Проверка знака в CX JS ... ;Переход, если отрицательно

Команда TEST действует  аналогично команде AND, но устанавливает  только флаги, а операнд не изменяется. Ниже приведено несколько примеров:

1. TEST BL,11110000B ;Любой из левых бит в BL JNZ ... ; равен единице?

2. TEST AL,00000001B ;Регистр AL содержит JNZ ... ; нечетное значение?

3. TEST DX,OFFH ;Регистр DX содержит JZ ... ; нулевое значение?

Еще одна логическая команда NOT устанавливает обpатное значение бит в байте или в слове, в регистре или в памяти: нули становятся единицами, а единицы — нулями. В случае, если, например, pегистр AL содержит 1100 0101, то команда NOT AL изменяет это значение на 0011 1010. Флаги не меняются.

Команда NOT не эквивалентна команде NEG, которая меняет значение с положительного на отрицательное и наоборот, посредством замены бит на противоположное значение и прибавления единицы.

4

Изменение строчных букв на заглавные

Существуют различные  причины для преобразований между строчными и заглавными буквами. Например, вы могли получить файл данных, созданный на компьютере, который работает только с заглавными буквами. Или некая программа должна позволить пользователям вводить команды как заглавными, так и строчными буквами (например, YES или yes) и преобразовать их в заглавные для проверки. Заглавные буквы от A до Z имеют шест. коды от 41 до 5A, а строчные буквы от a до z имеют шест. коды от 61 до 7A.

Единственная pазница в том, что пятый бит равен 0 для заглавных букв и 1 для строчных:

Буква A: 01000001

Буква a: 01100001

Буква Z: 01011010

Буква z: 01111010

4

Команды сдвига и циклического сдвига

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

u обрабатывают байт или слово;

u имеют доступ к регистру или к памяти;

u сдвигают влево или вправо;

u сдвигают на величину до 8 бит (для байта) и 16 бит (для слова)

u сдвигают логически (без знака) или арифметически (со знаком).

Значение сдвига на 1 может быть закодировано как непосредcтвенный операнд, значение больше 1 должно находиться в регистре CL.

Команды сдвига

При выполнении команд сдвига флаг CF всегда содержит значение последнего выдвинутого бита.

Существуют следующие  команды cдвига:

SHR ;Логический (беззнаковый) сдвиг вправо

SHL ;Логический (беззнаковый) сдвиг  влево

SAR ;Арифметический сдвиг вправо

SAL ;Арифметический сдвиг влево

Следующий фрагмент иллюстрирует выполнение команды SHR:

MOV CL,03 ; AX:

MOV AX,10110111B ; 10110111

SHR AX,1 ; 01011011 ;Сдвиг вправо на 1

SHR AX,CL ; 00001011 ;Сдвиг вправо на 3

Первая команда SHR сдвигает содержимое регистра AX вправо на 1 бит.

Выдвинутый в  результате один бит попадает в флаг CF, а самый левый бит регистра AX заполняется нулем. Вторая команда cдвигает содержимое регистра AX еще на три бита. При этом флаг CF последовательно принимает значения 1, 1, 0, а в три левых бита в регистре AX заносятся нули.

Рассмотрим действие команд арифметического вправо SAR:

MOV CL,03 ; AX:

MOV AX,10110111B ; 10110111

SAR AX,1 ; 11011011 ;Сдвиг вправо на 1

SAR AX,CL ; 11111011 ;Сдвиг вправо на 3

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

При сдвигах  влево правые биты заполняются нулями. Таким обpазом, результат команд сдвига SHL и SAL индентичен.

Сдвиг влево  часто используется для удваивания чисел, а сдвиг вправо — для  деления на 2. Эти операции осуществляются значительно быстрее, чем команды умножения или деления. Деление пополам нечетных чисел (например, 5 или 7) образует меньшие значения (2 или 3, соответственно) и устанавливает флаг CF в 1. Кроме того, если необходимо выполнить сдвиг на 2 бита, то использование двух команд сдвига более эффективно, чем использование одной команды с загрузкой регистра CL значением 2.

Для проверки бита, занесенного в флаг CF используется команда JC (переход, если есть перенос).

Команды циклического сдвига

Циклический сдвиг представляет собой операцию сдвига, при которой выдвинутый бит занимает освободившийся разряд. Существуют следующие команды циклического сдвига:

ROR ;Циклический сдвиг вправо

ROL ;Циклический сдвиг влево 

RCR ;Циклический сдвиг вправо  с переносом

RCL ;Циклический сдвиг влево с  переносом

Следующая последовательность команд иллюстрирует операцию циклического сдвига ROR:

MOV CL,03 ; BX:

MOV BX,10110111B ; 10110111

ROR BX,1 ; 11011011 ;Сдвиг вправо на 1

ROR BX,CL ; 01111011 ;Сдвиг вправо на 3

Первая команда ROR при выполнении циклического сдвига переносит правый единичный бит регистра BX в освободившуюся левую позицию. Вторая команда ROR переносит таким образом три правых бита.

В командах RCR и RCL в сдвиге участвует флаг CF. Выдвигаемый  из регистра бит заносится в флаг CF, а значение CF при этом поступает в освободившуюся позицию.

Рассмотрим пример, в котором используются команды  циклического и простого сдвига. Предположим, что 32-битовое значение находится  в регистрах DX:AX так, что левые 16 бит лежат в регистре DX, а правые — в AX. Для умножения на 2 этого значения возможны cледующие две команды:

SHL AX,1 ;Умножение пары регистров 

RCL DX,1 ; DX:AX на 2

Здесь команда SHL сдвигает все биты регистра AX влево, причем самый левый бит попадает в флаг CF. Затем команда RCL сдвигает все биты регистра DX влево и в освободившийся правый бит заносит значение из флага CF. 

 

4

Организация программ

Ниже даны основные рекомендации для написания ассемблерных программ:

1. Четко представляйте  себе задачу, которую должна решить программа.

2. Сделайте эскиз  задачи в общих чертах и  спланируйте общую логику программы. 

Например, если необходимо проверить операции пеpесылки нескольких байт, начните c определения  полей с пересылаемыми данными.

Затем спланируйте  общую стратегию для инициализации, условного перехода и команды LOOP.

Приведем основную логику, которую используют многие программисты в таком случае:

инициализация стека и сегментных регистров

вызов подпрограммы цикла

возврат

Подпрограмма  цикла может быть спланирована следующим образом:

инициализация регистров значениями адресов и числа циклов

Метка: пересылка одного байта увеличение адресов на 1 уменьшение счетчика на 1: если счетчик не ноль, то идти на метку  если ноль, возврат

3. Представьте  программу в виде логических блоков, следующих друг за другом. Процедуры не превышающие 25 строк (размер экрана) удобнее для отладки.

4. Пользуйтесь  тестовыми примерами программ. Попытки  запомнить все технические детали  и программирование сложных программ  «из головы» часто приводят к многочисленным ошибкам.

5. Используйте  комментарии для описания того, что должна делать процедура,  какие арифметические действия  или операции сравнения будут  выполняться и что делают редко  используемые команды. (Например, команда  XLAT, не имеющая операндов).

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

Важно:

u Метки процедур должны завершаться двоеточием для указания типа NEAR. Отсутствие двоеточия приводит к ассемблерной ошибке.

u Метки для команд условного перехода и LOOP должны лежать в границах -128 до +127 байт. Операнд таких команд генерирует один байт объектного кода. Шест. от 01 до 7F соответствует десятичным значениям от +1 до +127, а шест. от FF до 80 покрывает значения от -1 до +128. Так как длина машинной команды может быть от 1 до 4 байт, то соблюдать границы не просто. Практически можно ориентироваться на размер в два экрана исходного текста (примерно 50 строк).

u При использовании команды LOOP, инициализируйте регистр CX положительным числом. Команда LOOP контролирует только нулевое значение, при отрицательном программа будет продолжать циклиться.

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

u Выбирайте команды условного перехода соответственно операциям над знаковыми или беззнаковыми данными.

u Для вызова процедуры используйте команду CALL, а для возврата из процедуры — команду RET. Вызываемая процедура может, в свою очередь, вызвать другую процедуру, и если следовать существующим соглашениям, то команда RET всегда будет выбирать из стека правильный адрес возврата. 

 

 

  

 

u Будьте внимательны при использовании индексных операндов. Сравните: 
MOV AX,SI 
MOV AX,[SI] 
Первая команда MOV пересылает в регистр AX содержимое регистра SI. Вторая команда MOV для доступа к пересылаемому слову в памяти использует относительный адрес в регистре SI.

u Используйте команды сдвига для удваивания значений и для деления пополам, но при этом внимательно выбирайте соответствующие команды для знаковых и беззнаковых данных. 

 

Лекция 12. 
Компоновка программ

4

Межсегментные вызовы

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

u бывает необходимо скомпоновать программы, написанные на разных языках, например, для объединения мощности языка высокого уровня и эффективности Ассемблера;

Информация о работе Системное программирование