Міністерство освіти і науки України
Національний університет “Львівська політехніка”
/
Лабораторна робота № 2
Тема:
Змішане програмування на мовах С та Асемблер
Мета: оволодіти навиками створення програм, частини яких написані різними мовами програмування. Засвоїти правила взаємодії між програними модулями.
ТЕОРЕТИЧНІ ВІДОМОСТІ
Труднощі опису зв’язку програм написаних мовою C і асемблерних програм полягає в тому, що різні версії мови C мають різні угоди з виклику функцій та передавання їм параметрів. Для більш точної інформації варто користатися посібником з наявної версії мови C. До особливостей угод щодо виклику функцій та передавання їм параметрів можна віднести:
більшість версій мови C забезпечують передачу параметрів через стек у зворотній (у порівнянні з іншими мовами) послідовності. Зазвичай доступ, наприклад, до двох параметрів, переданих через стек, здійснюється в
такий спосіб:
PUSH EBP
MOV EBP,ESP
MOV EAX,[EBP+8]
MOV EDX,[EBP+12]
; тіло підпрограми ...
POP EBP
RET
у мові C розрізняють великі і малі літери, тому ім’я асемблерного модуля повинне бути представлено в тому ж символьному регістрі, який використовують для посилання C-програми;
у деяких версіях мови C потрібно, щоб асемблерні програми, що змінюють регістри EDI і ESI, записували їхній вміст у стек при вході і відновлювали ці значення зі стеку при виході;
ассемблерні програми повинні повертати значення, якщо це необхідно, у регістрі EAX (подвійне слово) чи в регістровій парі EDX:EAX (8 слів);
для деяких версій мови C, якщо ассемблерна програма встановлює прапор DF, то вона повинна скинути його командою CLD перед поверненням. Щоб скомпонувати разом модулі C++ і Макро асемблера, повинні бути
дотримані наступні три умови:
У модулях Макро Асемблера повинні використовуватися угоди про імена, прийняті в C++.
C++ і Макро Асемблер повинні спільно використовувати відповідні функції й імена змінних у формі, прийнятної для C++.
Для комбінування модулів у виконувану програму потрібно використовувати утіліту-компоновщик (TLINK, LINK тощо).
Підкреслення і мова С
Для забезпечення взаємодії програми написаної асемблером з програмами написаними мовами С чи С++, всі зовнішні мітки повинні починатися із символу підкреслення (_). Компілятор С і С++ вставляє символи підкреслення перед всіма іменами зовнішніх функцій і змінних при трансляції в об’єктний код автоматично, тому в асемблерних програмах перший символ підкреслення необхідно вставити самостійно. Тому, ідентифікатори глобальних змінних та назви функцій які використовуються в асемблерній програмі для взаємодії з С модулями, чи навпаки, повинні починатися із символу підкреслення.
Наприклад, наступна програма мовою С (link2asm.cpp):
extrn int ToggleFlag(); int Flag;
main()
{
ToggleFlag();
}
правильно компонується з наступною програмою на асемблері (casmlink.asm):
.586
.MODEL FLAT
.DATA
EXTRN _Flag:dword
.CODE
PUBLIC _ToggleFlag
_ToggleFlag PROC
; прапорець скинутий?
cmp [_Flag], 0
jz SetFlag
; так, установити його
mov [_Flag], 0
; ні, скинути його
jmp EndToggleFlag
; виконано
SetFlag:
; встановити прапорець
mov [_Flag], 1
EndToggleFlag:
ret
_ToggleFlag ENDP
END
При використанні в директивах EXTERN і PUBLIC специфікатора мови С правильно компонується з наступною програмою на Асемблері (cspec.asm) (приклад для 16-ти бітної програми):
.MODEL Small
.DATA
EXTRN C Flag:word
.CODE
PUBLIC C ToggleFlag
ToggleFlag PROC
; прапорець скинутий?
cmp [Flag], 0
jz SetFlag
; так, установити його
mov [Flag], 0
; ні, скинути його
jmp short EndToggleFlag ; виконано
SetFlag:
; установити прапорець
mov [Flag], 1
EndToggleFlag:
ret
ToggleFlag ENDP
END
Примітка: Мітки, на які відсутні посилання в програмі на С (такі, як SetFlag) не вимагають попередніх символів підкреслення. Турбо Асемблер (...