МИНОБРНАУКИ РОССИИ САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ ЭЛЕКТРОТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ «ЛЭТИ» ИМ. В.И. УЛЬЯНОВА (ЛЕНИНА)
Кафедра МО ЭВМ
ОТЧЕТ по лабораторной работе №6
по дисциплине «Организация ЭВМ и систем»
Тема: ОРГАНИЗАЦИЯ СВЯЗИ АССЕМБЛЕРА С ЯВУ НА ПРИМЕРЕ
ПРОГРАММЫ ПОСТРОЕНИЯ ЧАСТОТНОГО РАСПРЕДЕЛЕНИЕ ПОПАДАНИЙ
ПСЕВДОСЛУЧАЙНЫХ ЦЕЛЫХ ЧИСЕЛ В ЗАДАННЫЕ ИНТЕРВАЛЫ
Студент гр. 8383 |
|
Ларин А. |
Преподаватель |
|
Ефремов М.А, |
Санкт-Петербург
2019
Цель работы.
Научится совмещать ЯВУ с языком ассемблера. Научится использовать в ЯВУ функции, написанные на языке ассемблера, передавать в них параметры и обрабатывать их. Использовать полученные знания для анализа распределения псевдослучайных чисел.
Основные теоретические положения.
Существуют следующие формы комбинирования программ на языках высокого уровня с ассемблером:
Использование ассемблерных вставок (встроенный ассемблер, режим inline).Ассемблерныекодыввидекомандассемблеравставляютсяв). Ассемблерные коды в виде команд ассемблера вставляются в текст программы на языке высокого уровня. Компилятор языка распознает их как команды ассемблера и без изменений включает в формируемый им объектный код. Эта форма удобна, если надо вставить небольшой фрагмент.
Использование внешних процедур и функций. Это более универсальная форма комбинирования. У нее есть ряд преимуществ:
—написание и отладку программ можно производить независимо;
—написанные подпрограммы можно использовать в других проектах;
—облегчаются модификация и сопровождение подпрограмм.
Использование внешних процедур Для связи посредством внешних процедур создается многофайловая
программа. При этом в общем случае возможны два варианта вызова:
программа на языке высокого уровня вызывает процедуру на языке ассемблера;
программа на языке ассемблера вызывает процедуру на языке высокого
уровня.
Рассмотрим более подробно первый вариант. В программах, написанных на языке ассемблера, используется соглашение передачи параметров stdcall. Однако по сути получение и передача параметров в языке ассемблера производится явно, без помощи транслятора.
2
При связи процедуры, написанной на языке ассемблера, с языком высокого уровня, необходимо учитывать соглашение по передаче параметров.
Конвенция Pascal заключается в том, что параметры из программы на языке высокого уровня передаются в стеке и возвращаются в регистре АХ/ЕАХ, — это способ, принятый в языке PASCAL (а также в BASIC, FORTRAN, ADA, OBERON, MODULA2), — просто поместить параметры в стек в естественном порядке. В этом случае запись
some).Ассемблерныекодыввидекомандассемблеравставляютсяв_proc(a,b,c,d); запишется как push a
push b push с push d
call some).Ассемблерныекодыввидекомандассемблеравставляютсяв_proc@16
Процедура some).Ассемблерныекодыввидекомандассемблеравставляютсяв_proc, во-первых, должна очистить стек по окончании работы (например, командой re).Ассемблерныекодыввидекомандассемблеравставляютсявt 16) и, во-вторых, параметры, переданные ей, находятся в стеке в обратном порядке:
some).Ассемблерныекодыввидекомандассемблеравставляютсяв_proc proc push e).Ассемблерныекодыввидекомандассемблеравставляютсявbp
mov e).Ассемблерныекодыввидекомандассемблеравставляютсявbp,e).Ассемблерныекодыввидекомандассемблеравставляютсявsp ; пролог mov e).Ассемблерныекодыввидекомандассемблеравставляютсявax, [e).Ассемблерныекодыввидекомандассемблеравставляютсявbp+20] ; a mov e).Ассемблерныекодыввидекомандассемблеравставляютсявbx, [e).Ассемблерныекодыввидекомандассемблеравставляютсявbp+16] ; b mov e).Ассемблерныекодыввидекомандассемблеравставляютсявcx, [e).Ассемблерныекодыввидекомандассемблеравставляютсявbp+12] ; c mov e).Ассемблерныекодыввидекомандассемблеравставляютсявdx, [e).Ассемблерныекодыввидекомандассемблеравставляютсявbp+8] ; d
…
pop e).Ассемблерныекодыввидекомандассемблеравставляютсявbp ; эпилог re).Ассемблерныекодыввидекомандассемблеравставляютсявt 16 some).Ассемблерныекодыввидекомандассемблеравставляютсяв_proc e).Ассемблерныекодыввидекомандассемблеравставляютсявndp
Этот код в точности соответствует полной форме директивы proc.
Однако можно использовать упрощенную форму, которую поддерживают все современные ассемблеры:
3
some).Ассемблерныекодыввидекомандассемблеравставляютсяв_proc proc PASCAL, а:dword, b:dword, с:dword, d:dword
…
re).Ассемблерныекодыввидекомандассемблеравставляютсявt
some).Ассемблерныекодыввидекомандассемблеравставляютсяв_proc e).Ассемблерныекодыввидекомандассемблеравставляютсявndp
Главный недостаток этого подхода — сложность создания функции с изменяемым числом параметров, аналогичных функции языка С printf. Чтобы определить число параметров, переданных printf, процедура должна сначала прочитать первый параметр, но она не знает его расположения в стеке. Эту проблему решает подход, используемый в С, где параметры передаются в обратном порядке.
С используется, в первую очередь, в языках С и C++, а также в PROLOG и других. Параметры помещаются в стек в обратном порядке, и, в противоположность PASCAL-конвенции, удаление параметров из стека выполняет вызывающая процедура.
Запись some).Ассемблерныекодыввидекомандассемблеравставляютсяв_proc(a,b,c,d) будет выглядеть как push d
push с push b push a
call some).Ассемблерныекодыввидекомандассемблеравставляютсяв_proc@16
add e).Ассемблерныекодыввидекомандассемблеравставляютсявsp,16 ; освободить стек
Вызванная таким образом процедура может инициализироваться так: some).Ассемблерныекодыввидекомандассемблеравставляютсяв_proc proc
push e).Ассемблерныекодыввидекомандассемблеравставляютсявbp
mov e).Ассемблерныекодыввидекомандассемблеравставляютсявbp,e).Ассемблерныекодыввидекомандассемблеравставляютсявsp ; пролог mov e).Ассемблерныекодыввидекомандассемблеравставляютсявax, [e).Ассемблерныекодыввидекомандассемблеравставляютсявbp+8] ; a mov e).Ассемблерныекодыввидекомандассемблеравставляютсявbx, [e).Ассемблерныекодыввидекомандассемблеравставляютсявbp+12] ; b mov e).Ассемблерныекодыввидекомандассемблеравставляютсявcx, [e).Ассемблерныекодыввидекомандассемблеравставляютсявbp+16] ; c mov e).Ассемблерныекодыввидекомандассемблеравставляютсявdx, [e).Ассемблерныекодыввидекомандассемблеравставляютсявbp+20] ; d
…
4
pop e).Ассемблерныекодыввидекомандассемблеравставляютсявbp re).Ассемблерныекодыввидекомандассемблеравставляютсявt
some).Ассемблерныекодыввидекомандассемблеравставляютсяв_proc e).Ассемблерныекодыввидекомандассемблеравставляютсявndp
Трансляторы ассемблера поддерживают и такой формат вызова при помощи полной формы директивы proc с указанием языка С:
some).Ассемблерныекодыввидекомандассемблеравставляютсяв_proc proc С, а:dword, b:dword, с:dword, d:dword
…
re).Ассемблерныекодыввидекомандассемблеравставляютсявt
some).Ассемблерныекодыввидекомандассемблеравставляютсяв_proc e).Ассемблерныекодыввидекомандассемблеравставляютсявndp
Регистр EВР используется для хранения параметров, и его нельзя изменять программно при использовании упрощенной формы директивы proc. Преимущество по сравнению с PASCAL-конвенцией заключается в том, что освобождение стека от параметров в конвенции С возлагается на вызывающую процедуру, что позволяет лучше оптимизировать код программы. Например, если необходимо вызвать несколько функций, принимающих одни и те же параметры подряд, можно не заполнять стек каждый раз заново, и это — одна из причин, по которой компиляторы с языка С создают более компактный и быстрый код по сравнению с компиляторами с других языков.
Смешанные конвенции
Существует конвенция передачи параметров STDCALL, отличающаяся и от C, и от PASCAL-конвенций, которая применяется для всех системных функций Win32 API. Здесь параметры помещаются в стек в обратном порядке, как в С, но процедуры должны очищать стек сами, как в PASCAL.
Еще одно отличие от С-конвенции – это быстрое или регистровое соглашение FASTCALL. В этом случае параметры в функции также передаются по возможности через регистры. Например, при вызове функции с шестью параметрами
some).Ассемблерныекодыввидекомандассемблеравставляютсяв_proc(a,b,с,d,e).Ассемблерныекодыввидекомандассемблеравставляютсяв,f);
первые три параметра передаются соответственно в ЕАХ, EDX, ЕСХ, а только начиная с четвертого, параметры помещают в стек в обычном обратном порядке:
5