ЗМІШАНЕ ПРОГРАМУВАННЯ НА МОВАХ С ТА АСЕМБЛЕР

Інформація про навчальний заклад

ВУЗ:
Національний університет Львівська політехніка
Інститут:
Не вказано
Факультет:
Комп'ютерна інженерія
Кафедра:
Кафедра ЕОМ

Інформація про роботу

Рік:
2011
Тип роботи:
Методичні вказівки до лабораторної роботи
Предмет:
Системне програмування

Частина тексту файла (без зображень, графіків і формул):

Міністерство освіти і науки, молоді та спорту України Національний університет “Львівська політехніка”  Кафедра ЕОМ ЗМІШАНЕ ПРОГРАМУВАННЯ НА МОВАХ С ТА АСЕМБЛЕР Методичні вказівки до лабораторної роботи № 2 з курсу “ Системне програмування ” для студентів базового напряму 6.050102  -  “Комп’ютерна інженерія” Затверджено на засіданні кафедри ”Електронні обчислювальні машини” Протокол №  від року Львів – 2011 Змішане програмування на мовах С та Асемблер: Методичні вказівки до лабораторної роботи № 2 з курсу “ Системне програмування ” для студентів базового напряму 6.050102  -  “Комп’ютерна інженерія” / Укладачі: Мархивка В.С., Олексів М.В., Акимишин О.І., Мороз І.В., – Львів: Національний університет “Львівська політехніка”, 2011, 14  с. Укладачі Мархивка В.С., ст. викл. Олексів М. В., асистент Акимишин О.І., к.т.н., доцент Мороз І.В., ст. викл. Рецензенти Відповідальний за випуск: Мельник А. О., професор, завідувач кафедри Змішане програмування на мовах С та Асемблер Мета: оволодіти навиками створення програм, частини яких написані різними мовами програмування Засвоїти правила взаємодії різних модулів. ТЕОРЕТИЧНІ ВІДОМОСТІ Труднощі опису зв'язку програм мовою 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 Розпізнавання рядкових і прописних символів в ідентифікаторах В іменах ідентифікаторів Макро асемблер звичайно не розрізняє рядкові і прописні букви (верхній і нижній регістр). Оскільки в С++ вони розрізняються, бажано задати таке розходження й у Макро Асемблері (принаймні для тих ідентифікаторів, що спільно використовуються Асемблером і С++). Це можна зробити за допомогою макрокоманди OPTION CASEMAP:NONE. Типи міток Хоча в програмах Асемблера можна вільно звертатися до будь-якої змінної чи даних будь-якого розміру (8, 16, 32 біти і т.д.), у загальному випадку добре звертатися до змінних відповідно до їхніх розмірів. Наприклад, якщо ви записуєте слово в байтову змінну, то звичайно це приводить до проблем: . . . SmallCount DB 0 . . . mov WORD PTR [SmallCount],0ffffh . . . Тому важливо, щоб в операторі Асемблера EXTRN, у якому описуються змінні С++, задавався правильний розмір цих змінних, тому що при генерації розміру доступу до змінного С++ Асемблер ґрунтується саме на цих описах. Якщо в програмі мовою С++ міститься оператор: char c то код Асемблера: . . . EXTRN c:WORD . . . inc c . . . може привести до дуже неприємних помилок, оскільки після того, як у коді мовою С++ змінна c збільшиться чергові 256 разів, її значення буде скинуто, а тому що вона описана, як змінна розміром у слово, то байт за адресою OFFSET c + 1 буде збільшуватися некоректно, що приведе до непередбачених результатів. Узгодження типів (С++ та Assembler) Між типами даних С++ та Макро асемблера існує наступне співвідношення: Тип даних С++ Тип даних Макро Асемблера  unsigned char byte  char byte  enum dword  unsigned short dword  short dword  unsigned int dword  int dword  unsigned long dword  long dword  float dword  double qword  long double tbyte  near* dword   Передача параметрів C++ передає функціям параметри через стек. Перед викликом функції С++ спочатку заносить передані цієї функції параметри, починаючи із самого правого параметра і кінчаючи лівим, у стек. У С++ виклик функції: . . . Test(i, j, 1); . . . компілюється в інструкції: mov eax,1 push eax push dword ptr _j push dword ptr _i call _Test add esp,12 де видно, що правий параметр (значення 1), заноситься в стек першим, потім туди заноситься параметр j і, нарешті, і. При поверненні з функції занесені в стек параметри усе ще знаходяться там, але вони більше не використовуються. Тому безпосередньо після кожного виклику функції C++ налаштовує вказівник стеку назад у відповідності зі значенням, що він мав перед занесенням у стек параметрів (параметри, таким чином, відкидаються). У попередньому прикладі три параметри (по два байти кожен) займають у стеку разом 12 байт, тому C++ додає значення 12 до вказівника стека, щоб відкинути параметри після звертання до функції Test. Важливий момент тут полягає в тому, що відповідно до використовуваних за замовчуванням угод С/C++ за видалення параметрів зі стеку відповідає викликаюча програма. Функції Асемблера можуть звертатися до параметрів, переданих у стеку, щодо регістра EBP. Наприклад, припустимо, що функція Test являє собою наступну функцію на Макро Асемблері (PRMSTACK.ASM): .586 .MODEL FLAT .CODE PUBLIC _Test _Test PROC push ebp mov ebp,esp mov eax,[ebp+8] ; одержати параметр 1 add eax,[ebp+12] ; додати параметр 2 ; до параметра 1 sub eax,[ebp+16] ; відняти від суми 3 pop ebp ret _Test ENDP Функція Test одержує передані з програми мовою С параметри через стек, відносно регістра EBP. (Якщо ви пам’ятаєте, EBP адресується відносно сегмента стека). Але звідки вона знає, де знайти параметри відносно EBP? На рис.1 показано, як виглядає стек перед виконанням першої інструкції у функції Test: i = 25; j = 4; Test(1, j, 1); Рис. 1. Стан стеку перед виконанням першої інструкції функції Test Параметри функції Test являють собою фіксовані адреси відносно ESP, починаючи з комірки, на 4 байти старшої від адреси, за якою зберігається адреса повернення, занесена туди при виклику. Після завантаження регістра EBP значенням ESP ви можете звертатися до параметрів відносно EBP. Однак, ви повинні спочатку зберегти EBP тому, що у викликаючій програмі передбачається, що при поверненні EBP змінений не буде. Занесення в стек EBP змінює всі зміщення в стеку. На рис. 2 показано стан стеку після виконання наступних рядків коду: ... push ebp mov ebp,esp ... Рис.2 Стан стеку після інструкцій PUSH і MOVE Організація передачі параметрів функції через стек і використання його для динамічних локальних змінних - це стандартний прийом для мови С++. Як можна помітити, неважливо, скільки параметрів має програма мовою С++: Самий лівий параметр завжди зберігається в стеку за адресою, що безпосередньо слідує за збереженою у стеку адресою повернення, наступний параметр, що повертається, зберігається безпосередньо після самого лівого параметра і т.д. Оскільки порядок і тип переданих параметрів відомі, їх завжди можна знайти в стеку. Простір для динамічних локальних змінних можна зарезервувати, віднімаючи від ESP необхідну кількість байт. Наприклад, простір для динамічного локального масиву розміром у 100 байт можна зарезервувати, якщо почати функцію Test з інструкцій: . . . push ebp mov ebp,esp sub esp,100 . . . Повернення значень Програми, які викликаються з С++ і написані на Асемблері можуть повертати значення. Значення функцій повертаються в такий спосіб: тип що повертає значения  Де перебуває значення, що повертається   unsigned char  EAX   char  EAX   enum  EAX   unsigned short  EAX   short  EAX   unsigned int  EAX   int  EAX   unsigned long  EAX   long  EAX   float  регістр вершини стека співпроцесора 8087 (ST(0))   double  регістр вершини стека співпроцесора 8087 (ST(0))   long double  регістр вершини стека співпроцесора 8087 (ST(0))   near*  EAX  КОНТРОЛЬНІ ПИТАННЯ 1. Що таке змішане програмування? 2. Яких узгоджень необхідно дотримуватися при змішаному програмуванні на С/Асемблер? 3. Як передаються параметри функціям, що написані на мові С? 4. Як передаються результати з функцій, що написані на мові С? 5. Хто має очищати стек після виклику функції, що написана на мові С? 6. Як передати параметри з Асемблера в функцію, що написана на мові С? 7. Особливості взаємодії С-Асемблер. 8. Особливості взаємодії С-Асемблер-С. ЛІТЕРАТУРА 1. Джордейн Р.Справочник програмиста персональных компъютеров типа ІBM PC XT и AT. - M."Финансы и статистика",1992,стор.13-31. 2.Березко Л.О., Троценко В.В. Особливості програмування в турбо-асемблері. - Київ, НМК ВО, 1992. 3.Дао Л. Программирование микропроцессора 8088.Пер. с англ. -М.: "Мир",1988. 4.Абель П.Язык ассемблера для ІBM PC и программирования. Пер. з англ.-М.,"Высшая школа",1992. ЗАВДАННЯ Створити дві програми. Прша програма реалізує взаємовиклики С – ASM та здійснює обчислення, заданого виразу, згідно варіанту. Програма повинна складатися з кількох модулів, передача параметрів між якими здійснюється через стек. Основний модуль – створюється мовою С. Він повинен забезпечувати: ввід даних з клавіатури; виклик підпрограми обчислення виразу; вивід на екран результату обчислення виразу. Модуль безпосередніх обчислень – здійснює всі обчислення виразу. Створюється мовою Assembler. Друга програма реалізує взаємовиклики С – ASM – С та здійснює обчислення, заданого виразу, згідно варіанту. Програма повинна складатися з кількох модулів, передача параметрів між якими здійснюється через стек. Основний модуль – створюється мовою С. Він повинен забезпечувати: ввід даних з клавіатури; виклик підпрограми обчислення виразу; Модуль безпосередніх обчислень – здійснює всі обчислення і вивід на екран результату обчислення виразу викликом стандартної функції printf() . Створюється мовою Assembler. Відлагодити та протестувати програми. Результати роботи програм продемонструвати викладачу. Скласти звіт про виконану роботу з приведенням тексту програми та коментарів до неї, а також результатів її роботи. Дати відповідь на контрольні запитання. ВАРІАНТИ ЗАВДАНЬ А, В, С, D, E, F - знакові операнди, довжиною в байтах, згідно з індексу, значення К подано у 16-му форматі. № Вираз K  1 X=A2+C1-D2/2+K 1254021  2 X=A4+C2+D1*4-K 202  3 X=K-B2*5+C2-E1 37788663  4 X=A4+C1-D4/5+K 45694  5 X=B4-A2*2-E2+K 505  6 X=K+B2/4-D2*4-E1 6DD02316  7 X=A4/2-4*(D1+E2-K) 717  8 X=A4-B2+K-D2/2+8*B2 88  9 X=4*B2-C2+D4/4 29  10 X=A4-B4/2+K+E2*4 2310  11 X=(A4-B2-K)*2+E4/4 311  12 X=K+B4/2-4*F2-E1 7055E0AC  13 X=A2/2+8*(D1+E2-K) 2513  14 X=A4-B1-K-D2/2+4*B1 614  15 X=A3+(4*C2)-D4/2+K 4569600F  16 X=A4/4+C2-D1*2+K 616  17 X=A4-K+C4/2-E1*8 1017  18 X=4*(B2-C1)+D2/4+K 56987018  19 X=A2*4+C1-D4/2+K 4019  20 X=K+B4/4-D1*2-E2 18932020  21 X=A4/8+2*(D2 – E1+K) 21  22 X=K-B1-C1-D2/2+4*B1 45781022  23 X=A2*8-C1+D4/2+K 7AA02023  24 X=K-B2/2+D3+E2*4 74569024  25 X=(K-B2-C1)*2+E4/42 2B05025  26 X=A2+K+C2/2-E1*8 6C26  27 X=A2*4+(K-E1*4) A77627  28 X=K+B4/2+D2-E2/4 3FF28  29 X=K-B1*4+D2-F2/2 12A0C029  30 X=K+B4-D2/2+E1*4 25630   ПОРЯДОК ВИКОНАННЯ Запустити середовище розробки Microsoft Visual Studio 2005, для чого потрібно виконати: Start-> All programs->Microsoft Visual Studio 2005 -> Microsoft Visual Studio 2005. Створити новий проект: 2.1. В закладці File вибрати New - > Project (Рис. 3).  Рис. 3. Створення нового проекту в середовищі Microsoft Visual Studio 2005. 2.2. Вибрати тип проекту Visual C++ та шаблон Win32 Console Application (Рис. 4) та натиснути кнопку «ОК».  Рис. 4. Вибір типу проекту. У вікні, що з’явиться натиснути кнопку «NEXT» (Рис. 5).  Рис. 5. Інформаційне вікно, що вказує тип вибраного проекту. У додаткових опціях проекту встановити тип «Empty project» (Рис. 6) та натиснути «Finish».  Рис. 6. Встановлення параметрів проекту. У вікні менеджера проекту буде відображатись структура створеного проекту, зображена на рис. 7.  Рис. 7. Менеджер проекту. 3. До створеного проекту додати файли вихідних текстів програми. Для цього потрібн натиснути праву клавішу миші на іконці проекту та у спливаючому вікні вибрати Add -> New Item (Рис. 8). 4. На основі наведених в методичних вказівках кодів програм підготувати два файли з розширеннями .срр та .asm.Для цього можна використати будь-який тексів редактор (наприклад Notepad). Зауваження: створенні файли повинні мати різні імена. 5. Додати створенні файли до проекту Microsoft Visual Studio 2005 так, як наведено на рис. 8-9.  Рис. 8. Додавання існуючих файлів з вихідними кодами. При додавання файлу з розширенням .asm у Microsoft Visual Studio 2005 з’явиться вікно, що дозволяє встановити правила компіляції програм, написаних мовою програмування assembler (Рис. 9). Вибрати єдине доступне правило та натиснути кнопку «ОК».  Рис. 9. Вибір правила компіляції асемблерних файлів. 6. Скомпілювати створений проект, використавши вкладку «build» (рис. 9). 7. Модифікувати тестову програму відповідно до заданого варіанту, скомпілювати та запустити на виконання. Приклад програми з взаємодією C-ASM, що виконує додавання двох цілих чисел main.cpp  calc.asm  #include <stdio.h> extern "C" void calc(void); extern "C" { int A=0; int B=0; int X=0; }; int main() { printf("Please, enter your numbers:\n"); printf("A = "); scanf("%d",&A); printf("B = "); scanf("%d",&B); calc(); printf("X = %d\n",X); return 0; } .386 .model flat,c EXTRN A:SDWORD, B:SDWORD, X:SDWORD .data Afl dd 0 Bfl dd 0 format db "X = %d\n" .code calc PROC mov eax,A mov ebx,B add eax, ebx mov X, eax ret calc ENDP END   НАВЧАЛЬНЕ ВИДАННЯ ЗМІШАНЕ ПРОГРАМУВАННЯ НА МОВАХ С ТА АСЕМБЛЕР МЕТОДИЧНІ ВКАЗІВКИ до лабораторної роботи № 2 з дисципліни “ Системне програмування ” для студентів базового напряму 6.050102 -  “Комп’ютерна інженерія” Укладачі Мархивка В.С., ст. викл. Олексів М. В., асистент Акимишин О.І., к.т.н., доцент Мороз І.В., ст. викл. Редактор Комп’ютерне верстання Здано у видавництво . Підписано до друку Формат 70х100/16. Папір офсетний. Друк на різографі Умовн. друк. арк. Обл..-вид. арк.. Тираж прим. Зам.. Видавництво Національного університету “Львівська політехніка” Реєстраційне свідоцтво ДК №751 від 27.12.2001 р. Поліграфічний центр Видавництва Національного університету “Львівська політехніка” Вул.. Ф. Колесси, 2. Львів, 79000
Антиботан аватар за замовчуванням

20.05.2013 22:05-

Коментарі

Ви не можете залишити коментар. Для цього, будь ласка, увійдіть або зареєструйтесь.

Ділись своїми роботами та отримуй миттєві бонуси!

Маєш корисні навчальні матеріали, які припадають пилом на твоєму комп'ютері? Розрахункові, лабораторні, практичні чи контрольні роботи — завантажуй їх прямо зараз і одразу отримуй бали на свій рахунок! Заархівуй всі файли в один .zip (до 100 МБ) або завантажуй кожен файл окремо. Внесок у спільноту – це легкий спосіб допомогти іншим та отримати додаткові можливості на сайті. Твої старі роботи можуть приносити тобі нові нагороди!
Нічого не вибрано
0%

Оголошення від адміністратора

Антиботан аватар за замовчуванням

Подякувати Студентському архіву довільною сумою

Admin

26.02.2023 12:38

Дякуємо, що користуєтесь нашим архівом!