Вложенные процедуры и правила области действия
Хотя вы можете вкладывать одну процедуру в другую, все процедуры имеют глобальную область действия, Например:
. . . test1 PROC FAR ; код процедуры CALL test2 ; код процедуры RET test2 PROC NEAR ; код процедуры RET ; ближний возврат test2 ENDP test1 ENDP . . .
В данном примере вне охватывающей процедуры можно вызывать test1 и test2.
Если вы хотите получить локальные подпроцедуры, используйте имя с локальной областью действия, например:
. . . LOCALS test1 PROC FAR ; код процедуры RET @test2 PROC NEAR ; код процедуры RET @test2 ENDP test1 ENDP . . .
Примечание: Директива LOCALS разрешает идентификаторы с локальной областью действия. Подробнее об этом рассказывается тут.
В данном коде в процедуре test1 вы можете обратиться только к процедуре @test2. Фактически, если они не находятся в одной и той же процедуре может существовать несколько процедур с именем @test2. Например, допустимо следующее:
. . . LOCALS test1 PROC FAR MOV si, OFFSET Buffer CALL @test2 RET @test2 PROC NEAR ; некоторый код RET @test2 ENDP
test2 PROC FAR MOV si,OFFSET Buffer2 CALL @test2 RET @test2 PROC NEAR ; некоторый код RET @test2 ENDP test2 ENDP . . .
Следующий код недопустим:
. . . lOCALS test1 PROC FAR MOV si,OFFSET Buffer CALL @test2 RET test1 ENDP
@test2 PROC NEAR ; код процедуры RET @test2 ENDP . . .
так как вызов @test2 задает локальный идентификатор для процедуры test1, а таких идентификаторов не существует.
Описание процедур методов для объектов
При создании процедур методов для объектов применяются некоторые специальные соглашения. Процедуры методов объектов должны иметь возможность должны иметь возможность доступа к объекту, с которым они работают. Таким образом, в качестве параметра процедуры должен использоваться указатель на объект.
Турбо Ассемблер интерпретирует объекты достаточно гибко и позволяет использовать для передачи аргументов процедурам методов разнообразные соглашения. Эти соглашения ограничиваются только необходимостью взаимодействовать с объектами, создаваемыми на языке высокого уровня.
Если вы пишете процедуру метода объекта на самом языке Ассемблера, то может оказаться полезным использование соглашения, по которому аргументы передаются через регистры. В этом случае вам следует написать процедуру метода, воспринимающую указатель на объект в регистре или паре регистров ES:DI).
Если вы пишете процедуру метода, которая использует соглашения по интерфейсу языка высокого уровня, то процедура должна воспринимать указатель объекта в одном из аргументов. Указатель объекта, передаваемый из объектно-ориентированных языков высокого уровня (таких как С++), представляет собой неявный аргумент, помещаемый в начало списка аргументов. Процедура метода, написанная на языке Ассемблера, должна явно включать в список аргументов указатель объекта. В противном случае вы можете получить непредвиденные результаты. Нужно помнить, что в зависимости от того, является ли объект ближним (NEAR) или дальним (FAR), указатель может быть величиной WORD или DWORD.
Когда вы пишете на языке Ассемблера конструктор или деструктор, могут возникнуть другие сложности. Чтобы указать, что конструктор или деструктор должен выполнять определенные действия, С++ использует (при некоторых обстоятельствах) использует другие неявные аргументы.
Примечание: Об используемых в С++ соглашениях по вызову рассказывается в этот.
Конструкторам, написанным на языке Ассемблера, не обязательно требуется передавать указатель на объект. Если объект никогда не распределяется статически, то конструктор объекта всегда будет выделять для объекта память из динамически распределяемой области.
1 2 3 4 5
8 8 8
|