Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции / Лекция № 11 Использование ассемблера с языками высокого уровня.ppt
Скачиваний:
8
Добавлен:
07.08.2024
Размер:
346.11 Кб
Скачать

Системное программное обеспечение

Лекция № 11 «Использование ассемблера с языками высокого уровня»

Использование ассемблера с языками высокого уровня

Необходимость­ использования ассемблера в языках высокого уровня возникает, когда требуется:

реализовать какой-то специальный алгоритм, который требует нетривиальной­ обработки данных и который трудно создать средствами языка высокого­ уровня

обеспечить высокое быстродействие какого-либо алгоритма обработки данных­ или фрагмента программы

обеспечить минимизацию используемой памяти

обеспечить доступ к аппаратуре

Cпециалист по программированию на любом языке программирования должен обязательно владеть ассемблером как

вторым инструментом.

Использование ассемблера с языками высокого уровня

Cтыковка ассемблера с языками высокого уровня состоит в:

1)Cогласовании моделей памяти

2)Cогласовании передачи параметров процедурам

3)Cогласовании имен идентификаторов

Согласование моделей памяти. При стыковке необходимо учитывать используемые модели памяти. От этого будет зависеть тип применяемых­ сегментов (16- или 32-разрядные) и ссылок на имена переменных и процедур: ближние (если ссылка выполняется в пределах одного сегмента) или дальние (если ссылка выполняется на объект, расположенный в другом сегменте). При переходе к Windows эту проблему можно исключить, так здесь используется плоская модель памяти. Соответственно, все вызовы по типу являются близкими, т.е. осуществляющимися в рамках одного огромного сегмента.

Использование ассемблера с языками высокого уровня

Cогласование передачи параметров процедурам.

Большинство языков высокого уровня передают параметры вызываемой процедуре в стеке и ожидают возвращения параметров в регистре АХ (ЕАХ) (иногда используется DX:AX (EDX:EAX), если результат не умещается в одном регистре, и ST(0), если результат число с плавающей запятой).

Основными конвенциями передачи параметров процедурам являются следующие:

1.Конвенция Pascal

Самый очевидный способ вызова процедуры или функции языка высокого уровня, после того как решено, что параметры передаются в стеке и возвращаются в регистре АХ/ЕАХ, просто поместить параметры в стек в естественном порядке.

Использование ассемблера с языками высокого уровня

Это способ, принятый в языке PASCAL (а также в BASIC, FORTRAN, ADA, OBERON, MODULA2). В этом случае запись

some_proc(a,b,c,d,e)

превращается в

push a push b push с push d push e

call some_proc

Это значит, что процедура some_proc, во-первых, должна в конце очистить стек (например, командой ret 10) и, во-вторых, параметры, переданные ей, находятся в стеке в обратном порядке:

Использование ассемблера с языками высокого уровня

some_proc

proc

 

 

 

push

bp

 

 

mov

bp,sp

; создать стековый кадр

a

equ

[bp+12]

; определения параметров

b

equ

[bp+10]

 

c

equ

[bp+8]

 

d

equ

[bp+6]

 

e

equ

[bp+4]

 

; текст процедуры, использующей параметры а, Ь, с, d, e

 

ret

10

 

some_proc

endp

 

 

Этот код в точности соответствует усложненной форме

директивы

proc,

которую

поддерживают все современные

ассемблеры:

some_proc proc

PASCAL,а:word,b:word,с:word,d:word,e:word

;текст процедуры, использующей параметры а, Ь, с, d, e.

;Так как ВР используется в качестве указателя стекового кадра,

;его использовать нельзя!

 

ret

; эта команда RET будет заменена на RET 10

some_proc

endp

 

Использование ассемблера с языками высокого уровня

Главный недостаток этого подхода — сложность создания функции с изменяемым числом параметров, аналогичных функции языка С printf. Чтобы определить число параметров, переданных printf, процедура должна сначала прочитать первый параметр, но она не знает его расположения в стеке.

Эту проблему решает подход, используемый в С, где параметры передаются в обратном порядке.

2.Конвенция C

Этот способ передачи параметров используется в первую очередь в языках С и C++, а также в PROLOG и других. Параметры помещаются в стек в обратном порядке, и, в противоположность PASCAL-конвенции, удаление параметров из стека выполняет вызывающая процедура.

Использование ассемблера с языками высокого уровня

Запись some_proc(a,b,c,d,e)

превращается в

 

 

 

 

 

push

e

 

 

 

 

push

d

 

 

 

 

push

с

 

 

 

 

push

b

 

 

 

 

push

a

 

 

 

 

call

some_proc

 

 

 

add

sp,10

; освободить стек

 

Вызванная

таким

образом

процедура

может

инициализироваться так:

Использование ассемблера с языками высокого уровня

some_proc proc push bp

mov bp,sp ; создать стековый кадр

a equ [bp+4] ; определения параметров b equ [bp+6]

с equ [bp+8] d equ [bp+10] e equ [bp+12]

; текст процедуры, использующей параметры a, b, с, d, e pop bp

ret some_proc endp

Ассемблеры поддерживают и такой формат вызова при

помощи усложненной формы директивы proc с указанием языка С:

Использование ассемблера с языками высокого уровня

some_proc proc

С,а:word,b:word,с:word,d:word,e:word

;текст процедуры, использующей параметры a, b, с, d, e.

;Так как BP применяется как указатель стекового кадра,

;его использовать нельзя!

ret some_proc endp

Преимущество по сравнению с PASCAL-конвенцией заключается в том, что освобождение стека от параметров в С возлагается на вызывающую процедуру, что позволяет лучше оптимизировать код программы. Например, если нужно вызвать несколько функций, принимающих одни и те же параметры подряд,

можно не заполнять стек каждый раз заново:

push param2 push param1 call proc1 call proc2 add sp,4