Вспоминается: Цвет - любой при условии, что покупатель выбирает черный.
Занудствовать, так занудствовать )))
Это высказывание принадлежит Генри Форду.
Он говорил: «Цвет автомобиля может быть любым, при условии, что он чёрный».
Историки не нашли подтверждения, что он это говорил
Спорить о том, какой из вариантов придуманной фразы правильный, довольно -таки странно.
Кажется у нас новый зануда )))
Еще раз глянул на этот говнокод. Да, говнокод, безусловно, уникальный.
Но во что он скомпилируется? Особенно switch - сase.
В кучу сравнений и условных переходов или компилятор там сумеет применить IJMP ?
Посмотрите и нам расскажете. Не забудьте только сказать о каком процессоре речь.
@ЕвгенийП, а мне всегда фишки с кейсами нравились. Типа,
strcpy(to, from, count) {
register char *to, *from;
register count;
register n = (count + 7) / 8;
if (!count)
return;
switch (count % 8) {
case 0: do { *to++ = *from++;
case 7: *to++ = *from++;
case 6: *to++ = *from++;
case 5: *to++ = *from++;
case 4: *to++ = *from++;
case 3: *to++ = *from++;
case 2: *to++ = *from++;
case 1: *to++ = *from++;
} while (--n);
}
}
Ну, чем плохо то?
И как тут форматировать?!)
const int bufferSize = 253;//задать тут
byte myBuffer[bufferSize];
void setup() { Serial.begin(9600); }
void loop() {
if (bufferSize % 8 == 0) { Serial.println("1");
} else { Serial.println("2"); }
}// вооо, может будет полезно...
Так это ж ровно то же самое, что у меня в статье. Вы привели оригинал, а я немного под ардуино-пример поменял, но идея и основной приём остались неизменными.
Друзья, для несведующего, это что за тип такой?
Жаль. Жаль что не слежу за говнокодом. Да и не понимаю уже особо.(
Это подсказка компилятору, что переменная будет интенсивно использоваться и что вы рекомендуете по возможности хранить ее в регистре процессора.
Большинство современных компиляторов делают это автоматически, и у них это получается лучше, чем у нас, людей.
@ЕвгенийП, у вас талант.) У меня так не получится.
Ну, по сути Вам уже сказали - это int
с просьбой разместить в регистре.
А так – забудьте, в С++ он устарел, считайте, что его уже (и пока) нет. В последний раз он фигурировал в стандарте 14-го года. Уже в стандарте 17-го (и 20-го тоже) сказано:
The export and register keywords are unused but are reserved for future use.
Впрочем, в кошерном Си это понятие по-прежнему присутствует. У них есть очевидные ограничения – нельзя брать их адрес, нельзя использовать под sizeof
. Массивы опять же … поведение не определено.
atmega328p
В loop добавил несколько вызовов функции duffsDevice, чтобы компилятор не занимался самодеятельностью и оформил ее в виде именно отдельной подпрограммы.
duffsDevice(buffer,3);
duffsDevice(buffer,bufLength-50);
duffsDevice(buffer,bufLength);
Оказалось, что да, компилятор использует ijmp, но также оказалось что компилятор генерит такой говнокод, который всем говнокодам говнокод.
void duffsDevice(const uint8_t *from, size_t count) {
90: cf 93 push r28
92: df 93 push r29
C:\ARDUINO\testxxx/testxxx.ino:19
size_t n = (count + 7) / 8;
94: 9c 01 movw r18, r24
96: 29 5f subi r18, 0xF9 ; 249
98: 3f 4f sbci r19, 0xFF ; 255
9a: 43 e0 ldi r20, 0x03 ; 3
9c: 36 95 lsr r19
9e: 27 95 ror r18
a0: 4a 95 dec r20
a2: e1 f7 brne .-8 ; 0x9c <duffsDevice(unsigned char const*, unsigned int) [clone .constprop.0]+0xc>
C:\ARDUINO\testxxx/testxxx.ino:20
switch (count % 8){
a4: fc 01 movw r30, r24
a6: e7 70 andi r30, 0x07 ; 7
a8: ff 27 eor r31, r31
aa: 31 97 sbiw r30, 0x01 ; 1
ac: e7 30 cpi r30, 0x07 ; 7
ae: f1 05 cpc r31, r1
b0: 58 f4 brcc .+22 ; 0xc8 <duffsDevice(unsigned char const*, unsigned int) [clone .constprop.0]+0x38>
b2: e3 5a subi r30, 0xA3 ; 163
b4: ff 4f sbci r31, 0xFF ; 255
b6: 0c 94 42 01 jmp 0x284 ; 0x284 <__tablejump2__>
ba: 9f 00 .word 0x009f ; ????
bc: 9c 00 .word 0x009c ; ????
be: 99 00 .word 0x0099 ; ????
c0: 96 00 .word 0x0096 ; ????
c2: 93 00 .word 0x0093 ; ????
c4: 90 00 .word 0x0090 ; ????
c6: 8d 00 .word 0x008d ; ????
c8: e9 e0 ldi r30, 0x09 ; 9
ca: f1 e0 ldi r31, 0x01 ; 1
C:\ARDUINO\testxxx/testxxx.ino:23
case 0:
do {
PORTC = *from++;
cc: ef 01 movw r28, r30
ce: 21 96 adiw r28, 0x01 ; 1
d0: 80 81 ld r24, Z
d2: 88 b9 out 0x08, r24 ; 8
C:\ARDUINO\testxxx/testxxx.ino:24
case 7: PORTC = *from++;
d4: de 01 movw r26, r28
d6: 11 96 adiw r26, 0x01 ; 1
d8: 88 81 ld r24, Y
da: 88 b9 out 0x08, r24 ; 8
C:\ARDUINO\testxxx/testxxx.ino:25
case 6: PORTC = *from++;
dc: fd 01 movw r30, r26
de: 31 96 adiw r30, 0x01 ; 1
e0: 8c 91 ld r24, X
e2: 88 b9 out 0x08, r24 ; 8
C:\ARDUINO\testxxx/testxxx.ino:26
case 5: PORTC = *from++;
e4: df 01 movw r26, r30
e6: 11 96 adiw r26, 0x01 ; 1
e8: 80 81 ld r24, Z
ea: 88 b9 out 0x08, r24 ; 8
C:\ARDUINO\testxxx/testxxx.ino:27
case 4: PORTC = *from++;
ec: fd 01 movw r30, r26
ee: 31 96 adiw r30, 0x01 ; 1
f0: 8c 91 ld r24, X
f2: 88 b9 out 0x08, r24 ; 8
C:\ARDUINO\testxxx/testxxx.ino:28
case 3: PORTC = *from++;
f4: df 01 movw r26, r30
f6: 11 96 adiw r26, 0x01 ; 1
f8: 80 81 ld r24, Z
fa: 88 b9 out 0x08, r24 ; 8
C:\ARDUINO\testxxx/testxxx.ino:29
case 2: PORTC = *from++;
fc: fd 01 movw r30, r26
fe: 31 96 adiw r30, 0x01 ; 1
100: 8c 91 ld r24, X
102: 88 b9 out 0x08, r24 ; 8
C:\ARDUINO\testxxx/testxxx.ino:30
case 1: PORTC = *from++;
104: 80 81 ld r24, Z
106: 88 b9 out 0x08, r24 ; 8
C:\ARDUINO\testxxx/testxxx.ino:31
} while(--n > 0);
108: 21 50 subi r18, 0x01 ; 1
10a: 31 09 sbc r19, r1
C:\ARDUINO\testxxx/testxxx.ino:30
case 6: PORTC = *from++;
case 5: PORTC = *from++;
case 4: PORTC = *from++;
case 3: PORTC = *from++;
case 2: PORTC = *from++;
case 1: PORTC = *from++;
10c: 31 96 adiw r30, 0x01 ; 1
C:\ARDUINO\testxxx/testxxx.ino:31
} while(--n > 0);
10e: 21 15 cp r18, r1
110: 31 05 cpc r19, r1
112: e1 f6 brne .-72 ; 0xcc <duffsDevice(unsigned char const*, unsigned int) [clone .constprop.0]+0x3c>
C:\ARDUINO\testxxx/testxxx.ino:33
}
}
114: df 91 pop r29
116: cf 91 pop r28
118: 08 95 ret
C:\ARDUINO\testxxx/testxxx.ino:20
void duffsDevice(const uint8_t *from, size_t count) {
size_t n = (count + 7) / 8;
switch (count % 8){
11a: c9 e0 ldi r28, 0x09 ; 9
11c: d1 e0 ldi r29, 0x01 ; 1
11e: da cf rjmp .-76 ; 0xd4 <duffsDevice(unsigned char const*, unsigned int) [clone .constprop.0]+0x44>
120: a9 e0 ldi r26, 0x09 ; 9
122: b1 e0 ldi r27, 0x01 ; 1
124: db cf rjmp .-74 ; 0xdc <duffsDevice(unsigned char const*, unsigned int) [clone .constprop.0]+0x4c>
126: e9 e0 ldi r30, 0x09 ; 9
128: f1 e0 ldi r31, 0x01 ; 1
12a: dc cf rjmp .-72 ; 0xe4 <duffsDevice(unsigned char const*, unsigned int) [clone .constprop.0]+0x54>
12c: a9 e0 ldi r26, 0x09 ; 9
12e: b1 e0 ldi r27, 0x01 ; 1
130: dd cf rjmp .-70 ; 0xec <duffsDevice(unsigned char const*, unsigned int) [clone .constprop.0]+0x5c>
132: e9 e0 ldi r30, 0x09 ; 9
134: f1 e0 ldi r31, 0x01 ; 1
136: de cf rjmp .-68 ; 0xf4 <duffsDevice(unsigned char const*, unsigned int) [clone .constprop.0]+0x64>
138: a9 e0 ldi r26, 0x09 ; 9
13a: b1 e0 ldi r27, 0x01 ; 1
13c: df cf rjmp .-66 ; 0xfc <duffsDevice(unsigned char const*, unsigned int) [clone .constprop.0]+0x6c>
13e: e9 e0 ldi r30, 0x09 ; 9
140: f1 e0 ldi r31, 0x01 ; 1
142: e0 cf rjmp .-64 ; 0x104 <duffsDevice(unsigned char const*, unsigned int) [clone .constprop.0]+0x74>
...
__tablejump2__():
284: ee 0f add r30, r30
286: ff 1f adc r31, r31
288: 05 90 lpm r0, Z+
28a: f4 91 lpm r31, Z
28c: e0 2d mov r30, r0
28e: 09 94 ijmp
Полный с++ код бы ещё, а то так трудно.
А там ничего особенного нет:
//
constexpr size_t bufLength = 1024;
static uint8_t buffer[bufLength];
void setup() {
}
void loop() {
duffsDevice(buffer,3);
duffsDevice(buffer,bufLength-50);
duffsDevice(buffer,bufLength);
}
void duffsDevice(const uint8_t *from, size_t count) {
size_t n = (count + 7) / 8;
switch (count % 8){
case 0:
do {
PORTC = *from++;
case 7: PORTC = *from++;
case 6: PORTC = *from++;
case 5: PORTC = *from++;
case 4: PORTC = *from++;
case 3: PORTC = *from++;
case 2: PORTC = *from++;
case 1: PORTC = *from++;
} while(--n > 0);
}
}