LE A A X , © R e su lt
MOV w o rd p t r M y R e s u lt, AX
MOV A X , SS
MOV w o rd p t r M y R e su lt+ 2 , AX
end;
M y R e s u ltA := 1 0 ;
M y R e s u ltA : = M y R e su lt* + 50;
end;
Идентификатор
M y R e s u lt
я применил для наглядности, хотя для
большего удобства следует использовать просто идентификатор
R e-
s u lt ,
не путать со стандартным
© R esu lt.
Следует отметить ряд ограничений. В выражениях asm-операто-
ра недопустимо использовать следующие конструкции языка Turbo
Pascal:
а) стандортные
функции и
процедуры, токие как
W r it e ln , e h r,
б) специальные массивы Mem, MemW, MemL, P o r t , Po rtw ;
в) константы строковых, вещественных и множественных типов;
г) inline-подпрограммы;
д) нелокальные метки;
е) специальный идентификатор
© R esult
за пределами тела функции.
Помимо osm-операторов Turbo Pascal позволяет создавать под-
программы полностью на языке оссемблера. Для этого достаточно за-
головок подпрограммы завершить служебным словом
assembler,
а
тело подпрограммы должно быть оформлено в виде единственного
asm-оператора без
Begin. .End.
При этом, если такая подпрограм-
ма не имеет входных пораметров и локальных переменных, то компи-
лятор не отводит память в стеке и код для этого не формирует. К то-
му же ассемблерные функции возвращают результат в регистрах про-
цессора и, таким образом, эффективность кода за счеттоких ассемб-
лерных подпрограмм увеличивается. Ток, функции 8-битных типов
(Byte,
Shortint,
C h a r,
Boolean
и перечислимые) должны возвращать ре-
зультат в регистре
AL.
Функции 16-битных типов
(integer, word)
долж-
ны возвращать результат в регистре
а х .
Функции 32-битных типов
(Longint, Pointer)
должны возвращать результат в регистровой па-
ре
DX:AX,
іде
d x
— старшее слово,
а х
— младшее слово. Функции
вещественного типо
Real
должны возврощать результат в регистрах
DX:BX:AX
Функции, использующие обращения к математическому со-
процессору i80x87, с типом результата
Single, Double, Extended,
comp
возвращают его в регистре
ST(0)
сопроцессора. Исключением
являются ассемблерные функции, возвращающие результат строчно-
го типа, так как для результата такой функции резервируется помять
в стеке длиной 256 байт, где первый байт — это длино строки. Сле-
дующая ассемблерная функция переводит значение типа байт в тек-
стовую строку с представлением в шестнадцатеричной системе:
function
B yte T o H e x ( D e c im a l
: byte ) : string; assembler;
const HexTable : strings ('0123456789ABCDEF');
asm
LES D I, © R e su lt
MOV A L , 2 { стр о ка д линой 2 сим вола}
M O VES: [D I] , A L
INC D I
LE A B X , H e x T a b le
INC BX {п р оп ускаем б а й т длины стр о ки }
M O VAL, D e c im a l
S H R A L .4 {берем стар ш и е 4 бита}
XLAT
M OVES: [D I] , A L
INC D I
M O VAL, D e c im a l
A N D A L, $0F { б ер ем
младшие
4 бита}
XLAT
M O VES: [D I] , A L
end;
При компиляции ассемблерных подпрограмм компилятор фор-
мирует код для зогрузки значений фактических параметров в ло-
кальные переменные только для формальных параметров, размер
которых ровен 1, 2 и 4 бойтом (типы
b y t e , s h o r t in t , c h a r ,
b o o le a n , in t e g e r , w o rd , lo n g in t , p o in t e r ,
перечислимые и ог-
раниченные). В случое передочи в кочесгве порометра строки, за-
писи или массива следуе рассматривать данный параметр как
v a r-
пораметр, то
есть
параметр-переменная Так, в функции
G e tL e n g th
из следующего примера, котороя возвращоет длину строки, пора-
метр
S t r
подразумевается как var-параметр.
ty p e T A rr B y te = a r r a y [0 . .6 4 0 0 0 ] o f b y te ;
v a r S : s t r in g ;
S c re e n : AT A rrB y te ;
f u n c t io n G e tL e n g th ( S t r : s t r in g ) :b y te ; a s s e m b le r;
asm
LES D I , S t r
MOV A L , E S : [D I] {длину с т р о к и в р е зу л ь т а т }
end;
p ro c e d u re F a stM o v e ( v a r S r c , D s t; C o u n t : w o rd );
asse m b le r,-
asm
PUSH DS
M O VCX, C o u n t
C M P C X ,0
J Z ©End
L D S S I , S rc
LES D I, D s t
REP MOVSB
©End:
POP DS
end;
b e g in
S : = ' H e l l o ! ';
S c re e n := P t r ( $ 0B 80 0, 0 );
F a stM o v e ( S [ 1 ] , S c re e n * , G e tL e n g th ( S ) );
en d .
Данный пргимер прій выполнении процедуры
F a stM o ve
выводит
строку s но экран. Экран представлен в виде массива screen*,
расположенного в экранной облости видеопамяти. Так кок данноя
процедура получает бестиповые пораметры
S r c
и
D st,
то ссылка
на строку указана как S [i], чтобы вывод строки ночинался с ее
первого символа, а не с символа длины. В процедуре
F a stM o ve
ин-
струкция
r e p m o v s b
эквивалентна строкам:
© Next:
M O VAL, DS: [S I]
M O VES: [D I] , A L
IN C S I
IN C D I
LOOP © Next
Хочу обратить особое внимание на то, что вопреки рекоменда-
циям не изменять значение регистра
d s в
данной процедуре все же
его значение изменяется инструкцией
l d s
s i ,
S rc .
Чтобы такая дерг-
зость с нашей стороны не повлекла за собой сбоев, код процеду-
ры заключен в комбинацию инструкций
p u s h d s .
..p o p d s .
Таким об-
разом, удается восстановить исходное значение регистра
d s ,
рав-
ное истинному номеру сегмента данных.
Если
необходимо экономить стек, то есть другой сп особ восста-
новить значение регистра d s . Д ля этого м ож но в этом ж е примере
убрать команду p u s h d s , а вместо комонды p o p d s поставить инст-
рукции MOV а х , SEG © Data; m o v d s ,a x .
В
последнем сп особе
для
вос-
становления значения регистра d s зсщ ейсгвован регистр а х .
Есть третий способ, он использует стек, но сразу же его вырав-
нивает и не использует других регистров. Для его реализации дос-
таточно в примере убрать команду
p u s h d s ,
а вместо команды
p o p
DS
поставить инструкции
p u s h S e g © D a ta ; P 0 P D S .
При этом долж-
но быть установлена директива компиляции
{$G+}.
Также вопреки рекомендациям не изменять значение регистра
в р
это все-токи можно делать, если необходимо серьезно оптими-
зировать код подпрограммы.
В практике программиста могут возникать случаи, когда некото-
рый код оперирует большим количеством параметров, но при этом
должен выполнять свою роботу весьмо быстро. Параметры, кок пра-
вило, размещаются в помяти (это же переменные). Кождое обра-
щение к помяти занимает уйму врюмени, ток кок вступоет в силу
фактор производительности системной памяти компьютера, а она,
как правило, на порядок медленнее, чем процессор. Даже при но-
личии кэш-памяти может наблюдаться медлительность, так кок один
параметр может быть размещен в начале сегмента данных, другой
в его конце, за пределами кэшируемой страницы. Третий параметр
может быть расположен в стеке, а четвертый и вовсе в видеопамя-
ти. При таком разбросе одресов, вероятнее всего, будут
к.
О кончание на стр. 41
предыдущая страница 39 Мой Компьютер 2005 08 читать онлайн следующая страница 41 Мой Компьютер 2005 08 читать онлайн Домой Выключить/включить текст