Определение физического адреса.




 

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

В макросредствах широко применяются два вида директив (повторения и условные директивы).

 



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2016-02-16 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: