Использование ассемблера в Дельфи


         

Передача параметров по зничению и ссылке


Имеется огромная разница между передачей параметров по значению и по ссылке (через директиву var). Например, следующее объявление функции:

function MyFunction(I: Integer): Integer; register;

Значение параметра I будет передано через регистр EAX (см. таблицу 2 для обзора, как параметры разного типа передаются в функцию/процедуру). Например, когда I=254, EAX подобен $000000FE. Но следующее объявление:

function MyFunction(var I: Integer): Integer; register;

передаст не значение I (254 в нашем примере), а указатель на местонахождение, где  переменная I записана в памяти (например, $0066F8BC) и этот указатель будет помещен в регистр EAX! При передаче параметра с помощью ключевого слова var, вы всегда передаете 32-битный указатель на переменную (который естественно помещается в регистр соглашения register).

Посмотрим на простой пример: допустим, мы желаем, чтобы наша функция вернула сумму целочисленного числа и 12 (Конечно, это очень бессмысленный пример, он нужен просто для демонстрации), передадим параметр по значению (функция вернет результат в регистре EAX):

function MyFunction(I: Integer): Integer; register;

asm

add EAX,12

end;

В случае же передачи по ссылке, мы должны написать так:

function MyFunction(var I: Integer): Integer; register;

asm

mov EAX,[EAX] {Загрузить значение параметра I через указатель}

add EAX,12

end;

При использовании директивы const правила те же, как для переменных, передаваемых по значению. Например, для объявления:

function MyFunction(const I: Integer): Integer; register;

Регистр EAX будет содержать значение I, а не указатель.

Как мы обсуждали в главе 1.6, длинные строки, динамические массивы, варианты, большие множества и записи возвращаются с помощью дополнительного var параметра. Позже, в других главах, мы обсудим эти типы более детально.



Содержание раздела