I'm trying to set bit 2 in TIMSK register and using the following C code:

TIMSK |= (1<<2);

Compiler makes the following code:

TIMSK |= (1<<TOIE1);
108:    89 b7           in  r24, 0x39   ; 57
10a:    84 60           ori r24, 0x04   ; 4
10c:    89 bf           out 0x39, r24   ; 57

So it is Read-Modify-Write operation which is a) slow, b) not very consistent as sometimes it is better not to disturb any excess bits.

However if I'd replace TIMSK with let's say PORTA I will get SEI as expected:

PORTA |= (1<<2);
108:    da 9a           sbi 0x1b, 2 ; 27

So how do I force the compiler to compile the instruction above as bit instruction instead of RMW?

Or this (TIMSK) register is not bit accessible?

  • 1
    \$\begingroup\$ The resulting code is not disturbing any excess bits. It reads the register, performs the OR and writes the result, it's exactly the OR-IS you typed in C code. Further, SEI is the global interrupt enable instruction (brother of CLI), you mean SBI as in your second code block. \$\endgroup\$
    – Asmyldof
    Jun 1, 2015 at 12:43

1 Answer 1


I found it:

Citation from original datasheet (page 20):

I/O Registers within the address range 0x00 - 0x1F are directly bit-accessible using the SBI and CBI instructions

So only first 32 registers are bit-accessible. TIMSK has address 0x39 - so it's pretty high above the range :(

  • \$\begingroup\$ Exactly. It's a trade-off for the choices they made way back when to keep things stream-lined in most-use situations. They do try to get the most likely candidates into the lower 32, though. How often do you write TIMSK? How often PortA/B/C? \$\endgroup\$
    – Asmyldof
    Jun 1, 2015 at 12:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.