Согласование вызовов.
Согласование вызовов.
Согласование параметров,
Согласование имен,
В ОС MS DOS вызываемая процедура могла находиться:
1) в том же сегменте, что и команда вызова, тогда вызов называется близким (NEAR) или внутрисегментным. Адрес возврата состоит из 2 байт;
2) в другом сегменте, тогда вызов назывался дальним (FAR) или межсегментным. Адрес возврата состоит из 4 байт.
Возврат из процедуры мог быть либо:
1) близким (RETN), адрес возврата формировался на основе двух байт, взятых из стека;
2) дальним (RETF), адрес формировался на основе четырех байт, взятых из стека.
Вызов и возврат должны быть согласованы друг с другом. В рамках единой программы это не вызывает больших проблем. Но при работе с двумя модулями могут возникнуть трудности.
Например: если в объектном модуле возврат осуществляется по RETN, то необходимо компоновать объектные модули так, чтобы сегмент, где находится процедура, был объединен с сегментом, откуда осуществляется вызов. Вызов в этом случае должен быть близким.
|
|
Если же возврат из процедуры осуществлялся по команде RETF, то и вызов этой процедуры должен быть дальним. При этом при компоновке вызов и сама процедура должны были попасть в разные сегменты.
С этим были связаны и так называемые модели памяти в языке Си.
При переходе к Windows (плоская модель памяти) все вызовы по типу являются близкими, т.е. осуществляющимися в рамках одного огромного сегмента. Тем самым была снята проблема согласования вызовов.
1) Транслятор MASM добавляет в конце имени процедуры @N, где N количество передаваемых в стек параметров. То же делает и компилятор Visual C++. Т.о. трудности возникают уже при согласовании двух ассемблерных модулей. ТASM является более гибким компилятором, так как в конце любого имени можно добавить @N, тем самым согласовав имена.
2) Подчеркивание перед именем. Транслятор MASM генерирует подчеркивание автоматически, если в начале программы устанавливается тип вызова stdcall (Standard Call, т.е. стандартный вызов). Транслятор TASM этого не делает, то есть, при необходимости это нужно делать в тексте программы, что является положительным моментом. Между фирмами Borland и Microsoft в этом вопросе полное разночтение.
4) Согласование заглавных и прописных букв. При трансляции с помощью TASM мы используем ключ /ml для того, чтобы различать буквы прописные и заглавные. Транслятор MASM делает это автоматически. В стандарте языка Си с самого начала предполагалось различие между заглавными и прописными буквами. В Паскале же прописные и заглавные буквы не различаются.
5) Уточняющие имена в Си++. В Си++ возможна так называемая перегрузка. Это значит, что одно и тоже имя может относиться к разным функциям. В тексте программы эти функции отличаются друг от друга по количеству и типу параметров и типу возвращаемого значения. Поэтому компилятор Си++ автоматически делает в конце имени добавку - так, чтобы разные по смыслу функции различались при компоновке. Фирмы Borland и Microsoft тут не пожелали согласовать свои позиции и делают в конце имени совершенно разные добавки. Обойти эту проблему не так сложно, нужно использовать модификатор EXTERN "С".
|
|