Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
2014- СП 3.0 ЛАБЫ ОБЯЗАТ.doc
Скачиваний:
99
Добавлен:
01.03.2016
Размер:
896 Кб
Скачать
      1. Эксперимент 4

Целью этого эксперимента будет наблюдение кода символа, введенного при исполнении макроса inkey.

Выполните коррекцию макроса inkey, как описано в Примечании А п.6.2.4.3.

  1. Ниже строки inkey "Нажми пробел..."вставьте строки:print str$(EAX),13,10 inkey "Выскочил код пробела 32?"

  2. Сохранить изменения. Распечатать программу в этом состоянии, включить в отчет.

  1. Создать программу консольным вызовом (можно в TotalCommander)buildc cio

  2. Выполнить cio.exe. После вывода «Нажми пробел…» нажмите именно пробел, мы знаем его код (32), убедиться, что всё работает правильно .

  3. Сделать скриншот выполнения эксперимента для отчета.

    1. Состав отчета по работе

  1. Номер и название работы, фамилия и группа студента.

  2. Цель работы.

  3. Протокол выполнения работы со всеми распечатками, скриншотами, комментариями и наблюдениями согласно разделу «Выполнение работы».

  4. Развернутые выводы по работе.

    1. Вопросы для самопроверки

  1. Каков механизм общения компьютерных программ с внешним миром?

  2. Что такое APIWin32? Какую функцию он выполняет?

  3. Что такое процедурный и функциональный способ вызова макросов?

  4. Какой регистр меняет значение при выполнении макроса print? Как обойти эту особенность его работы?

  5. Какой дефект мы обнаружили и исправили в поставляемом макросе inkey?

  1. МЕХАНИЗМ ИСПОЛЬЗОВАНИЯ ПРОЦЕДУР

    1. Цель работы

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

    1. Теоретические сведения

Процедура – это подпрограмма основной программы. Основная программа может вызывать процедуру сколько угодно раз. Для этого нужно при каждом вызове передать управление на «точку входа» в процедуру – то есть ту команду, которая в процедуре будет выполняться первой.

Тут есть две технических проблемы:

  1. как нарушить естественное последовательное выполнение команд основной программы и «перепрыгнуть» в процедуру и

  2. как правильно вернуться к продолжению основной программы после окончания выполнения процедуры.

И то, и другое просто и эффективно решается с помощью специального регистра процессора EIP–ExtendedInstructionPointer. Ну, и, разумеется, соблюдением определенных правил поведения, о чем пойдет речь ниже.

      1. Последовательное выполнение команд

Сначала разберемся, как вообще происходит выполнение процессором цепочек команд.

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

Регистр EIPиспользуется процессором для адресации в оперативной памяти очередной машинной команды (что видно и из его названия –pointer, то есть указатель).

Стандартной ситуацией при выполнении программ является последовательное выполнение команд, записанных в памяти одна за другой вплотную. Нарушения этого порядка происходят при:

  1. безусловных и условных переходах в программах (конструкции типа “if–else”, циклы;

  2. вызовах процедур и возвратах из них.

Подобные «нарушения» происходят очень часто, потому что без них реальное программирование попросту невозможно (что же это за программа, в которой нельзя, например, проверить ну хоть какое-то условие и разветвить выполнение?). Но для процессора такие «прыжки» были и остаются особыми действиями, и мы сейчас разберемся, как это организовано.

Для внешнего наблюдателя выполнение процессором любой команды происходит в пять последовательных стадий:

  1. чтениекоманды из оперативной памяти по адресу, который хранится вEIP, в устройство распознавания (оно – функциональная часть процессора);

  2. распознаваниекоманды и построение ее микрокода;

  3. установка адресовчтения операндов команды и (для пятого шага) адреса записи результатов выполнения;

  4. выполнениекоманды (то есть вычисление результата выполнения);

  5. Запись результатавыполнения по сформированному на шаге 3 адресу.

Давайте разберемся, что происходит с регистром EIPпри чтении команды.

Перед началом чтения команды регистр EIPуказывает на первый байт команды, которая будет читаться (08):

Происходит копирование байта 08 в процессор. Что нужно сделать, чтобы в процессор стало возможно прочитать следующий байт ВЕ? Давайте рассмотрим этот вопрос подробно.

Чтение-запись выполняется только по адресу, который выставляется на шине адреса. Это хорошо знакомая вам по общему курсу программирования операция разадресации, когда дан адрес, а читается-пишется данное, расположенное по этому адресу. В компьютере операцию разадресации (чтение-запись по указанному адресу) выполняет аппаратная компонена системный контроллер, он входит в состав микросхемы «Южный мост», которую всегда можно увидеть на материнской плате. Он коммутируется, во-первых, с шиной адреса, на которую выставляется адрес, а во-вторых, с шиной данных, на которую либо передаются прочитанные данные, либо с неё берутся записываемые данные.

Если ничего не менять на шинах, то сколько раз ни подавать на контроллер сигнал чтения, на шину данных всякий раз будет переноситься один и тот же байт – тот, чей адрес выставлен на шине адреса.

Понятно! Чтобы прочитать байт ВЕ, нужно указатель EIPпереставить на него! Как? Очень просто – прибавить кEIPединицу, потому что адреса соседних байтов отличаются ровно на 1. И можно читать.

Теперь мы понимаем: чтение каждого очередного байта команды сразу же увеличивает EIP на 1.

Примечание. Команды в архитектуре х86/IA-32 имеют разную длину – от одного до 7 байт. Откуда процессор «знает», сколько байт нужно прочесть, чтобы получилась полная команда? Ответ – это становится «известным» сразу после чтения первого байта команды, который выполняет роль идентификатора команды. Как только этот байт прочитан, в процессоре внутренний счетчик цикла чтения байтов команды аппаратно устанавливается в значение «сколько дополнительных байтов команды еще нужно прочесть». Что и делается.

Когда команда 08BE1400 полностью прочитана из памяти в процессор, он приступает к ееобработке(шаги 2-5 из приведенной выше последовательности). Там в том числе и шаг 4 «выполнение». Вопрос: а в каком положении при этом находитсяEIP? А вот в каком:

Неожиданное открытие! Выполняется команда 1, а EIPуже указывает на следующую по записи команду 2! И произошло это именно потому, что побайтное чтение команды сдвигаетEIPвперед на 1 после чтения каждого байта. Выходит, что при последовательном выполнении команд адрес следующей (по отношению к выполняемой в данный момент) команды формируется автоматически, просто в силу процесса чтения команд из памяти. Кстати, это есть практическое проявление одного из принципов фон Неймана по правильному построению архитектуры компьютеров.

Теперь рассмотрим особенности передачи управления..