Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Нужна помощь по С
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
impuls-v
Можеть комунибудь покажется этот вопрос дибильным, но может кто знает.
Нужно сделать простейшую операцию - обмен нимблов т.е. ассемблерная команда swap.
Но вот в С++ я не нашел такой.
Вроде чего тут сложного сделал ассемблерную вставку, но нужно чтобы программы была универсальной, т.е. если сделать вставку swap r25? я не знаю может потом r25 окажется занятым переменной и все собъется.
Как сделать обмен нимблов на С, подскажите плиз.
Petka
Цитата(impuls-v @ Jul 14 2006, 14:22) *
Можеть комунибудь покажется этот вопрос дибильным, но может кто знает.
Нужно сделать простейшую операцию - обмен нимблов т.е. ассемблерная команда swap.
Но вот в С++ я не нашел такой.
Вроде чего тут сложного сделал ассемблерную вставку, но нужно чтобы программы была универсальной, т.е. если сделать вставку swap r25? я не знаю может потом r25 окажется занятым переменной и все собъется.
Как сделать обмен нимблов на С, подскажите плиз.


c=(c>>4)|(c<<4);
impuls-v
Черт спасибо попробую.
Сначала была идея использовать>> но зациклился на том что
Цитата
При сдвиге влево правые освобождающиеся биты устанавливаются в нуль. При сдвиге вправо метод заполнения освобождающихся левых битов зависит от типа первого операнда.Если тип unsigned, то свободные левые биты устанавливаются в нуль. В противном случае они заполняются копией знакового бита.

И не подумал что можно сделать нужную операцию используя | и сдвиг влево и вправо.
otrog
Цитата(Petka @ Jul 14 2006, 14:25) *
c=(c>>4)|(c<<4);

IAR компилирует вот во что:
Код
    120            i=(i>>4)|(i<<4);
   \   00000004   2F10               MOV     R17, R16
   \   00000006   9512               SWAP    R17
   \   00000008   701F               ANDI    R17, 0x0F
   \   0000000A   9502               SWAP    R16
   \   0000000C   7F00               ANDI    R16, 0xF0
   \   0000000E   2B01               OR      R16, R17
sad.gif
unichorn
smile.gif
Ндааа. Дешевле ассемблерную вставку сделать.
_Bill
Цитата(otrog @ Jul 14 2006, 14:20) *
Цитата(Petka @ Jul 14 2006, 14:25) *

c=(c>>4)|(c<<4);

IAR компилирует вот во что:
Код
    120            i=(i>>4)|(i<<4);
   \   00000004   2F10               MOV     R17, R16
   \   00000006   9512               SWAP    R17
   \   00000008   701F               ANDI    R17, 0x0F
   \   0000000A   9502               SWAP    R16
   \   0000000C   7F00               ANDI    R16, 0xF0
   \   0000000E   2B01               OR      R16, R17
sad.gif

Хм... Другой IAR компилирует SWAP
otrog
Цитата(_Bill @ Jul 14 2006, 15:27) *
Хм... Другой IAR компилирует SWAP

Код
     34          unsigned int fu( unsigned int x )
   \                     fu:
     35          {
     36            return(( x &lt;&lt; 8 ) | ( x &gt;&gt; 8 ));
   \   000000   8C10         SWPB    R12
   \   000002   3041         RET
     37          }
     38

Дык то для MSP430 huh.gif
IgorKossak
В IAR есть такая функция
Код
__intrinsic unsigned char __swap_nibbles(unsigned char);

и не нужно к ассемблеру прибегать.
Надо включить файл inavr.h
impuls-v
Похоже эта темы вызвала обсуждение
Ассемблерная вставка дешевле если эта в ставка в вызываемой функции
Например
write(unsigned char data)
{
#asm
LD R30,Y
SWAP R30
ST Y,R30
#endasm
PORTB=data;
}
А в теле основной программы не дешевле.
_Bill
Цитата(impuls-v @ Jul 14 2006, 14:37) *
Похоже эта темы вызвала обсуждение
Ассемблерная вставка дешевле если эта в ставка в вызываемой функции
Например
write(unsigned char data)
{
#asm
LD R30,Y
SWAP R30
ST Y,R30
#endasm
PORTB=data;
}
А в теле основной программы не дешевле.

Вообще, лучше вставками не пользоваться. Вставки не дают возможность компилятору оптимизировать код. Выигрывая в одном, Вы можете проиграть много больше в другом. Да и сама программа будет выглядеть коряво.
impuls-v
Вопервых откуда этот файл а во вторых нетрогать ассемблер, ассемблер это клёво.
otrog
Цитата(IgorKossak @ Jul 14 2006, 15:35) *
В IAR есть такая функция
Код
__intrinsic unsigned char __swap_nibbles(unsigned char);

и не нужно к ассемблеру прибегать.
Надо включить файл inavr.h

Враво!!!
Код
    120            i = __swap_nibbles(i);  
   \   00000002   9502               SWAP    R16

PS ушел учить матчасть.
impuls-v
Цитата
Вообще, лучше вставками не пользоваться. Вставки не дают возможность компилятору оптимизировать код. Выигрывая в одном, Вы можете проиграть много больше в другом. Да и сама программа будет выглядеть коряво.

НУ не знаю не знаю приведенный кусок уже оптимизирован.
_Bill
Цитата(impuls-v @ Jul 14 2006, 14:43) *
Цитата
Вообще, лучше вставками не пользоваться. Вставки не дают возможность компилятору оптимизировать код. Выигрывая в одном, Вы можете проиграть много больше в другом. Да и сама программа будет выглядеть коряво.

НУ не знаю не знаю приведенный кусок уже оптимизирован.

Так в том-то и дело, что Вы привели фрагмент как раз без использования ассемблерной вставки. intrisic функция это не есть вставка. Вы дали возможность компилятору сделать свое дело, результат которого Вас устроил самым наилучшим образом.
Laksus
Цитата
Bill
...Вообще, лучше вставками не пользоваться. Вставки не дают возможность компилятору оптимизировать код.

Не могли бы Вы уточнить как не дают. Очень хорошо если бы
простейший пример.
_____________________________________
Вот тут попробовал в WinAVR20060421
unsigned char с1;
__________
Код
    c1 = PINC;
    asm ("swap %0" : "=r" (c1) : "0" (c1));
    PORTC = c1;
    asm("sleep");
********************************************
    c1 = PINC;
  72:    86 b1           in    r24, 0x06; 6
    asm ("swap %0" : "=r" (c1) : "0" (c1));
  74:    82 95           swap    r24
    PORTC = c1;
  76:    88 b9           out    0x08, r24; 8
    asm("sleep");

___________
а если c1 не используем и не применямем voletile
Код
    c1 = PINC;
    asm ("swap %0" : "=r" (c1) : "0" (c1));
    asm("sleep");
********************************************
    c1 = PINC;
  72:    86 b1           in    r24, 0x06; 6
    asm ("swap %0" : "=r" (c1) : "0" (c1));
    asm("sleep");
  74:    88 95           sleep

То есть, насколько я понимаю, оптимизация есть и с ассемблером.
____________
____________
А без ассемблера у меня получилось вот такой бред.
OPTIMIZE = -O3, без оптимизации еще хуже.
(WinAVR я только пытаюсь освоить, поэтому подозреваю что
сделал что-то не так):
Код
    c1 = PINC;
    c1 = (c1>>4)|(c1<<4);
    PORTC = c1;
    asm("sleep");
********************************************
    c1 = PINC;
  72:    26 b1           in    r18, 0x06; 6
    c1 = (c1>>4)|(c1<<4);
  74:    82 2f           mov    r24, r18
  76:    99 27           eor    r25, r25
  78:    82 95           swap    r24
  7a:    92 95           swap    r25
  7c:    90 7f           andi    r25, 0xF0; 240
  7e:    98 27           eor    r25, r24
  80:    80 7f           andi    r24, 0xF0; 240
  82:    98 27           eor    r25, r24
  84:    22 95           swap    r18
  86:    2f 70           andi    r18, 0x0F; 15
  88:    28 2b           or    r18, r24
    PORTC = c1;
  8a:    28 b9           out    0x08, r18; 8
    asm("sleep");
  8c:    88 95           sleep

__________
Александр
2006 07 15
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.