ЛР2 > Основи програмування мовою асемблер процесора TMS320C55х
Статьи по теме
- ЛР4 > Реалізація дискретного перетворення Фур’є на процесорі С55х
- ЛР3(а) > Робота цифрового сигнального процесору з даними у форматі з фіксованою точкою: квантування даних
- ЛР3(б) > Робота ЦСП з даними у форматі з фіксованою точкою: переповнення, насичення акумулятора, квантування коефіцієнтів
- ЛР1(в) > Використання Code Composer Studio: Підключення файлів вводу/виводу, Мова GEL
- ЛР1(б) > Використання Code Composer Studio: Відладка програми
- ЛР1(а) > Використання Code Composer Studio: Створення програми та підключення плати TMS320VC5510DSK
Тема: Створення програм для процесора TMS320C55х. Сумісне програмування на С та асемблер, способи адресації.
Завдання, які виконуються у даній роботі, допоможуть зрозуміти використання різних способів адресації процесора TMS320C55х при написанні програм мовою асемблер. Також зрозуміти, яким чином відбувається узгодження програм, написаних мовою С та асемблеру, в межах одного проекту.
Завдання А
Узгодження програм, написаних мовою С та асемблер
У цьому завданні вивчається підпрограма, написана мовою асемблер, та виклик її програмою, написаною мовою С. Наведений нижче приклад ілюструє функцію main, що застосовується у програмі написаною мовою С, яка викликає підпрограму sum, написану мовою асемблер, для здійснення операції складання і повернення результату до головної функції. Нижче наведений текст програми expA.c, написаної мовою С:
extern int sum(int *); /* Assembly routine */
int x[2]={0×1234,0×4321}; /* define x1[ ] as global array */
int s; /* define result s as global variable */
void main()
{
s = sum (x); /* return sum product */
}
Текст підпрограми sum.asm, написаної мовою асемблер, наведено нижче:
.global _sum
_sum
mov *AR0+,AC0 ;AC0 = x[1]
add *AR0+,AC0 ;AC0 = x[1]+x[2]
mov AC0,T0 ;Return value to TO
ret ;Return to calling function
.end
Мітка _sum визначає початок виконання або місце старту підпрограми, написаної мовою асемблер. Директива .global означає, що підпрограма _sum є глобальною функцію.
Виконайте наступні дії для виконання завдання А:
1. Створіть новий проект у середовищі CCS; назвіть його expA та збережіть його у відповідній директорії.
2. Напишіть програму expA.с на основі наведеного вище коду та збережіть її у відповідній директорії.
3. Напишіть підпрограму sum.asm на основі наведеного вище коду та збережіть її у відповідній директорії.
4. Скопіюйте командний файл лінкера exp.cmd з попередньої лабораторної роботи, та збережіть його у відповідній директорії. Додайте всі три файли до проекту.
5. Підключить бібліотеку засобів динамічної підтримки rst55.lib (розташована у директорії C:\ti\c5500\cgtools\lib).
6. Запустіть програму на компіляцію. Якщо компіляція виконалась без помилок, завантажте файл expA.out до процесора. Виконайте команду Debug→Go Main.
7. Відкрийте вікно перегляду регістрів процесору. Відкрийте вікно перегляду значень у пам’яті даних, вкажіть у полі адреса змінну ‘x’. Розпочніть виконання програми у покроковому режимі. Спостерігайте та записуйте зміни значень в регістрах AC0, AR0, та T0. Спостерігайте за змінами даних у комірці пам’яті ‘s’ та зверніть увагу на час зміни вмісту результату ‘s’. Поясніть алгоритм роботи програми.
8. За допомогою команди View→Mixed Source/ASM перейдіть до режиму одночасного перегляду кодів на мові С та асемблер. Перевірте асемблерний код, згенерований компілятором середовища CCS. Яким чином значення, що повертається з підпрограми, потрапляє до головної функції, написаної мовою С?
Завдання Б
Перевірка різних способів адресації процесора
Процесор С55х підтримує чотири різних способа адресації. У другій частині завдання розглядаються підпрограми на мові асемблер, що використовують різні методи адресації. Всі підпрограми у цьому завданні викликаються головною функцією, написаною мовою С.
1. Створіть новий проект у середовищі CCS; назвіть його expВ та збережіть його у відповідній директорії.
2. Напишіть програму expВ.с на основі наведеного нижче коду та збережіть її у відповідній директорії:
extern void expb_1(void);
extern void expb_2(void);
extern int expb_3(int *, int *);
extern int expb_4(int *, int *);
int Ai[8];
int Xi[8];
int result1,result2;
void main()
{
expb_1();
expb_2();
result1= expb_3(Ai, Xi);
result2 = expb_4(Ai, Xi);
}
3. Напишіть підпрограму expB_1.asm мовою асемблер, використовуючи абсолютну адресацію для ініціалізації масиву Ai[8]={1, 2, 3, 4, 5, 6, 7, 8} у пам’яті даних таким чином, як це показано у наведеному нижче прикладі:
.def _expb_1
.ref _Ai
.text
_expb_1
;
; (1) Absolute addressing
;
mov #1,*(_Ai) ; Absolute addressing mode
mov #2,*(_Ai+1) ; Initialize Ai[8]={1,2,3,4,5,6,7,8}
mov #3,*(_Ai+2)
mov #4,*(_Ai+3)
mov #5,*(_Ai+4)
mov #6,*(_Ai+5)
mov #7,*(_Ai+6)
mov #8,*(_Ai+7)
ret
.end
Коли масив Ai[8] оголошується у головній функції на мові С, то підпрограми на мові асемблер звертаються до нього, використовуючи директиви .global ( або .ref).
4. Напишіть підпрограму expB_2.asm, що використовує метод безпосередньої адресації для ініціалізації масиву Х[8]={9, 3, 2, 0, 1, 9, 7, 1} у пам’яті даних. Для безпосередньої адресації використовується регістр-вказівник сторінки пам’яті даних ХDP. Значення до вказівника сторінки пам’яті даних XDP повинно бути завантажено до того, як починається використання безпосередньої адресації. Масив Хі ініціалізується за допомогою наступної підпрограми, написаної мовою асемблер:
.def _expb_2
.ref _Xi
.text
_expb_2
;
; Direct addressing
;
btstclr #14,*(ST1),TC1 ; Turn off CPL bits for direct addressing mode
amov #_Xi,XDP ; Load direct addressing data-page pointer
.dp _Xi
mov #9,@_Xi ; Direct addressing mode
mov #3,@_Xi+1 ; Initialize Xi[8]={9,3,2,0,1,9,7,1}
mov #2,@_Xi+2
mov #0,@_Xi+3
mov #1,@_Xi+4
mov #9,@_Xi+5
mov #7,@_Xi+6
mov #1,@_Xi+7
xcc continue,TC1
bset CPL ; Turn CPL bit back on
continue
ret
.end
Оператор btstclr #14,*(ST1),TC1 перевіряє біт CPL (біт 14) регістру стану ST1. Значення цього біту збережеться у регістрі TC1, а сам біт CPL буде очищений. Це необхідно для використання регістру DP замість регістру вказівника стеку SP у методі безпосередньої адресації. У кінці підпрограми, оператор умовного переходу xcc continue,TC1 використовується для встановлення попереднього значення біту CPL з регістру TC1.
5. Операція додавання результатів множення (точкове множення) – одна з найбільш використовуваних функцій у системах цифрової обробки сигналів. Точкове множення двох векторів довжиною L може бути представлено так:
,
де вектори Ai та Xi – одновимірні масиви довжиною L. Є багато способів звернення до елементів масивів, такі як прямий, непрямий та спосіб абсолютної адресації. В даному завданні буде розроблена підпрограма expB_3.asm для виконання точкового множення використовуючи спосіб непрямої адресації. Повернене значення змінної result1 повинно зберегтись у пам’яті даних. Напишіть підпрограму expB_3.asm, текст якої наведений нижче:
.def _expb_3
.text
_expb_3
;
; Indirect addressing
;
mpym *AR0+,*AR1+,AC0
add AC1,AC0
mpym *AR0+,*AR1+,AC1
add AC1,AC0
mpym *AR0+,*AR1+,AC1
add AC1,AC0
mpym *AR0+,*AR1+,AC1
add AC1,AC0
mpym *AR0+,*AR1+,AC1
add AC1,AC0
mpym *AR0+,*AR1+,AC1
add AC1,AC0
mpym *AR0+,*AR1+,AC1
add AC1,AC0
mpym *AR0+,*AR1+,AC1
add AC1,AC0
mov AC0,T0
ret
.end
В даній підпрограмі використовуються масиви Аі та Хі, що визначені як глобальні у головній програмі expВ.c. Масиви Аі та Хі мають ті самі значення даних, що наведені раніше. Повернене значення надходить до головної функції через регістр T0.
6. Напишіть підпрограму expB_4.asm, яка також виконує операцію точкового множення двох векторів. В цій підпрограмі використовується спосіб непрямої адресації разом з оператором повтору у паралельному режимі роботи. Такий підхід дозволяє збільшити оптимальність коду та його ефективність. Нижче наведен приклад коду підпрограми:
.def _expb_4
.text
_expb_4
;
; Indirect addressing with paralle processing
;
mpym *AR0+,*AR1+,AC0
|| rpt #6
macm *AR0+,*AR1+,AC0
mov AC0,T0
ret
.end
Допоміжні регістри AR0 та AR1 використовуються як вказівники адресу масиву Аі та масиву Хі відповідно. Команда macm виконує операцію одночасного множення та додавання. Паралельні лінії || вказують на паралельне виконання двох операцій. Команда повторення rpt #K – означає повтор даної операції К+1 раз.
7. Скопіюйте командний файл лінкера exp.cmd з попередньої лабораторної роботи, та збережіть його у відповідній директорії. Додайте всі файли до проекту. Підключить бібліотеку засобів динамічної підтримки rst55.lib (розташована у директорії C:\ti\c5500\cgtools\lib). В рядку Map Filename (-m) вкажіть ім’я файлу перегляду карти пам’яті expB.map. Скомпілюйте проект.
8. Завантажте програму до процесора. Відкрийте вікно перегляду змісту пам’яті даних для перегляду масивів Аі та Хі. Для цього в полі адресу пам’яті вкажіть ім’я масиву Аі.
9. Відкрийте вікно перегляду змісту регістрів процесора. Виконайте команду Debug → Go Main. Виконуючи програму в покроковому режимі, спостерігайте за зміною значень в регістрах АС0, АС1, XAR0, XAR1, T0 та пам’яті даних. Поясніть хід виконання програми.
10. Відкрийте файл карти пам’яті expB.map, та порівняйте розмір кодів підпрограм expB_3.asm та expB_4.asm, написаних мовою асемблер. Зазначимо, що розмір програм наведений у байтах.
Завдання для самостійної роботи
Створіть свої програми поелементного складання та віднімання двох масивів з використанням різних способів адресації.