Материал взят из демонстрационной версии компилятора 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 b
Idd r27,у+2;R27=MSB b
add r30,r26;(R31,R30)=a+b
adc r31,r27
Id r26,у;R26=c
clr r27; Преобразование с типа unsigned char в тип int
add r30,r26; (R31,R30)=(R31,R30)+C
adc 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 следующим образом:
Текст программы: