Материал взят из демонстрационной версии компилятора CodeVisionAVR С Compiler, автором которого является Pavel Haiduc, HP InfoTech S.R.L.
Текст программы:
// Определение функции на ассемблере. Эта функция возвращает а+Ь+с
#pragma warn-
// Запретить предупрежденияint sum_abc(int a, int b, unsigned char с) {
#asm
ldd r30, у+3
;R30=LSB аIdd r31,у+4
;R31=MSB аIdd r26,у+1
;R26=LSB bIdd r27,у+2
;R27=MSB badd r30,r26
;(R31,R30)=a+badc r31,r27
Id r26,у;R26=c
clr r27
; Преобразование с типа unsigned char в тип intadd r30,r26;
(R31,R30)=(R31,R30)+Cadc r31,r27
#endasm
}
#pragma warn+
// Разрешить предупрежденияvoid main(void) {
int r;
// Теперь вызовем функцию и сохраним результат в r
r=sum_abc(2,4,6);
}
Компилятор передает параметры функции с помощью стека данных. Первым он передаст целый параметр
В случае параметров, состоящих из нескольких байтов, первым передается старший байт. Как вы видите, стек растет вниз. После того как все параметры функции были записаны в стек (pushed), регистр
Параметр
Старший байт был записан в стек первым, поэтому он находится по более высокому адресу.
Параметр а был записан в стек перед
Старший байт был записан в стек первым, поэтому он находится по более высокому адресу.
Функции возвращают свои значения в следующих регистрах:
R30 для типов char & unsigned char;
R30, R31 для типов int & unsigned int;
R30, R31, R22, R23 для типов long & unsigned long.
Поэтому наша функция должна вернуть ее результат в регистрах R30, R31.
После возвращения из функции компилятор автоматически генерирует код, освобождающий стек от параметров функции, поэтому можно не задумываться об этом.
Директива #pragma warn запрещает компилятору генерировать предупреждения о том, что функция не возвращает результат.
Это необходимо, потому что компилятору не известно, что мы делаем в нашей написанной на ассемблере функции.
Материал взят из демонстрационной версии компилятора CodeVisionAVR С Compiler, автором которого является Pavel Haiduc, HP InfoTech S.R.L.
Текст программы:
// Контроллер: AT90S2313
// Модель памяти: TINY
// Размер стека данных: 64 bytes
flash char f[]="This is a test";
#pragma warn-
eeprom char e[16];
#pragma warn+
char r[16];
void main (void)
{
Char flash *ptr_to_flash;
char eeprom *ptr_to_eeprom;
char *ptr_to_ran;
// Копировать строку f из FLASH в
// Строку e в EEPROM
ptr_to_flash=f;
ptr_to_eeprom=e;
while (*ptr_to_flash)
*ptr_to_eeprom++=*ptr_to_flash++;
// Копировать строку e из EEPROM в
// строку г в оперативной памяти
ptr_to_eeprom=e;
ptr_to_ram=r;
while (*ptr_to_eeprom)
*ptr_to_ram++=* ptr_to_eeprom++;
// Стоп (бесконечный цикл)
while (1);
}
Материал взят из демонстрационной версии компилятора CodeVisionAVR С Compiler, автором которого является Pavel Haiduc, HP InfoTech S.R.L.
Рис. 4.11.
Для индикации использован 2х16 алфавитно-цифровой ЖКИ, подсоединенный к порту PORTC следующим образом:
Текст программы: