This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430FR2355: Basic question on shift operator???

Part Number: MSP430FR2355


In using the above with CCS I am noticing some strange things with the shift operator.  I expected that if I shifted left OR right that '0' would be shifted in but I am seeing that if I shift right '1' is shifted in and if I shift left '0' is shifted in.....Is this the way shift works?

Ex. a uint8_t variable 

0xE1 >> 4

0xFFFE

I was hoping for 0x0E......

I am finding I have to typecast and do something like

(uint8_t(variable >> 4) & 0xF))

Is this correct or am I missing something?

Thanks

I am adding a follow up here....I am inverting my variable first as ~variable.....Seems that doing a bitwise negation on a uint8_t creates a signed int....Can someone tell me why a signed uint8_t isn't created?

  • I think this is explained by the The integer promotions section of  Implicit type promotion rules. That referenced StackOverflow post explains it better than I can.

  • I don't see the behavior you described. If I code:

    > volatile uint16_t rrr = (0xE1 >> 4);

    the compiler (.lst) gives me 0x000E in rrr.

    -----

    To answer your question: 0xE1 is an int (roughly "(int16_t)0xE1"). If you want it to be unsigned, append a "u" to the constant e.g. 0xE1u.

  • //                    if (((~relayRegister) >> 4) & 0xF)
                        if ((uint8_t)(~relayRegister >> 4) & (relayRegister & 0x0F))
    

    I believe you are correct....The above two lines of code act completely different....The commented out one does NOT work and the uncommented one works....Two completely different actions although they appear should yield the same result....

    Ughhh....Note to self 

  • the compiler (.lst) gives me 0x000E in rrr.

    I just tried running the following in a MSP430FR2355:

    #include <msp430.h> 
    #include <stdint.h>
    
    /**
     * main.c
     */
    int main(void)
    {
    	WDTCTL = WDTPW | WDTHOLD;	// stop watchdog timer
    	
    	volatile uint8_t variable = 0xE1;
    	volatile uint16_t rrr_a = variable >> 4;
        volatile uint16_t rrr_b = variable >> 4u;
    	volatile uint16_t rrr_c = 0xE1 >> 4;
    
    	return 0;
    }
    

    Where the generated assembler was:

     8      {
            main():
    00803c:   8231                SUB.W   #8,SP
     9      	WDTCTL = WDTPW | WDTHOLD;	// stop watchdog timer
    00803e:   40B2 5A80 01CC      MOV.W   #0x5a80,&WDT_A_WDTCTL
    11      	volatile uint8_t variable = 0xE1;
    008044:   40F1 00E1 0006      MOV.B   #0x00e1,0x0006(SP)
    12      	volatile uint16_t rrr_a = variable >> 4;
    00804a:   415F 0006           MOV.B   0x0006(SP),R15
    00804e:   0F5F                RRUM.W  #4,R15
    008050:   4F81 0000           MOV.W   R15,0x0000(SP)
    13          volatile uint16_t rrr_b = variable >> 4u;
    008054:   415F 0006           MOV.B   0x0006(SP),R15
    008058:   0F5F                RRUM.W  #4,R15
    00805a:   4F81 0002           MOV.W   R15,0x0002(SP)
    14      	volatile uint16_t rrr_c = 0xE1 >> 4;
    00805e:   40B1 000E 0004      MOV.W   #0x000e,0x0004(SP)
    16      	return 0;
    008064:   430C                CLR.W   R12
    17      }

    rra_a, rra_b and rra_c were all 14.

    For rra_a and rra_b the compiler emitted a RRUM.W instruction, for rrc_c the compiler emitted a constant.

    This was using the TI v21.6.0.LTS compiler with optimisation level zero.

**Attention** This is a public forum