реклама на сайте
подробности

 
 
> "asm" в WinAVR
Guest_Serg79_*
сообщение Sep 22 2006, 11:42
Сообщение #1





Guests






Требуется написать макрос для загрузки 16-битного значения в регистры r26:r27.
Для 8-битного, проблем нет. Делаю так:
Код
#define load_val(val)         \
    {                           \
        __asm__ __volatile__    \
        (                       \
            "ldi r26,%0 \n\t"   \
            : "M" (val)         \
        );                      \
    }


Думал, что для 16 такое прокатит:
Код
#define load_val(val)         \
    {                           \
        __asm__ __volatile__    \
        (                       \
            "ldi r26,%A0 \n\t"  \
            "ldi r27,%B0 \n\t"  \
            : "M" (val)         \
        );                      \
    }

оказалось ошибаюсь.

Кто знает, подскажите как быть, а то уже крыша начинает съезжать. blink.gif
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 4)
Tiro
сообщение Sep 22 2006, 20:42
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 781
Регистрация: 3-10-04
Из: Санкт-Петербург
Пользователь №: 768



Цитата(Serg79 @ Sep 22 2006, 14:42) *
Требуется написать макрос для загрузки 16-битного значения в регистры r26:r27.
Для 8-битного, проблем нет. Делаю так:
Код
#define load_val(val)         \
    {                           \
        __asm__ __volatile__    \
        (                       \
            "ldi r26,%0 \n\t"   \
            : "M" (val)         \
        );                      \
    }


Думал, что для 16 такое прокатит:
Код
#define load_val(val)         \
    {                           \
        __asm__ __volatile__    \
        (                       \
            "ldi r26,%A0 \n\t"  \
            "ldi r27,%B0 \n\t"  \
            : "M" (val)         \
        );                      \
    }

оказалось ошибаюсь.

Кто знает, подскажите как быть, а то уже крыша начинает съезжать. blink.gif


Посмотри avr-libc-user-manual раздел 7.4. Пара констант спасут?
Go to the top of the page
 
+Quote Post
Laksus
сообщение Sep 23 2006, 08:52
Сообщение #3


Частый гость
**

Группа: Участник
Сообщений: 146
Регистрация: 16-05-05
Пользователь №: 5 069



Может так?
_________________
Код
#define load_val(val)        \
    __asm__ __volatile__(\
        "ldi r26,%0 \n\t"\
        "ldi r27, %1 \n\t"\
        ::  "M"((char)(val)),"M"((char)((val)>>8)))

_________________
*.c
...
load_val(0x1234);
...
_________________
*.lss
...
d4: a4 e3 ldi r26, 0x34 ; 52
d6: b2 e1 ldi r27, 0x12 ; 18
...
_________________
WinAVR-20040404
Александр
2006 09 23
Go to the top of the page
 
+Quote Post
Tiro
сообщение Sep 23 2006, 19:50
Сообщение #4


Знающий
****

Группа: Свой
Сообщений: 781
Регистрация: 3-10-04
Из: Санкт-Петербург
Пользователь №: 768



В предложенных макросах есть неточности, хотя они и работоспособны. Вы не указываете, что r26:r27 являются "запорченными" (clobbers). Потенциально это может привести к глюкам программы. Но вот зачем Вам такой способ использования регистровой пары? Как вы ее дальше собираетесь использовать? Можно подойти к проблеме по другому. В gcc есть отличный способ привязать регистр к переменной, например, так:

Код
#include <stdint.h>

int16_t main ( void )
{
    register uint16_t xreg asm ("r26");

    xreg = 0x1234;
    *(uint8_t *)xreg = 0x11;
    xreg = 0x2345;
    *(uint8_t *)xreg = 0x22;
    xreg = 0x3456;
    *(uint8_t *)xreg = 0x33;
    
    return *(int16_t *)xreg;
}


Такое использование не сбивает оптимизатор.

Код
    5:            register uint16_t xreg asm ("r26");
    6:        
    7:            xreg = 0x1234;
    8:            *(uint8_t *)xreg = 0x11;
   \   0008 81E1              ldi r24,lo8(17)
   \   000a 8093 3412         sts 4660,r24
    9:            xreg = 0x2345;
    10:            *(uint8_t *)xreg = 0x22;
   \   000e 82E2              ldi r24,lo8(34)
   \   0010 8093 4523         sts 9029,r24
    11:            xreg = 0x3456;
   \   0014 A6E5              ldi r26,lo8(13398)
   \   0016 B4E3              ldi r27,hi8(13398)
    12:            *(uint8_t *)xreg = 0x33;
   \   0018 83E3              ldi r24,lo8(51)
   \   001a 8C93              st X,r24
    13:            
    14:            return *(int16_t *)xreg;
    15:        }
   \   001c 8D91              ld r24,X+
   \   001e 9C91              ld r25,X


С уважением.
Go to the top of the page
 
+Quote Post
Guest_Serg79_*
сообщение Sep 25 2006, 05:22
Сообщение #5





Guests






Laksus, ты прав. Именно так и надо поступать.
Проблему решил следующим способом:
Код
#define load_val(val)                              \
    {                                              \
        __asm__ __volatile__                       \
        (                                          \
            "ldi r26,%0 \n\t"                      \
            "ldi r27,%1 \n\t"                      \
            :: "M" ((uint8_t)((uint16_t)(val))),   \
               "M" ((uint8_t)((uint16_t)(val)>>8)) \
        );                                         \
    }

Теперь такое работает без проблем:
Код
load_val(0x2345);
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 22:51
Рейтинг@Mail.ru


Страница сгенерированна за 0.01405 секунд с 7
ELECTRONIX ©2004-2016