Top100
Поиск рефератов [+]

Студик.ру / Рефераты / Программирование и комп-ры /

Взаимосвязь языков C и ассемблера

МОСКОВСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ ЭКОНОМИКИ, СТАТИСТИКИ И ИНФОРМАТИКИ

КАФЕДРА МО ЭВМ

КУРСОВАЯ РАБОТА

на тему : “Взаимосвязь языков С и ассемблера”

Студент: Аплемах А.В. Группа: ДП-202

Руководитель проекта: Комлева Н.В.

Защищена “___” Мая 1997 г.

Москва 1997г.

СОДЕРЖАНИЕ

Введение3Раздел 1: Регистры и параметры51.1 Использование регистров51.2 Ассемблерные операторы Inline51.3 Размещение данных и операторов в программе6Раздел 2: Особенности данных72.1 Разделение данных72.2 Объявление ассемблерных данных72.3 Разделение кода8Раздел 3: Вызов ассемблерных функций из С93.1 Символы подчеркивания 93.2 Использование дальних данных93.3 Вызов ассемблерных функций из С103.4 Ассемблирование и компоновка внешних модулей11Раздел 4: Вызов функций С из ассемблера154.1 Вызов С и С++ из ассемблера154.2 Локальные переменные174.3 Передача аргументов18Раздел 5: Курсовая программа205.1 Постановка задачи205.2 Блоксхема программы205.3 Модуль на С++205.4 Модуль на ассемблере215.5 Анализ проведенной работы23Список использованной литературы24 Введение

В идеальном мире программирования компиляторы с языков высокого уровня должны генерировать самый быстрый, самый компактный и наилучший машинный код для любой программы. Если бы это было невозможно, то программирование много бы потеряло от этого, и наверняка не писался бы этот курсовик. Но это невозможно. Несмотря на множество усовершенствований при разработке компиляторов, ни один язык высокого уровня пока не в состоянии продублировать краткий, быстрый и изящный код, написанный опытным специалистом по ассемблеру. В чем же дело? А в том, что компиляторы обобщают решаемые ими задачи. В C++ существует только один способ написания цикла FOR. В то же время с помощью ассемблера этот цикл можно организовать с помощью ассемблера этот цикл можно организовать десятками способов. Чтобы компилятор выбирал идеально подходящие в каждой конкретной ситуации методы реализации алгоритма и при этом учитывая их влияние на остальные части программы - он должен обладать интеллектом гения, вкусом художника и интуицией предсказателя. Сегодняшние компиляторы с языков высокого уровня достаточно сообразительны, но не до такой степени. Среди всех существующих компиляторов С наиболее приблизился к идеалу С++. Порождаемый им машинный код работает достаточно быстро, занимает на диске немного места и в большинстве случаев может использоваться без каких-либо модификаций. Однако несмотря на все достоинства С++, все равно остается место для улучшений, благодаря чему даже небольшие участки программы, переписанные на ассемблере, могут значительно повысить скорость работы программы и уменьшить размер исполняемого файла. Кроме того, добавив ассемблер к С++, можно облегчить доступ к регистрам аппаратных средств и решение других задач низкого уровня, таких как запись символов непосредственно в видеопамять. Во многих случаях единственный способ для прибавления программе скорости - немного дополнить совершенный “С”, используя один из двух методов: · Использование встроенных операторов (операторов Inline) · Использование внешних функций Операторы Inline вставляют язык ассемблера непосредственно в исходную программу на С и С++. Эта методика быстрая и простая, но имеет несколько недостатков, которые поясняться ниже. Внешние функции, хотя их и трудно использовать, чем операторы Inline, имеют то преимущество, что позволяют наиболее полно использовать
все возможности Turbo Assembler.

Раздел 1: Регистры и параметры

1.1 Использование регистров

В создаваемых ассемблерных программах можно использовать все регистры процессора. Но чтобы предотвратить путаницу с функциями С и С++, необходимо восстанавливать bp, cs, sp и ss, которые они имели до запуска созданной подпрограммы. Тогда можно быть совершенно уверенным, что обращение к другим функциям не изменит эти регистры. Также нельзя забывать, что С использует регистры si и di для регистровых переменных, поэтому при использовании встроенного ассемблера замедляется общая работа программы. К регистрам ax, bx, cx, dx и es можно обращаться свободно и не нужно резервировать их значения до окончания подпрограммы. Эта свобода касается и других функций, поэтому надо помнить, что эти регистры изменяться, если вызываются функции С и С++ из ассемблерных подпрограмм.

1.2 Ассемблерные операторы Inline

Ассемблерные операторы inline начинаются словом asm, за которым следует инструкция и ее операнды. Например, чтобы синхронизировать программу с внешним сигналом прерывания, можно написать: /* ожидание прерывания*/ asm sti asm hlt printf(“Прерывание получено\n”) Когда ранние версии Turbo C компилируют программу со встроенными командами asm, компилятор сперва создает ассемблерный текст для всей программы, вставляя в текст наши ассемблерные инструкции вместе с откомпилированным кодом для остальных операторов С. Затем компилятор вызывает Turbo Assembler и Linker (компоновщик), чтобы провести ассемблирование и подключить программу к конечному файлу кода. Более поздние версии Turbo и Borland C++ могут компилировать операторы asm без вызова TASM. Полный синтаксис asm: asm[метка] мнемоника/директива операнды [;] [/*С комментарий*/] Точки с запятыми в конце строк asm и комментарии С, расположенные между /*и*/ удаляются из текста перед ассемблированием, поэтому их можно опускать в тексте программы.

1.3 Размещение данных и операторов в тексте программы

Каждая строка текста программы С и С++ находится либо внутри, либо снаружи функции, и операторы asm могут вставляться как в одном, так и в другом месте. Конкретное положение оператора asm влияет на то, куда ассемблируется код или директива. Если оператор asm появляется снаружи функции, то он ассемблируется в сегмент данных программы, если внутри функции - в кодовый сегмент. Обычно, чтобы создать переменные, операторы asm вставляются снаружи функций; для создания кода их следует вставлять внутрь функций. Например: asm count db ? int main() { asm shl [count], 1/*умножение count на 4*/ asm shl [count], 1 return 0; } Переменная count объявляется в сегменте данных программы (относительно ds). Операторы внутри функции main умножают count на 4, используя вместо mul быстрые инструкции сдвига shl. Если объявлять переменные внутри функции, данные ассемблируются в кодовый сегмент, требуя особого обхождения: int main() { asm jmp OverThere asm count db ? OverThere: asm shl [count], 1 /* умножение count на 4*/ asm shl [count], 1 return 0; } Поскольку теперь переменная count находится в кодовом сегменте, требуется инструкция jmp, чтобы избежать случайного восприятия значения count в качестве машинного кода и его исполнения.

Раздел 2: Особенности данных

2.1 Разделение данных

Inline операторы asm имеют свободный доступ к переменным и структурам С и C++ - одно из самых привлекательных преимуществ метода inline
1 2 3 4 ...    последняя
На сайте:
,
,
Rambler TOP100 Яндекс цитирования