216=1024*64=65536
Размер адресуемой памяти ограничен возможностями адресной шины процессора.
I86/88 – 20 разрядов, тогда адресовать можно 220=(210)2=1 МБ
FFFFF – максимально возможный адрес
Чтобы передать 20-битный адрес, разработчиками было принято решение, что адрес любого сегмента должен начинаться с адреса, кратного 16 (должен быть выровнен на границу параграфа), т.е. в 16-ричном коде адрес сегмента всегда заканчивается на 0.
Связь ассемблера с языками высокого уровня
Существует соглашения для связи ассемблера с каждым из языков. Здесь есть свои особенности.
1. Способ передачи управления (тип вызова). В Pascal, если ассемблеровская процедура описана в основной программе или в implementation, то она вызывается как NEAR; при описании в interface- вызов FAR.
2. Сегментация и модели памяти. Если выбрана модель.LARGE, то стек надо описывать как.FARSTACK и он уже не будет относиться к группе DGROUP.
3. Особенности описания общих и предопределенных переменных. В Pascal ограничений нет, но рекомендуется начинать переменные с заглавной буквы; в С- переменные необходимо начинать с символа подчеркивания “_”
4. Управление регистрами. DS – нужно следить за ним. РОН нужно сохранять или в головной программе или в процедуре на ассемблере.
5. Способы передачи параметров. Как правило параметры передаются через кадр стек, размещение параметров идет в различном порядке.
6. Способ возвращения результата. Возвращение результатов может быть реализована через стек, AX (BYTE, WORD), DX:AX (DWORD), ST(0)- вершина стека x87 (FLOAT).
7. Способ восстановления стека. Pascal – в вызываемой программе, в С – в вызывающей программе (для возможности оптимизации)
8. Способы задания и вызова ассемблерного модуля.
а) Раздельная компиляция. Модули на различных языках компилируются отдельно и в вызывающем модуле указан специальный оператор описания модуля на другом языке и его загрузки в виде объекта файла.
б) Встроенная компиляция. Фрагмент или команда ассемблера указывается как встроенный оператор и сам компилятор вызывает ассемблерные транслятор автоматически.
Связь ASSEMBLER и PASCAL.
Пример1:
Test(i, j, k)- вычисляет f=i+j-k; i, j, kÎZ.
i EQU WORD PTR [bp+8]
j EQU WORD PTR [bp+6]
k EQU WORD PTR [bp+4]
.Model Small
.Code
Public Test
Test Proc
Push bp
mov bp, sp
mov ax, i
add ax, j
sub ax, k
pop bp
ret 6
Test EndP
END
Function Test(i,j,k):Word;
External;
{$L Test.obj}
*******************
F:=Test(i,j,k);
Пример 2:
Декодирование символьной строки, которая расположена в области памяти с меткой Buffer длиной Count; кодирование- сдвиг символов на 1 бит влево.
shifr.asm
Code Segment byte Public
Assume cs:Code
Public Coder, Decoder
Buffer EQU DWORD PTR [bp+8]
Count EQU DWORD PTR [bp+6]
Cur_Byte EQU BYTE PTR es:[di]
;FAR вызов Coder(var Buffer, count: word)
Coder Proc
Push bp
mov bp, sp
mov cx, count
jcxz final
les di, Buffer; загрузка смещения с учетом es
cld; в стороны возрастания адресов
cycle:
moc al, Cur_Byte
rol al,1
stosb; переписывает соответствующий символ назад в строку
loop cycle
final:
pop bp
ret 6
Coder EndP
Decoder Proc
Push bp
mov bp, sp
mov cx, count
jcxz final
les di, Buffer; загрузка смещения с учетом es
cld; в стороны возрастания адресов
cycle:
moc al, Cur_Byte
ror al,1
stosb; переписывает соответствующий символ назад в строку
loop cycle
final:
pop bp
ret 6
Decoder EndP
Code EndS
END
Type TMode=(Coder, Decoder);
var Mode:TMode;
*****************
{$F+}
Procedure Coder (var Buffer, count: word); External;
Procedure Decoder(var Buffer, count: word); External;
{$F-}
{$L shifr.obj}
Begin
Case Mode of
Code: begin
Coder(str1,80);
write(codfile,str1);
end;
Decode: begin
read(codfile,str1);
Decoder(str1,80);
end;
end;
End.
Пример 3: использование встроенного ассемблера
Написать функцию, которая формирует слово, выбираемое по адресу 0040:006ch (BIOS счетчик таймера).
Function Get_Time:Longint;
var time:longunt;
begin
asm
push es
mov ax, 0040h
mov es, ax
mov ax, es:[006ch]
mov time, ax
pop es
end;
Get_Time:=time;
end;
Пример 4:
Использование стандартных функций Паскаля в ассемблерном модуле.
DATA Segment Word Public
EXTERN ch:Byte
DATA ENDS
CODE Segment Byte PUBLIC
ASSUME DS:DATA,CS:CODE
EXTERN Readkey: Far
AsmProc Proc Far
Push bp
mov bp, sp
pusha
Call Readkey
mov ch, al
popa
pop bp
ret 2
AsmProc EndP
CODE ENDS
END
Связь ASSEMBLER и С
Пример1:
Test(i, j, k)- вычисляет f=i+j-k; i, j, kÎZ.
Вызов из С скомпилировался в:
Push WORD PTR DGROUP: _k
Push WORD PTR DGROUP: _j
Push WORD PTR DGROUP: _i
call Near PTR _TEST
этот вызов порождает кадр стека
à | BP |
IP | |
I | |
J | |
K |
.Model Small
.Code
Public _Test
_Test Proc
Push bp
mov bp, sp
mov ax, [bp+4]
add ax, [bp+6]
pop bp
sub ax, [bp+8]
ret
_Test EndP
END
Пример2:
Разработать ассемблерный модуль, который вычисляет
StartVal+Repeat |
S=S i |
i=StartVal |
total.asm
.Model Small
.Data
Extern _Repetitions: word
Public _StartVal DW 0
Total DW?; локальная переменная
.Code
Public _Doloop
_Doloop Proc
mov cx, _Repetitions
mov ax, _StartVal
mov Total, ax
cycle:
inc ax
add Total, ax
Loop cycle
mov ax, Total
ret
_Doloop EndP
END
Call_Tot.c
extern “c” int Doloop(void);
extern int Repetitions,
StartVal;
main(){
Repetitions=10;
StartVal=2;
print(“%d\n”,Doloop());
}
Пример3: на встроенный ассемблер в программе, написанной на С.
Составить встроенную процедуру для заполнения некоторой области памяти размером count байтов заданным символом.
#pragma inline
void memset(void *dest, char val, short count){
asm{
push es
push di
les di, dest
mov cx, count
mov al, val
mov Total, ax
rep stosb
pop di
pop es
}
}
int main(){
char buf[0x20];
memset(buf,0xFF, size of (Buf));
return 0
}
Макросредства
Макросы- это еще один способ однократного описания последовательности действий и затем многократного их выполнения с различными параметрами. Основным отличием от использования процедур заключается в том, что макросы- это директивы ассемблеру (обрабатываются они при помощи препроцессорной обработки).
Достоинства:
- они более универсальны, т.к. позволяют параметрически управлять не только заданием обрабатываемых объектов, но и действиями над этими объектами;
- их использование не связано с выполнением команд CALL и RETURN, поэтому применение макросов ускоряет выполнение программы;
- поскольку описание макросов воспринимается как обычный текст при подстановке, то легко организуются библиотеки макросов.
Недостатки:
- существенное увеличение длины программы, связанное с подстановкой тела макроса во все точки его вызова.
Использование макросов связано с понятиями макроопределение, макровызов, макрорасширение.
Макроопределение- описание действия, выполняющегося макросом применительно к фиксированным параметрам; состоит из заголовка, тела и концовки.
Заголовок: Nam_Macro MACRO [список фиктивных параметров]
Тело: последовательность операторов
Концевик: END [Nam_Macro]
Пример макроопределение установки курсора в левый верхний угол экрана.
Home Macro
mov dh, 0
mov dl, 0
mov al, 2; функция перемещения курсора
int 10h; обработчик управления указателя
ENDM
Пример 2.
Sr_Mov Macro R1,R2
push R1
pop R2
ENDM
Пример3.
Add_W Macro par1, par2, sum
mov ax, par1
add ax, par2
mov sum, ax
ENDM
Макровызов представляет собой директиву ассемблера, помещаемую в текст программы и состоящую из имени макроса и списка фактических параметров, если они требуются. Если список фактических параметров меньше фиктивных, то оставшимся фиктивным параметрам присваиваются нулевые значения. Макрорасширение- это подстановка тела макроса из макроопределения на место макровызова с заменой фиктивных параметров на фактические. Например, макровызов
Sr_Mov ds,es
при макрорасширении будет заменен на
push ds
pop es
Пример некорректного задания параметра.
Time_Msg Macro XXX
TimXXX: db ‘сейчас ХХХ часов$’
ENDM
- параметр макроопределения не может быть частью идентификатора;
- параметр макроопределения непосредственно не может использоваться в строке, т.к. его трудно распознать.
Правильный вариант.
Time_Msg Macro XXX
Tim&XXX: db ‘сейчас &ХХХ& часов$’
ENDM
Если в теле макроса используется метка, то она должна быть объявлена локальной, чтобы исключить многократное объявление имен.
Пример.
Delay Macro count
local cycle
push cx
mov cx, count
cycle: loop cycle
pop cx
ENDM
В макросредствах широко применяются два вида директив (повторения и условные директивы).