Перейти к содержанию
    

Реализация битовых сдвигов в IAR C

Гость Duvanoff

Добрый день.

Не могли бы растолковать как ИАР реализовывает битовые сдвиги. Интересует прежде всего аналоги команд ROL / ROR, т.е. не понятно как быть с битом "С" ? В "больших" Сях (например от микрософт) какой сдвиг реализовать компилятор выбирает из типа аргумента (unsigned/signed). А как здесь быть? Как написано в документации на 4.10 - <</>> делают только логический сдвиг (LSL/LSR). Как быть если нужен "зацикленный" сдвиг? Или может чего то я путаю?

Заранее спасибо за разъяснения.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нет такой операции в Си.

Вообще, Си ничего не знает про флаг переноса.

Нужно вращение бит - делайте ассемблерную вставку/подпрограмму или пользуйтесь конструкцией вида

unsigned char n;
//вращение байта вправо
if (n&1) n = (n>>1)|0x80; else n >>= 1;
//вращение байта влево
if (n&0x80) n = (n<<1)|0x01; else n <<= 1;

 

Сдвиг вправо зависит от того, unsigned аргумент (логический сдвиг) или signed (арифметический).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Гость Duvanoff
Нет такой операции в Си.

Вообще, Си ничего не знает про флаг переноса.

Нужно вращение бит - делайте ассемблерную вставку/подпрограмму или пользуйтесь конструкцией вида

***** скип *****

 

Сдвиг вправо зависит от того, unsigned аргумент (логический сдвиг) или signed (арифметический).

 

Спасибо за ответ.

 

Очень жаль, что он ("СИ") этого не понимает 8-( .Т.е. соответственно команды типа ADC, SBC и подобные не реализовывает?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

"Внутри ", конечно, компилятор пользуется C-флагом, при сложениях-вычитаниях, многобайтовых сдвигах и т.д. Имелось в виду, что из Сишного кода нельзя напрямую достучаться до флага.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну вообщем, я набирался наглости на следующие вещи:

 

#define _CARRY SREG_Bit0

void subrxcrc(unsigned int i)
{
i=rxcrc-i;
if (_CARRY) i--;
rxcrc=i;
}

 

Можно и со сдвигами...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

если надо кольцевой сдвиг на Си, то x = x>>n | x<<sizeof(x)*8-n это пример для сдвига вправо.

где

n - на сколько бит нужно сдвинуть,

В зависимости от типа uC конечная реализация может оказаться как очень эффективной, так и наоборот, но работать будет всегда.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я использую флаг переноса таким макаром:

 

//Засвечиваю сегмент A. Значение уровня равно флагу переноса

Digit=Digit<<1;

//Запрещаю прерывания, иначе возможно изменение флага переноса

__disable_interrupt();

PORTD_Bit1=SREG&0x01;

__enable_interrupt();

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А вот и нифига. Не нужно запрещать прерывания, если у вас обработчик написан корректно (если писали сами на асме и не забыли сохранить SREG) или изготовлен самим компилятором (тот сохранит, если не глюканет ;))

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А вот и нифига. Не нужно запрещать прерывания, если у вас обработчик написан корректно (если писали сами на асме и не забыли сохранить SREG) или изготовлен самим компилятором (тот сохранит, если не глюканет ;))

Согласен

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...