Duvanoff
Apr 15 2006, 08:51
Добрый день.
Не могли бы растолковать как ИАР реализовывает битовые сдвиги. Интересует прежде всего аналоги команд 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
Apr 15 2006, 13:39
Цитата(vet @ Apr 15 2006, 14:25)

Нет такой операции в Си.
Вообще, Си ничего не знает про флаг переноса.
Нужно вращение бит - делайте ассемблерную вставку/подпрограмму или пользуйтесь конструкцией вида
***** скип *****
Сдвиг вправо зависит от того, unsigned аргумент (логический сдвиг) или signed (арифметический).
Спасибо за ответ.
Очень жаль, что он ("СИ") этого не понимает 8-( .Т.е. соответственно команды типа ADC, SBC и подобные не реализовывает?
"Внутри ", конечно, компилятор пользуется C-флагом, при сложениях-вычитаниях, многобайтовых сдвигах и т.д. Имелось в виду, что из Сишного кода нельзя напрямую достучаться до флага.
Ну вообщем, я набирался наглости на следующие вещи:
Код
#define _CARRY SREG_Bit0
void subrxcrc(unsigned int i)
{
i=rxcrc-i;
if (_CARRY) i--;
rxcrc=i;
}
Можно и со сдвигами...
Andy Mozzhevilov
Apr 17 2006, 06:05
если надо кольцевой сдвиг на Си, то x = x>>n | x<<sizeof(x)*8-n это пример для сдвига вправо.
где
n - на сколько бит нужно сдвинуть,
В зависимости от типа uC конечная реализация может оказаться как очень эффективной, так и наоборот, но работать будет всегда.
Igor26
Apr 18 2006, 05:54
Я использую флаг переноса таким макаром:
//Засвечиваю сегмент A. Значение уровня равно флагу переноса
Digit=Digit<<1;
//Запрещаю прерывания, иначе возможно изменение флага переноса
__disable_interrupt();
PORTD_Bit1=SREG&0x01;
__enable_interrupt();
Igor26
предлагаю поправку - запрещать прерывания нужно до сдвига.
А вот и нифига. Не нужно запрещать прерывания, если у вас обработчик написан корректно (если писали сами на асме и не забыли сохранить SREG) или изготовлен самим компилятором (тот сохранит, если не глюканет

)
А, ну да, верно

запрещать незачем вообще.
рефлексы сработали
Igor26
Apr 19 2006, 06:30
Цитата(Rst7 @ Apr 18 2006, 13:18)

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

)
Согласен
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.