Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Паскаль / tp3 / tp3 / 17.doc
Скачиваний:
17
Добавлен:
10.12.2013
Размер:
112.64 Кб
Скачать

X1, y1, x2, y2: integer;

procedure Init(XA, YA, XB, YB: integer);

procedure Union(var R: Rect);

function Contains(X, Y: integer): boolean;

end;

Rect представляет собой прямоугольник, ограниченный четырьмя координатами X1, Y1, X2 и Y2. Левый верхний угол прямоугольника определяется X1 и Y1, а правый нижний - координатами X2 и Y2. Метод Init присваивает значения координатам прямоугольника. Метод Union вычисляет наименьший прямоугольник, который содержит как сам прямоугольник, так и некоторый другой прямоугольник. Contains возвращает True, если данная точка лежит внутри прямоугольника, и False, если вне его. Другие методы, такие как перемещение, изменение размеров, вычисление точек пересечений и проверка на равенство, могут быть легко дописаны, чтобы сделать Rect более полезным объектом.

Реализация методов объекта Rect на Паскале приводит только заголовки методов, за каждым из которых следует зарезервированное слово external.

{$L RECT}

procedure Rect.Init(XA,YA, XB, YB: integer); external;

procedure Rect.Union(var R: Rect); external;

function Rect.Contains(X, Y: integer): boolean; external;

Разумеется, не существует никаких требований, чтобы методы были реализованы как внешние. Каждый отдельный метод может быть реализован как на Паскале, так и на Ассемблере, в зависимости от желания.

Исходный файл на языке Ассемблера RECT.ASM, который реализует три внешних метода, приводится ниже:

TITLE Rect

LOCALS@@

; структура Rect

Rect STRUCT

X1 DW ?

Y1 DW ?

X2 DW ?

Y2 DW ?

Rect ENDS

code SEGMENT BYTE PUBLIC

ASSUME cs:code

; процедура Rect.Init(XA, YA, XB, YB: Integer);

PUBLIC Rect@Init

Rect@Init PROC FAR

@XA EQU (WORD PTR [bp + 16])

@YA EQU (WORD PTR [bp + 14])

@XB EQU (WORD PTR [bp + 12])

@YB EQU (WORD PTR [bp + 10])

@Self EQU (DWORD PTR [bp + 6])

push bp ; сохранить bp

mov bp, sp ; установить границу стека

les di, @Self; загрузить Self d ES:DI

cld ; продвинуться вперед

mov ax, @XA;X1 := XA

stosw

mov ax, @YA;Y1 := YA

stosw

mov ax, @XB;X2 := XB

stosw

mov ax, @YB;Y2 := YB

stosw

pop bp ; восстановить BP

ret12 ; излечь параметры и выполнить возврат

Rect@Init ENDP

; Процедура Rect.Union (var R: Rect)

PUBLIC Rect@Union

Rect@Union PROC FAR

@R EQU (DWORD PTR [bp + 10])

@Self EQU (DWORDPTR [bp + 6])

push bp ; сохранить bp

mov bp, sp ; установить границу стека

push ds ; сохранить ds

lds si, @R ; загрузить R в DS:SI

les di, @Self ; загрузить Self в ES:DI

cld ; продвинуться вперед

lodsw ; если R.X1 >= X1, перейти к @@1

scasw

jge @@1

dec di ; X1 := R.X1

dec di

stosw

@@1: lod sw ; если R.Y1 >= Y1, перейти к @@2

scasw

jge @@2

decdi;Y1 := R.Y1

decdi

stos

@@2: lod sw ; если R.X2 <= X2, перейти к @@3

scasw

jle @@3

decdi ; X2 := R.X2

decdi

stosw

@@3: lodsw ; если R.Y2 <= Y2, перейти к @@4

scasw

jle @@4

decdi ; Y2 := R.Y2

decdi

stosw

@@4: popds ; восстановить ds

pop bp ; восстановить bp

ret8 ; извлечь параметры и выполнить возврат

Rect@Union ENDP

; функция Rect.Contains(X, Y: integer): boolean

PUBLIC Rect@Contains

Rect@Contains PROC FAR

@X EQU (WORD PTR [bp + 12])

@Y EQU (WORD PTR [bp + 10])

@Self EQU (DWORD PTR [bp + 6])

push bp ; сохранить bp

mov bp, sp ; установить границу стека

les di, @Self ; загрузить Self в ES:DI

mov al, 0 ; возвратить false

mov dx, @X ; если (X < X1) or (X > X2) - перейти

; на @@1

cmp dx, es:[di].X1

jl @@1

cmp dx, es:[di].X2

jg @@1

mov dx, @Y ; если (Y < Y1) or (Y > Y2) - на @@1

cmp dx, es:[di].Y1

jl @@1

cmp dx, es:[di].Y2

jg @@1

Соседние файлы в папке tp3