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

Системное программное обеспечение
Лекция № 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