74
12.3. Връзка с подпрограми на асемблер
използва UniPascal, т.е. трябва да бъде с наредба на байтовете младши-старши (на върха
на стека е младшият, а под него старшият байт), освен ако се връща указател. Освен
това размерът на резултата трябва да бъде кратен на дума, т.е. ако се връща байт
трябва да бъде върната дума със старши байт 0 (или $FF, ако е отрицателна стойност).
Всеки параметър също се предава съобразно представянето на данните в
UniPascal. Най-младшият байт е на върха на стека, а по-старшите байтове са под него.
Независимо от типа на параметъра той се предава с дължина, кратна на дума. Това
означава, че ако се очаква параметър байт, то неговата стойност е на върха на стека, а
намиращият се под него старши байт на думата може да бъде игнориран. Освен това,
всеки параметър в зависимост от типа и вида си се предава в съответствие със следните
правила:
Ако параметърът се предава по стойност (или ако е параметър-константа), то:
*
всички параметри с големина до две думи (4 байта) се предават директно
в стека;
*
за всички останали се предава адрес. Модифицирането на стойността е
нежелателно.
Ако параметърът се предава по адрес (VAR параметри), то на върха на стека се
предава адресът на параметъра.
Параметрите от тип STRING се предават по специален начин:
*
VAR параметри от тип STRING без описател за дължина се предават по
следния начин: в стека се предава адресът на променливата и след него
(т.е. отгоре - на върха на стека) се намира спецификаторът за дължина на
фактическия параметър. Пример: procedure MyASM(var s: string); се
активира чрез оператора MyASM(sss); където var sss: string[77]; тогава в
стека над адреса на променливата се намира дума със съдържание 77;
*
VAR параметри от тип STRING с описател за дължина, се предават по
нормалния (както за другите типове) начин;
*
CONST параметри от тип STRING (със или без описател за дължина). За
тези параметри се предава адресът на параметъра. Ако фактическият
параметър е от тип CHAR, компилаторът е генерирал код за даване на
стойността на вътрешна променлива от тип STRING[1], така че да бъде
предаден адрес на променлива от тип STRING, а не от тип CHAR;
*
Параметри-значения от STRING (със или без описател за дължина) се
предават, както CONST параметрите, т.е. предава се адреса им. Ако
фактическият параметър е от тип CHAR се предава съдържанието му като
адрес (т.е. първо старшия после младшия), чийто младши байт е нейният
ASCII код, а старшият байт е 0. Адресите, чийто първи байт е нула, са
адреси на клетки от нулевата страница, а тя не се използва за разполагане
на променливи в нея. По този начин, ако вашата процедура получи нормален
адрес, тя може спокойно да го обработи, а ако получи адрес, чийто старши
байт е 0, то това означава, че е бил предаден фактически параметър от
тип CHAR и стойността му се намира в младшия байт. Вие винаги трябва да
предполагате, че параметърът може да бъде от тип CHAR. Ако ви е
неудобно да обработвате такива параметри, опишете ги като CONST, тогава
подпрограмата ви на асемблер ще се опрости за сметка на увеличаване на
кода, генериран за UniPascal програмата (с 3 байта на всеки предаден
фактически параметър от тип CHAR).
<<  <  GO  >  >>

Вернуться к началу сайта