Dx! 0 28 сентября, 2010 Опубликовано 28 сентября, 2010 (изменено) · Жалоба Неужели в IAR или кейле этот (или любой другой стандартный) регистр имеет другое имя или не восемь бит без знака? 0_0 Изменено 28 сентября, 2010 пользователем Dx! Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 28 сентября, 2010 Опубликовано 28 сентября, 2010 · Жалоба Люди! Радуйтесь, что сдвиг вправо знакового числа арифметический. В более кривых компиляторах (в частности, МСС18) - этого нету. В любом случае идет заполнение нулями. :smile3046: Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 28 сентября, 2010 Опубликовано 28 сентября, 2010 · Жалоба Люди! Радуйтесь, что сдвиг вправо знакового числа арифметический.Результат сдвига вправо отрицательного числа по стандарту отдан на откуп компилятору. Почему они так решили - загадка. 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. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Petka 0 29 сентября, 2010 Опубликовано 29 сентября, 2010 · Жалоба Результат сдвига вправо отрицательного числа по стандарту отдан на откуп компилятору. Почему они так решили - загадка. могу только дополнить кусочком из книги K&R: "...Сдвиг вправо числа со знаком в некоторых системах приводит к заполнению этих битов (прим: освободившихся) значением знакового бита ("арифметический сдвиг") , а в других - нулями ("логический сдвиг")..." P.S. Однако, в случае топикстартера всё равно логический или арифметический сдвиг был применён. результат будет одинаковым. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dx! 0 30 сентября, 2010 Опубликовано 30 сентября, 2010 (изменено) · Жалоба Как заключение - остановился на варианте 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. Изменено 30 сентября, 2010 пользователем Dx! Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 30 сентября, 2010 Опубликовано 30 сентября, 2010 · Жалоба Как заключение - остановился на варианте somevar = (uint8_t)(~PIND) >> 4; Вы еще один вариант не проверили somevar = (PIND^0xFF) >> 4; Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
777777 0 30 сентября, 2010 Опубликовано 30 сентября, 2010 · Жалоба Вы еще один вариант не проверили somevar = (PIND^0xFF) >> 4; Какая разница? Все равно он приводит операнды к типу int Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dx! 0 30 сентября, 2010 Опубликовано 30 сентября, 2010 · Жалоба 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) Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 30 сентября, 2010 Опубликовано 30 сентября, 2010 · Жалоба Какая разница? Все равно он приводит операнды к типу intНе обязательно. Зависит от платформы, компилятора и оптимизации. На MSP430, например, преобразуется в команды работы с байтами, а не словами. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
777777 0 30 сентября, 2010 Опубликовано 30 сентября, 2010 · Жалоба Не обязательно. Зависит от платформы, компилятора и оптимизации. На MSP430, например, преобразуется в команды работы с байтами, а не словами. Да, кейл тоже творчески подходит к стандарту и знает где можно от него отойти ради более эффективного кода. А гцц слишком тупо ему следует. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Petka 0 30 сентября, 2010 Опубликовано 30 сентября, 2010 · Жалоба Да, кейл тоже творчески подходит к стандарту и знает где можно от него отойти ради более эффективного кода. А гцц слишком тупо ему следует. Не бывает тупого следования стандарту. Бывает либо соответствие стандарту, либо несоответствие стандарту. Если компилятор не соответствует стандарту, то одинаковый код на разных платформах будет давать разный результат. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 30 сентября, 2010 Опубликовано 30 сентября, 2010 · Жалоба Не бывает тупого следования стандарту. Бывает либо соответствие стандарту, либо несоответствие стандарту. Если компилятор не соответствует стандарту, то одинаковый код на разных платформах будет давать разный результат. Вы молоко покупаете в магазине? Откуда вы знаете автоматическая дойка на ферме стоит или доярки вручную каждую корову доят? Вы знаете входной параметр - молоко коровье, значит получено от коровы и видите/потребляете результат - молоко коровье пастеризованное, упакованное в полиэтилен, тетрапак или ПЭТ. А промежуточные этапы получения результата могут быть разными. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
777777 0 30 сентября, 2010 Опубликовано 30 сентября, 2010 · Жалоба Не бывает тупого следования стандарту. Бывает либо соответствие стандарту, либо несоответствие стандарту. Если компилятор не соответствует стандарту, то одинаковый код на разных платформах будет давать разный результат. Все верно. Но бывают случаи, когда несоответствие стандарту дает лучшие результаты, чем соответствие. В частности, стандарт требует при выполнении операций приводить операнды к типу int. Может это и хорошо когда размер int соответствует естественному размеру переменной на данной платформе. Но в 8-разрядных процессорах это не так - int не может быть 8-битным, а выполнение операций в 16-разрядных переменных приводит к неэффективности кода. Другой пример - различные адресные пространства. Стандарт предназначен для машин фон-неймановской архитертуры и ничего не хочет знать о том, что указатель может указывать как на пространство кода, так и на пространство данных. А в кейле можно объявить указатель на нужное нам пространство и просто разыменовывать его *p безо всяких уродских pgm_read_byte и компилятор генерирует нужный код в зависимости от типа указателя. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Petka 0 30 сентября, 2010 Опубликовано 30 сентября, 2010 · Жалоба Но в 8-разрядных процессорах это не так - int не может быть 8-битным, а выполнение операций в 16-разрядных переменных приводит к неэффективности кода. int может быть 8ми битным, для этого надо указать gcc правильный ключик. Другой пример - различные адресные пространства. Стандарт предназначен для машин фон-неймановской архитертуры и ничего не хочет знать о том, что указатель может указывать как на пространство кода, так и на пространство данных. А в кейле можно объявить указатель на нужное нам пространство и просто разыменовывать его *p безо всяких уродских pgm_read_byte и компилятор генерирует нужный код в зависимости от типа указателя. Это ещё одна причина использовать архитектуры где флэш и оперативная память адресуются одинаково без ущерба для производительности (ARM, например). Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
777777 0 30 сентября, 2010 Опубликовано 30 сентября, 2010 (изменено) · Жалоба int может быть 8ми битным, для этого надо указать gcc правильный ключик. И что, от этого компиоятор будет генерировать вычисление выражений по-другому? Будет приводить к 8-битному int? Это ещё одна причина использовать архитектуры где флэш и оперативная память адресуются одинаково без ущерба для производительности (ARM, например). Такое впечатление, что стандарт C для вас бог, а все остальное для него подстраиваться. Вообще-то первичным является железо, а все остальное делается для него (причем сначала появляются компиляторы, а потом стандарты для них). Поэтому и существуют до сих пор гарвардские процессоры, поскольку они удобнее в качестве микроконтроллеров, поэтому придумывают новые архитектуры - сигнальные процессоры, многопроцессорные системы. И если для кого-то из них не хватает возможностей языка - значит его надо расширять или менять. Изменено 30 сентября, 2010 пользователем 777777 Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться