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

 
 
 
Reply to this topicStart new topic
> Сдвиг в бит С
*Roma*
сообщение Jul 22 2005, 08:50
Сообщение #1


Участник
*

Группа: Новичок
Сообщений: 24
Регистрация: 17-06-05
Пользователь №: 6 089



Ктонибудь когда нибудь организовывал на С на AVR асемблерную операцию сдвига в бит C (Cerry) и возможно ли это вообще на С ???
Go to the top of the page
 
+Quote Post
subver
сообщение Jul 22 2005, 09:16
Сообщение #2


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

Группа: Свой
Сообщений: 185
Регистрация: 4-06-05
Из: Омск
Пользователь №: 5 726



Собственно любой сдвиг выталкивает крайний бит в с.

a>>=1 - младший бит попадает в С
Go to the top of the page
 
+Quote Post
VladislavS
сообщение Jul 22 2005, 14:18
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 475
Регистрация: 14-04-05
Из: Москва
Пользователь №: 4 140



Цитата(*Roma* @ Jul 22 2005, 11:50)
Ктонибудь когда нибудь организовывал на С на AVR асемблерную операцию сдвига в бит C (Cerry) и возможно ли это вообще на С ???
*


А какой в этом тайный смысл, если не секрет. Просто пиши на С, а с регистрами, битами, стеками это уже дело компилятора возиться. Сколько пишу для AVR и ARM на С/С++ ни разу не было желания в Cerry что-то задвигать.
Go to the top of the page
 
+Quote Post
potor
сообщение Jul 22 2005, 14:36
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 20
Регистрация: 22-07-05
Пользователь №: 7 022



Цитата
Собственно любой сдвиг выталкивает крайний бит в с.

a>>=1 - младший бит попадает в С

я бы такого не утверждал, это не предусмотренно Сишными стандартами, поэтому лучше на это не расчитывать
Go to the top of the page
 
+Quote Post
moonrock
сообщение Jul 22 2005, 15:43
Сообщение #5


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

Группа: Свой
Сообщений: 166
Регистрация: 24-03-05
Из: Санкт-Петербург
Пользователь №: 3 661



blink.gif
Работа с битами заложена в языке С. Посмотрите в любой книге. Другое дело куда попадает крайний бит после такой операции в конкретном компиляторе.
В своих программах я довольно часто применяю операцию сдвига, но флагом переноса не пользовался.
Go to the top of the page
 
+Quote Post
vip6k
сообщение Jul 22 2005, 19:04
Сообщение #6


Участник
*

Группа: Свой
Сообщений: 22
Регистрация: 13-05-05
Пользователь №: 4 994



Цитата(subver @ Jul 22 2005, 12:16)
Собственно любой сдвиг выталкивает крайний бит в с.

a>>=1 - младший бит попадает в С
*


Логический сдвиг гарантируется только для целых чисел без знака.
А для других типов данных зависит от конкретной реализации компилятора.
Go to the top of the page
 
+Quote Post
yung
сообщение Jul 22 2005, 20:34
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 207
Регистрация: 25-03-05
Из: Рязань
Пользователь №: 3 669



Теоретически можно сделать это ручками. Практически это не имеет никакого смысла, поскольку воспользоваться флагами реально только из ассемблера. А если ассемблер, то зачем сдвиг в Си делать?
Go to the top of the page
 
+Quote Post
*Roma*
сообщение Jul 23 2005, 07:49
Сообщение #8


Участник
*

Группа: Новичок
Сообщений: 24
Регистрация: 17-06-05
Пользователь №: 6 089



А какой в этом тайный смысл, если не секрет. Просто пиши на С, а с регистрами, битами, стеками это уже дело компилятора возиться. Сколько пишу для AVR и ARM на С/С++ ни разу не было желания в Cerry что-то задвигать.
*

[/quote]

Тайный смыс вот какой - в своей проге я создаю регистр флагов (обычно R15) сканировать его можна 2-мя способами:
1)
for(;;)
{
unsigned char buff=reg_flag;
if ((buff & 0x01) == 0x01){time();}
if ((buff & 0x02) == 0x02){indi ();}
if ((buff & 0x04) == 0x04){klava ();}
if ((buff & 0x08) == 0x08){break ;}
}

2)
for(;;)
{void (* Pfunk[3])()={minute,save,analiz_ADC};
unsigned char buff=reg_flag;
unsigned char count=2;
for(;;)
{
if ((buff&0x01)==0x01) {(* Pfunk[count])();}
buff>>=1;
count--;
if ((SREG&0x04)==0x04){break;}//if negative flag=1
}
}
прои большом количестве функций, которые необходимо адресовать при помощи регистра флагов способ 2 даёт меньший обьём кода в асме, просто хочу его не многа изменить.
Go to the top of the page
 
+Quote Post
avv
сообщение Jul 23 2005, 07:53
Сообщение #9


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

Группа: Свой
Сообщений: 113
Регистрация: 28-01-05
Из: Владивосток
Пользователь №: 2 247



Если ваш компилятор допускает ассемблерные вставки, может, стоит вставить этот кусок на асме? При таком ходе бит 100% попадет в Сarry и при переходе на другой компилятор не будет сюрпризов
Go to the top of the page
 
+Quote Post
*Roma*
сообщение Jul 23 2005, 08:03
Сообщение #10


Участник
*

Группа: Новичок
Сообщений: 24
Регистрация: 17-06-05
Пользователь №: 6 089



Компилятор IAR под AVR версии 4.10, асемблерные вставки делать под него, скажу прямо - полный отстой. Как я видел перед асмовской вставкой он сначала сохканяет на стеке регистры начиная с R16 а потом достаёт их назад, что раздувает код.
Go to the top of the page
 
+Quote Post
nml
сообщение Jul 23 2005, 09:06
Сообщение #11


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

Группа: Свой
Сообщений: 86
Регистрация: 13-06-04
Из: Minsk
Пользователь №: 29



Цитата(*Roma* @ Jul 23 2005, 10:49)
Код
  count--;
  if ((SREG&0x04)==0x04){break;}//if negative flag=1

Я не сильно большой знаток С, но не проще ли было записать так:
Код
if (--count <0) break;

, только объявить counter как signed...

Да, кстати, я не поленился и написал что-то типа первого варианта,
скомпилировал и получил примерно такой код:
Код
  \                     ??main_0:
  \   00000008   2D0F               MOV     R16, R15
  \   0000000A   FD00               SBRC    R16, 0
  \   0000000C   ....               RCALL   proc1
    49              if (F2){proc2();}
  \                     ??main_1:
  \   0000000E   2D0F               MOV     R16, R15
  \   00000010   FD01               SBRC    R16, 1
  \   00000012   ....               RCALL   proc2

Ну и куда уже короче-то? Нет, ну конечно мог бы компилер в R16 и не пересылать, но по моему и так неплохо. Не говоря уже о том, что первый вариант на порядок читабельнее.

А во втором - может, общий код будет и покороче. Но. Учтите что раздуется код инициализации (константы-указатели), и работать цикл будет прилично медленнее.

Что касается ассемблерных вставок и сохранения регистров - все логично. Ну не знает компилер, что и как вы там менять будете, а у него может свои задумки насчет того, что в каких регистрах лежать должно. Вот и защищается...
Go to the top of the page
 
+Quote Post
d__
сообщение Jul 26 2005, 09:27
Сообщение #12


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

Группа: Свой
Сообщений: 197
Регистрация: 26-08-04
Пользователь №: 548



А кто мешает использовать переменную с полями битов:
void fun1(void)
{
}
void fun2(void)
{
}
void fun3(void)
{
}

void main(void)
{
struct myflags{
char flag1 :1;
char flag2 :1;
char flag3 :1;
}m;
m.flag1=1;
m.flag2=m.flag3=0;
if(m.flag1!=0)fun1();
if(m.flag2!=0)fun2();
if(m.flag3!=0)fun3();
}
Разворачивается буквальнов в три команды и никаких сдвигов:
\ 00000008 FB80 BST R24, 0
\ 0000000A F40E BRTC ??main_0
\ 0000000C .... RCALL fun1
21 if(m.flag2!=0)fun2();
\ ??main_0:
\ 0000000E FB81 BST R24, 1
\ 00000010 F40E BRTC ??main_1
\ 00000012 .... RCALL fun2
22 if(m.flag3!=0)fun3();
\ ??main_1:
\ 00000014 FB82 BST R24, 2
\ 00000016 F40E BRTC ??main_2
\ 00000018 .... RCALL fun3
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 7th July 2025 - 06:42
Рейтинг@Mail.ru


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