46019 (665326), страница 37

Файл №665326 46019 (Turbo C++ Programer`s guide) 37 страница46019 (665326) страница 372016-07-31СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 37)

Для того, чтобы идентификаторы были видимыми извне ассемблерного модуля, вы должны объявить их как PUBLIC.

Например, если высобираетесь написать модуль с целочисленными функциями max и min, а также целочисленными переменными MAXINT, lastmaxи lastmin, вам следует поместить в кодовый сегмент оператор

PUBLIC _max, _min

и операторы

PUBLIC _MAXINT, _lastmax, _lastmin

_MAXINT DW 32767

_lastmin DW 0

_lastmax DW 0

в сегмент данных.

TASM 2.0

Turbo Assemblrt 2.0 расширяет синтаксис многих директив, позволяя задавать опциональный спецификатор языка. Например, если вы укажете С в вашем модуля в директиве .MODEL, то все имена идентификаторов будут записываться в объектный модуль с ведущим символом подчеркивания. Это средство такжеможет работать на уровне директив. При помощи спецификатора языкаC в Turbo Assembler 2.0 вышеприведенные объявления можно переписать в виде:

PUBLIC C max, min

PUBLIC C MAXINT, lastmax, lastmin

MAXINT DW 32767

lastmin DW 0

lastmax DW 0

Подготовка к вызову Turbo C++ из .ASM

Для того, чтобы модуль на языке ассемблера мог обращаться к функциям и переменным программы на Turbo C++, следует использовать оператор EXTRN.

Ссылки к функциям

Для того, чтобы иметьвозможность вызвать функцию С из подпрограммы на языке ассемблера, вы должны объявить ее в ассемблерном модуле в операторе

EXTRN fname : fdist

где fname - это имя функции, а fdist - это либо near, либо far, в зависимости от того, является ли функция С near или far. Поэтому в кодовом сегменте может находиться оператор

EXTRN _myCfunc1:near, _myCfunc2:far

что позволяет вызывать myCfunc1 и myCfunc2 из подпрограмм на языке ассемблера.

TASM 2.0

Используя спецификатор языкаС в Turbo Assembler2.0 последний оператор можно переписать как:

EXTRN C mCfunc1:near, myCfunc2:far

Ссылки к данным

Для обращения к переменным следует поместить в сегмент данных соответствующий оператор(ы) EXTRN в формате:

EXTRN vname : size

где vname - это имя переменной, а size указывает размер переменной.

Размер переменной может быть следующим:

BYTE(1 байт) QWORD(8 байтов)

WORD(2 байта) TBYTE(10 байтов)

DWORD(4 байта)

Поэтому, если вС-программе имеются следующие глобальные переменные:

int i,jarray[10];

char ch;

long result;

то можно сделать их видимыми из вашего модуля при помощи следующего оператора:

EXTRN _i:WORD,_jarray:WORD,_ch:BYTE,_result:DWORD

либо при помощи спецификатора языка С в Turbo Assembler 2.0 (TASM 2.0):

EXTRN C i:WORD,jarray:WORD,ch:BYTE,result:DWORD

Важное замечание !

При использовании модели памяти huge операторы EXTRN должны находиться вне любых сегментов. Это относится как к функциям,так и к переменным.

Определение подпрограмм на языке ассемблера

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

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

extern int min(int v1, int v2);

Вы хотите, чтобы min возвращала минимальное из двух переданных ей значений. Общий формат min будет следующий:

PUBLIC _min

_min PROC NEAR

...

_min ENDP

Разумеется, это предполагает,что min является ближней функцией; если бы эта функция была дальней, вы бы подставилиFAR вместо NEAR. Отметим, что мы добавили передmin символ подчеркивания, благодаря чему компоновщик Turbo C++ может правильно разрешить ссылки. Если бы мы использовали в операторе PUBLIC спецификатор языка С Turbo Assembler 2.0, ассемблер позаботился бы об этом сам.

Передача параметров

Прежде всего, вы должны решить, какое соглашениео передаче параметров использовать; при отсутствииадекватной причины избегайте соглашения о передаче параметров Паскаля, соглашение С является предпочтительным. Это означает, что когда min вызвана, стек будет выглядеть следующим образом:

sp + 04: v2

sp + 02: v1

sp: адрес возврата

Вам требуется получить доступ к параметрам, не выполняя снятие со стека, поэтому вам следует сохранить указатель базы (BP), переслать указатель стека (SP) в указатель базы, а затем использовать последний для прямой индексации стека, что позволит получить необходимые значения. Отметим, что при помещении BP в стек относительные смещения параметров увеличатся на 2, поскольку стек теперь увеличится на два.

TASM 2.0

Turbo Assembler 2.0 обеспечивает простой способ обращения к параметрам функции и работы со стеком. Прочтите следующее; для вас важно понять, как работает адресация стека.

Обработка значений возврата

Ваша функция возвращает целочисленное значение; куда же оно помещается? Для 16-битовых (2-байтовых) значений (char, short, int, enum иближних указателей) используется регистр AX; для 32-битовых (4-байтовых) значений (включая указатели far и huge) используется также регистр DX, причем старшее слово (в случае указателей это адрес сегмента) помещается в DX, а младшее слово помещается в AX.

Значениятипа float, double и long double возвращаются через регистр "вершины стека" (TOS), ST(0); если используется эмулятор 80x87, то значение возвращается через регистр TOS эмулятора. Вызывающая функция должна скопировать это значениетуда, куда требуется.

Структуры длиной в 1 байт возвращаются через AL. Структуры длиной в 2 байта возвращаются через AX. Структуры длиной 4 байта возвращаются через DX:AX. Для возврата структур, имеющих размер 3 байта или более 5 байтов, онипомещаются в областьстатических данных и затем возвращается указатель на их адрес (через AX для моделей данных small и через DX:AX для моделей данных large). вызываемая подпрограмма должна скопировать значение возврата по адресу, задаваемому указателем.

В примере с функцией min выимеетедело с 16-битовым значением, поэтому ответ можно поместить непосредственно в AX.

Так будет выглядеть этот код теперь:

PUBLIC _min

_min PROC NEAR

push bp;записать bp в стек

mov bp,sp;скопировать sp в bp

mov ax,[bp+4];переслать v1 в ax

cmp ax,[bp+6];сравнить с v2

jle exit ;если v1 > v2

mov ax,[bp+6];то загрузить v2 в ax

exit: pop bp;восстановить bp

ret;и выполнить возврат в С

_min ENDP

Что, если вы объявитеmin как дальнюю (far) функцию - что изменится в результате этого? Главноеотличие будетсостоять в том, что стек на входе в подпрограмму будет выглядеть следующим образом:

sp + 06: v2

sp + 04: v1

sp + 02: сегмент возврата

sp: смещение возврата

Это означает, что смещения встек увеличились на два, поскольку теперь в стекпомещается дополнительно 2 байта (содержащие сегмент возврата). Версия min в случае far выглядит следующим образом:

PUBLIC _min

_min PROC FAR

push bp;записать bp в стек

mov bp,sp;скопировать sp в bp

mov ax,[bp+6];переслать v1 в ax

cmp ax,[bp+8];сравнить с v2

jle exit ;если v1 > v2

mov ax,[bp+6];то загрузить v2 в ax

exit: pop bp;восстановить bp

ret;и выполнить возврат в С

_min ENDP

Отметим,что все смещения для v1 и v2 увеличились на 2, что отражает дополнительно помещенные в стек два байта.

Что будет, если вы решите использовать последовательность передачи параметров Паскаля?

При входе ваш стек будет выглядеть теперь следующим образом (предполагая снова, что min является NEAR функцией):

SP + 04: v1

SP + 02: v2

SP: адрес возврата

Кроме того, вам придетсясоблюдать соглашения Паскалядля идентификатора min: он должен быть записан заглавными буквами и не иметь символа подчеркивания в начале.

Помимо того, что должны поменяться местами v1 и v2, это соглашение также подразумевает, что min должна очищать стекпри выходе, задавая в команде RET число байтов, которые должны сниматься со стека. В данном случае требуетсяснять со стека 4 дополнительных байтадля v1 и v2 (адрес возврата снимается со стека автоматически командой RET).

Вот как будет выглядеть модифицированная подпрограмма:

PUBLIC MIN

MIN PROC NEAR ;версия с соглашениями Паскаля

push bp;записать bp в стек

mov bp,sp;скопировать sp в bp

mov ax,[bp+6];переслать v1 в ax

cmp ax,[bp+4];сравнить с v2

jle exit ;если v1 > v2

mov ax,[bp+4];то загрузить v2 в ax

exit: pop bp;восстановить bp

ret 4;очистить стек и выполнить

;возврат в С

MIN ENDP

Приведем последний пример того,почемуможет понадобиться использование последовательностьпередачи параметров С. Предположим, вы переопределили min следующим образом:

int min (int count,...);

Теперь min может принимать любое число целочисленных параметров, возвращая минимальный из них. Однако, поскольку min не можетавтоматически определить число передаваемых ей параметров, можно сделать первый передаваемый параметр счетчиком , который будетуказывать число следующих за ним параметров. Например, вы можете использовать функцию следующим образом:

i = min(5, j, limit, indx, lcount, 0);

предполагая, что i, j, limit, indx и lcount имеют тип int (или любой совместимый с ним тип). Стек после входа в подпрограмму будет иметь вид:

sp + 08: (и т.д.)

sp + 06: v2

sp + 04: v1

sp + 02: count

sp: адрес возврата

Модифицированная версия min будет иметь теперь вид:

PUBLIC MIN

_min PROC NEAR

push bp;записать bp в стек

mov bp,sp;скопировать sp в bp

mov cx,[bp+4];переслать count в cx

cmp cx,0 ;сравнить с 0

jle exit ;если <= 0 то выход из подпрограммы

lea bx,[bp+6];установить bx

mov ax,[bx];переслать первое значение

imp ltest;проверить цикл

compare: cmp ax,[bx];сравнение

jle ltest;если след. значение

mov ax,[bx];то загрузить в ax...

ltest: add bx,2 ;переход к новому значению

loop compare;продолжение цикла

exit: pop bp;восстановить bp

ret;возврат в С

_min ENDP

Данная версии подпрограммы будет правильно обрабатыватьвсе возможные значения счетчика count:

- Если count <= 0, то min возвращает 0.

- Если count = 1, то min возвращает первое значение в списке.

- Если count >= 2, то min выполняет последовательность сравнений до последнего переданного ей в списке значения.

Теперь, когда вы понимаете, как нужно манипулировать стеком и умеете писать свои собственные функции,вы можете оценить некоторые новые расширения версии Turbo Assembler

2.0. Некоторые из них позволяют вам автоматически создавать имена переменных, устанавливать и очищать стек из PROC, а также легко выполнять доступ к параметрам, используя при этом соглашения того языка, на котором написана вызывающая процедура.

С учетомэтих расширений первая версия min (на стр.257 оригинала) может быть переписана следующим образом:

PUBLIC C MIN

min PROC C NEAR v1: WORD, v2: WORD

mov ax,v1

cmp ax,v2

jle exit

mov ax,v2

exit: ret

min ENDP

Версия с соглашениями Паскаля (стр.259 оригинала) может быть переписана в виде:

PUBLIC PASCAL MIN

min PROC PASCAL NEAR v1: WORD, v2: WORD

mov ax,v1

cmp ax,v2

jle exit

mov ax,v2

exit: ret

min ENDP

Отметим, что код в обоих случаях отличается только ключевым словом PASCAL вместо С, а в остальных он идентичен. Однако, код, фактически генерируемый ассемблером, соответствует исходным примерам. Полное описание этих новых средств, учитывающих конкретные языки при смешанномпрограммировании, см. в руководствах по Turbo Assembler.

Как и обычные процедуры и функции С, подпрограммы на языке ассемблера типа external должны соблюдать определенные правила программирования, чтобы с ними могла правильно работать программа управления оверлеями.

Если подпрограмма на языке ассемблера выполняет вызов любой оверлейной процедуры или функции, то эта подпрограмма должна быть дальней (far) и устанавливать стековый фрейм, используя для этого регистр BP. Более подробную информацию см. на стр.217 оригинала.

Соглашения о регистрах

В min было использовано несколько регистров (BP, SP, AX,BX, CX); было ли это использование безопасным? Как обстоит дело с регистрами, которые может использовать ваша программа на Turbo C++?

Оказывается, данная функция была написана верно. Изо всех используемых в ней регистров единственный регистр, окотором вы должны были специально позаботиться, это BP, и при входе в функцию вы сохраняли его в стеке, восстанавливая затем при выходе.

Два остальных регистра, на которые также следует обращать внимание, это SI и DI; Turbo C++ использует эти два регистрадля любыхрегистровых переменных. Есливы используете их в вашей ассемблерной подпрограмме, то при входе в нее следует сохранить эти регистры(возможно, в стеке),и затем восстановить их при выходе. Однако, при компиляции программы Turbo C++ сопцией-r(или при выключенной опцииRegister Variables диалогового поля Code Generation) вы можете не беспокоиться о сохранении SI и DI.

Примечание

При использовании опции -r- следует принимать меры предосторожности. См. Главу4, "Компилятор командной строки" в Руководстве пользователя, где данная опция описана подробно.

Регистры CS, DS, SS и ESпринимают конкретные значения, в зависимости от используемоймоделипамяти. Ниже приводится эта взаимозависимость:

Характеристики

Тип файла
Документ
Размер
2,71 Mb
Тип материала
Учебное заведение
Неизвестно

Список файлов реферата

Свежие статьи
Популярно сейчас
Почему делать на заказ в разы дороже, чем купить готовую учебную работу на СтудИзбе? Наши учебные работы продаются каждый год, тогда как большинство заказов выполняются с нуля. Найдите подходящий учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6518
Авторов
на СтудИзбе
302
Средний доход
с одного платного файла
Обучение Подробнее