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

 
 
3 страниц V  < 1 2 3 >  
Closed TopicStart new topic
> Последовательность действий - побитовая инверсия и сдвиг, (~PIND) >> 4 == ~(PIND >> 4) ???
Dx!
сообщение Sep 28 2010, 20:01
Сообщение #16


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

Группа: Участник
Сообщений: 108
Регистрация: 6-02-09
Из: Новочеркасск
Пользователь №: 44 469



Неужели в IAR или кейле этот (или любой другой стандартный) регистр имеет другое имя или не восемь бит без знака? 0_0

Сообщение отредактировал Dx! - Sep 28 2010, 20:08
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Sep 28 2010, 20:14
Сообщение #17


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Люди! Радуйтесь, что сдвиг вправо знакового числа арифметический. В более кривых компиляторах (в частности, МСС18) - этого нету. В любом случае идет заполнение нулями. smile3046.gif
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 28 2010, 22:31
Сообщение #18


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(_Pasha @ Sep 28 2010, 23:14) *
Люди! Радуйтесь, что сдвиг вправо знакового числа арифметический.
Результат сдвига вправо отрицательного числа по стандарту отдан на откуп компилятору. Почему они так решили - загадка.
Цитата
5 The result of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type or if E1 has a signed type and a nonnegative value, the value of the result is the integral part of the quotient of E1 /2^E2. If E1 has a signed type and a negative value, the resulting value is implementation-defined.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Petka
сообщение Sep 29 2010, 04:50
Сообщение #19


Профессионал
*****

Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886



Цитата(Сергей Борщ @ Sep 29 2010, 02:31) *
Результат сдвига вправо отрицательного числа по стандарту отдан на откуп компилятору. Почему они так решили - загадка.

могу только дополнить кусочком из книги K&R:
"...Сдвиг вправо числа со знаком в некоторых системах приводит к заполнению этих битов (прим: освободившихся) значением знакового бита ("арифметический сдвиг") , а в других - нулями ("логический сдвиг")..."

P.S. Однако, в случае топикстартера всё равно логический или арифметический сдвиг был применён. результат будет одинаковым.
Go to the top of the page
 
+Quote Post
Dx!
сообщение Sep 30 2010, 09:05
Сообщение #20


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

Группа: Участник
Сообщений: 108
Регистрация: 6-02-09
Из: Новочеркасск
Пользователь №: 44 469



Как заключение - остановился на варианте
somevar = (uint8_t)(~PIND) >> 4;
ибо
Код
----------------------------------------------------
    PORTB = (~PIND) >> 4;
  80:    89 b1           in    r24, 0x09; 9
  82:    90 e0           ldi    r25, 0x00; 0
  84:    80 95           com    r24
  86:    90 95           com    r25
  88:    95 95           asr    r25
  8a:    87 95           ror    r24
  8c:    95 95           asr    r25
  8e:    87 95           ror    r24
  90:    95 95           asr    r25
  92:    87 95           ror    r24
  94:    95 95           asr    r25
  96:    87 95           ror    r24
  98:    85 b9           out    0x05, r24; 5
----------------------------------------------------
    PORTB = ((~PIND) >> 4)&0xf;
  80:    89 b1           in    r24, 0x09; 9
  82:    90 e0           ldi    r25, 0x00; 0
  84:    80 95           com    r24
  86:    90 95           com    r25
  88:    95 95           asr    r25
  8a:    87 95           ror    r24
  8c:    95 95           asr    r25
  8e:    87 95           ror    r24
  90:    95 95           asr    r25
  92:    87 95           ror    r24
  94:    95 95           asr    r25
  96:    87 95           ror    r24
  98:    8f 70           andi    r24, 0x0F; 15
  9a:    85 b9           out    0x05, r24; 5
----------------------------------------------------
    PORTB = ((~PIND)&0xff) >> 4;
  80:    89 b1           in    r24, 0x09; 9
  82:    80 95           com    r24
  84:    90 e0           ldi    r25, 0x00; 0
  86:    95 95           asr    r25
  88:    87 95           ror    r24
  8a:    95 95           asr    r25
  8c:    87 95           ror    r24
  8e:    95 95           asr    r25
  90:    87 95           ror    r24
  92:    95 95           asr    r25
  94:    87 95           ror    r24
  96:    85 b9           out    0x05, r24; 5
----------------------------------------------------
    PORTB = ((uint8_t)(~PIND)) >> 4;
  80:    89 b1           in    r24, 0x09; 9
  82:    80 95           com    r24
  84:    82 95           swap    r24
  86:    8f 70           andi    r24, 0x0F; 15
  88:    85 b9           out    0x05, r24; 5
----------------------------------------------------
    PORTB = (uint8_t)(~PIND) >> 4;
  80:    89 b1           in    r24, 0x09; 9
  82:    80 95           com    r24
  84:    82 95           swap    r24
  86:    8f 70           andi    r24, 0x0F; 15
  88:    85 b9           out    0x05, r24; 5
----------------------------------------------------
    uint8_t tmpD;
    tmpD = PIND;
  80:    89 b1           in    r24, 0x09; 9
    tmpD = ~tmpD;

    PORTB = tmpD >> 4;
  82:    80 95           com    r24
  84:    82 95           swap    r24
  86:    8f 70           andi    r24, 0x0F; 15
  88:    85 b9           out    0x05, r24; 5
----------------------------------------------------

Даже swap а не тупо сдвиг. Компиленно с -O2.

Сообщение отредактировал Dx! - Sep 30 2010, 09:12
Go to the top of the page
 
+Quote Post
rezident
сообщение Sep 30 2010, 10:47
Сообщение #21


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(Dx! @ Sep 30 2010, 15:05) *
Как заключение - остановился на варианте
somevar = (uint8_t)(~PIND) >> 4;
Вы еще один вариант не проверили
Код
somevar = (PIND^0xFF) >> 4;

Go to the top of the page
 
+Quote Post
777777
сообщение Sep 30 2010, 10:53
Сообщение #22


Профессионал
*****

Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357



Цитата(rezident @ Sep 30 2010, 14:47) *
Вы еще один вариант не проверили
Код
somevar = (PIND^0xFF) >> 4;

Какая разница? Все равно он приводит операнды к типу int
Go to the top of the page
 
+Quote Post
Dx!
сообщение Sep 30 2010, 11:02
Сообщение #23


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

Группа: Участник
Сообщений: 108
Регистрация: 6-02-09
Из: Новочеркасск
Пользователь №: 44 469



Код
PORTB = (PIND^0xFF) >> 4;
  80:    89 b1           in    r24, 0x09; 9
  82:    80 95           com    r24
  84:    82 95           swap    r24
  86:    8f 70           andi    r24, 0x0F; 15
  88:    85 b9           out    0x05, r24; 5

Оптимизация 8)
Go to the top of the page
 
+Quote Post
rezident
сообщение Sep 30 2010, 11:25
Сообщение #24


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(777777 @ Sep 30 2010, 16:53) *
Какая разница? Все равно он приводит операнды к типу int
Не обязательно. Зависит от платформы, компилятора и оптимизации. На MSP430, например, преобразуется в команды работы с байтами, а не словами.
Go to the top of the page
 
+Quote Post
777777
сообщение Sep 30 2010, 12:00
Сообщение #25


Профессионал
*****

Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357



Цитата(rezident @ Sep 30 2010, 15:25) *
Не обязательно. Зависит от платформы, компилятора и оптимизации. На MSP430, например, преобразуется в команды работы с байтами, а не словами.

Да, кейл тоже творчески подходит к стандарту и знает где можно от него отойти ради более эффективного кода. А гцц слишком тупо ему следует.
Go to the top of the page
 
+Quote Post
Petka
сообщение Sep 30 2010, 12:24
Сообщение #26


Профессионал
*****

Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886



Цитата(777777 @ Sep 30 2010, 16:00) *
Да, кейл тоже творчески подходит к стандарту и знает где можно от него отойти ради более эффективного кода. А гцц слишком тупо ему следует.

Не бывает тупого следования стандарту.

Бывает либо соответствие стандарту, либо несоответствие стандарту.
Если компилятор не соответствует стандарту, то одинаковый код на разных платформах будет давать разный результат.
Go to the top of the page
 
+Quote Post
rezident
сообщение Sep 30 2010, 13:13
Сообщение #27


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(Petka @ Sep 30 2010, 18:24) *
Не бывает тупого следования стандарту.

Бывает либо соответствие стандарту, либо несоответствие стандарту.
Если компилятор не соответствует стандарту, то одинаковый код на разных платформах будет давать разный результат.

Вы молоко покупаете в магазине? Откуда вы знаете автоматическая дойка на ферме стоит или доярки вручную каждую корову доят? Вы знаете входной параметр - молоко коровье, значит получено от коровы и видите/потребляете результат - молоко коровье пастеризованное, упакованное в полиэтилен, тетрапак или ПЭТ. А промежуточные этапы получения результата могут быть разными.
Go to the top of the page
 
+Quote Post
777777
сообщение Sep 30 2010, 15:51
Сообщение #28


Профессионал
*****

Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357



Цитата(Petka @ Sep 30 2010, 16:24) *
Не бывает тупого следования стандарту.

Бывает либо соответствие стандарту, либо несоответствие стандарту.
Если компилятор не соответствует стандарту, то одинаковый код на разных платформах будет давать разный результат.

Все верно. Но бывают случаи, когда несоответствие стандарту дает лучшие результаты, чем соответствие. В частности, стандарт требует при выполнении операций приводить операнды к типу int. Может это и хорошо когда размер int соответствует естественному размеру переменной на данной платформе. Но в 8-разрядных процессорах это не так - int не может быть 8-битным, а выполнение операций в 16-разрядных переменных приводит к неэффективности кода.
Другой пример - различные адресные пространства. Стандарт предназначен для машин фон-неймановской архитертуры и ничего не хочет знать о том, что указатель может указывать как на пространство кода, так и на пространство данных. А в кейле можно объявить указатель на нужное нам пространство и просто разыменовывать его *p безо всяких уродских pgm_read_byte и компилятор генерирует нужный код в зависимости от типа указателя.
Go to the top of the page
 
+Quote Post
Petka
сообщение Sep 30 2010, 16:00
Сообщение #29


Профессионал
*****

Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886



Цитата(777777 @ Sep 30 2010, 19:51) *
Но в 8-разрядных процессорах это не так - int не может быть 8-битным, а выполнение операций в 16-разрядных переменных приводит к неэффективности кода.

int может быть 8ми битным, для этого надо указать gcc правильный ключик.
Цитата
Другой пример - различные адресные пространства. Стандарт предназначен для машин фон-неймановской архитертуры и ничего не хочет знать о том, что указатель может указывать как на пространство кода, так и на пространство данных. А в кейле можно объявить указатель на нужное нам пространство и просто разыменовывать его *p безо всяких уродских pgm_read_byte и компилятор генерирует нужный код в зависимости от типа указателя.

Это ещё одна причина использовать архитектуры где флэш и оперативная память адресуются одинаково без ущерба для производительности (ARM, например).
Go to the top of the page
 
+Quote Post
777777
сообщение Sep 30 2010, 16:58
Сообщение #30


Профессионал
*****

Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357



Цитата(Petka @ Sep 30 2010, 20:00) *
int может быть 8ми битным, для этого надо указать gcc правильный ключик.

И что, от этого компиоятор будет генерировать вычисление выражений по-другому? Будет приводить к 8-битному int?
Цитата(Petka @ Sep 30 2010, 20:00) *
Это ещё одна причина использовать архитектуры где флэш и оперативная память адресуются одинаково без ущерба для производительности (ARM, например).

Такое впечатление, что стандарт C для вас бог, а все остальное для него подстраиваться.
Вообще-то первичным является железо, а все остальное делается для него (причем сначала появляются компиляторы, а потом стандарты для них). Поэтому и существуют до сих пор гарвардские процессоры, поскольку они удобнее в качестве микроконтроллеров, поэтому придумывают новые архитектуры - сигнальные процессоры, многопроцессорные системы. И если для кого-то из них не хватает возможностей языка - значит его надо расширять или менять.

Сообщение отредактировал 777777 - Sep 30 2010, 17:00
Go to the top of the page
 
+Quote Post

3 страниц V  < 1 2 3 >
Closed TopicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


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


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