¿Cómo puedo ordenar a mi compilador que use bytes de 8 bits en lugar de enteros de 16 bits?

6

Tengo el siguiente código en mi programa de microcontroladores:

int analogValue = ADCH;        // ADC Data Register

//
// Simple analog comparator. 
// If analogValue lower than threshold then toggle output high,
// Otherwise toggle it low.
//
if ( analogValue > 128 ) {
    PORTB = 0;                 // Port B Data Register
} else {
    PORTB = _BS( outputPin );  // Port B Data Register
}

Donde:

  • ADCH es el registro que contiene el valor del ADC
  • PORTB es un puerto de salida vital que alterna un LED

Al observar el código de ensamblaje resultante, me di cuenta de que está haciendo una comparación de 16 bits (líneas 40-44) donde, estrictamente hablando, solo 8 bits hubieran sido suficientes:

40:   90 e0           ldi     r25, 0x00       ; 0
42:   81 38           cpi     r24, 0x81       ; 129
44:   91 05           cpc     r25, r1
46:   14 f0           brlt    .+4             ; 0x4c <__SREG__+0xd>
48:   18 ba           out     0x18, r1        ; PORTB
4a:   f5 cf           rjmp    .-22            ; 0x36 <__CCP__+0x2>
4c:   28 bb           out     0x18, r18       ; PORTB
4e:   f3 cf           rjmp    .-26            ; 0x36 <__CCP__+0x2>

Me doy cuenta de que declaré analogValue como int , que de hecho es de 16 bits en AVR, pero ...

¿Cómo puedo ordenar al compilador que use una comparación de 8 bits? El IDE de Arduino me permite usar byte , pero avr-gcc por defecto no.

Consulte esta página para ver el programa completo y su código resultante desensamblado.

EDIT1:

Al cambiar de int a char se cambia el código de ensamblaje a:

14:   11 24           eor     r1, r1          ; r1 = 0
3e:   18 ba           out     0x18, r1        ; PORTB

Básicamente se omite la prueba por completo.

EDIT2: (Thnx: Wouter van Ooijen)

Al cambiar de int a unsigned char se cambia el código de ensamblaje a:

3c:   85 b1           in      r24, 0x05       ; ADCH
3e:   ...
40:   87 fd           sbrc    r24, 7          ; compare < 128 (well optimized)
42:   02 c0           rjmp    .+4             ; 0x48 <__SREG__+0x9>
44:   18 ba           out     0x18, r1        ; 24
46:   f7 cf           rjmp    .-18            ; 0x36 <__CCP__+0x2>
48:   98 bb           out     0x18, r25       ; 24
4a:   f5 cf           rjmp    .-22            ; 0x36 <__CCP__+0x2>
    
pregunta jippie

2 respuestas

18

Realmente creo que una mejor práctica que evita esta ambigüedad arquitectónica es incluir <stdint.h> y luego usar tipos declarativos como:

  • uint8_t para enteros de 8 bits sin signo
  • int8_t para enteros de 8 bits firmados
  • uint16_t para enteros de 16 bits sin signo
  • uint32_t para enteros de 32 bits sin signo

y así sucesivamente ...

    
respondido por el vicatcu
8

La definición estándar más o menos de un byte en C es 'carácter sin signo'.

    
respondido por el Wouter van Ooijen

Lea otras preguntas en las etiquetas