what's "<<" mean

Go To Last Post
24 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

what's "<<" mean
like this:

ldi r16, (1<<TWINT)|(1<<TWSTA)|
(1<<TWEN)
out TWCR, r16

and this:

	ldi zh,high(mytable<<1)
	ldi zl,low(mytable<<1)
	lpm
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It means "shifted left by".

Imagine a definition of "FOO" to be 3 (meaning bit 3), then

(1 << FOO) would give you mask that could be used to set bit 3.

It is standard C syntax.

Hope that helps.

Andy

If we are not supposed to eat animals, why are they made out of meat?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

<< and >> are bit shifts

x << y means: "shift x by y bits"

1 << 3 = 8(dec)
3 << 1 = 6(dec)

>> is the way to shift right

Alexander

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

SteveN wrote:
Hi again,

ldi zh,high(mytable<<1) 
ldi zl,low(mytable<<1)

At first I did not understand this one. I am used to seeing this:

ldi zh,high(mytable*2) 
ldi zl,low(mytable*2)

But then I remembered that shifting left by one position is equivalent to multiplying by 2. Shifting right is equivalent to dividing by 2. Sorry if you already knew this.

Do you know why you have to multiply "mytable" by 2?

Regards,
Steve

can you tell me what is the result after 1<<0b00000100
or 0b0b00000100 multiplying by 2

yes i still not understand why i have to multiply "mytable"by 2

thank you

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

1) high and low directive extracts higher and lower bytes from a word.

2) mytable is a constant, a label in program memory. Prog memory is organised in words, not bytes, so it must be multiplied by 2.

Ciao
Quix01

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

can you tell me what is the result after 1<<0b00000100
or 0b0b00000100 multiplying by 2

What number would you expect to get if you shift 1 left by 4 bits?

1 shifted left by zero bits is 1
1 shifted left by one bit is 2
1 shifted left by two bits is 4
etc.

What number would you expect to get if you multiplied the number 4 by 2?

You have to multiply the index into you array of integers by 2 because it is an array of integers and these are each 2 bytes in length.

Thus entry 0 is at offset 0, entry 1 is at offset 2, entry 2 is at offset 4.
Etc.

Andy

If we are not supposed to eat animals, why are they made out of meat?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ok,i have understood what's << mean
but
1) what's the different between 1<< and instruction "ROL"
2) i not very clearly understand why need multiplied by 2

thanx

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

1) what's the different between << and instruction "ROL"

ROL is an instruction and causes some action to happen.

using << is a way of specifying a number.

0b00010000
0x10
16
1 << 4

Are all ways of expressing the same number.

If we are not supposed to eat animals, why are they made out of meat?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The questions that you are asking all deal with constant "expressions" evaluated >>at assembly time<<, not while your application is running (those would be "instructions").

Look at the manual for the AVR Assembler. Every question you have asked in this thread has been addressed there. I looked in the Help file for AVRStudio 3.56 to verify.

Come back if you have any specific questions not covered in the manual.

Note: The AVR Assembler accepts manay operators in expressions that are similar to the equivlent C operators. Constants may also be in C form (e.g., 0x23).

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

i knows 1<< is mul by 2
but why in program
i need write
mytable<<1
or
mytable*2
but not "1<<mytable"

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

bigreat wrote:
i knows 1<< is mul by 2

No, it is not. 1<<x is (1 * (2 ** x)).

Let's say mytable is 234--a perfectly reasonable address.

1 << 234 is certainly NOT the same as 234 << 1 (which would be 234 * 2).

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

2) program memory is adressed in words. LPM/SPM instructions use 16 bit to adress any data in prog memory.

From AVR Instruction Set document LPM:
"Constant byte address is specified by the Z-register contents. The 15 MSBs select word address. For LPM, the LSB selects low byte if cleared (LSB = 0) or high byte if set (LSB = 1)...."

So it is the easiest way to multiply the label by 2. All constants defined by .db statement are aligned to LSB=0 automatically.

Hope that helps, ciao
Quix01

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

00000000
a 1 shifted left one place =
00000001
shifted left again (2nd shift) =
00000010
shifted left again (3rd shift) =
00000100
shifted left 4th time =
00001000

Sorry if this was a typo, Steve, but it's not actually accurate.

1 is a 1 shifted left by 0 places
2 is a 1 shifted left by 1 place
etc.

So a 1 shifted left by 4 places is 0010000

Cheers
A

If we are not supposed to eat animals, why are they made out of meat?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
i knows 1<< is mul by 2
but why in program
i need write
mytable<<1
or
mytable*2
but not "1<<mytable"

3<<1 is NOT equal to 1<<3

x<<y is same as saying x * 2^y

so x<<1 is x * 2^1 or x * 2

x<<3 is same as x * 2^3 or x * 8

3<<1 is same as 3 * 2^1 or 3 * 2
1<<3 is same as 1 * 2^3 or 1 * 8

the << operator is NOT commutative

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you for all of your help
i am an unquestionable a beginner of avr

I look up the dictionary what's the mean of word

Computer Science A set of bits constituting the smallest unit of addressable memory.

in avr
64K bytes=32K words
Z is 16bit(2 bytes)
so
mytable * 2
is a 16 bit address

is that right?

i have understood why need mul by 2

thanx

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

so why do people set register contents using stuff like SOME_REGISTER = (1 << 3) instead of '8'?   Or even weirder, why do I see stuff like (1 << 0)?  Why not just load the 'raw' value straight in? thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It is easier for humans to deal with bits rather than a collection of them.

1<<3 suggests we are dealing with bit number three. We might give that a name like PB3 that is just #defined to the value 3

of course, the compiler just converts this to a value.

the biggest challenge in programming is avoiding defects. So making it easy for humans to understand is the challenge.

 

 

Last Edited: Fri. Oct 3, 2014 - 01:46 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I will suggest... specificity and transportability.

 

What do I mean by specificity? Well let's imagine that your SOME_REGISTER already "contains" the number 5, ie 0b00000101 and you want to set another bit without changing the existing others. If you used SOME_REGISTER = ob00001000 or your '8', what happens to b0 and b2? They get clobbered. By using (1<<3), you retain all the other bits.

 

Transportability: Because the position of various flags in a register may change from device to device, it is much easier to use their abbreviated form, eg TOV1, than having to use its numeric form. You would hate to have to search your code, or someone else's, replacing one number with another just because you want to use a different AVR chip in your application.

 

Hope that helps.

 

Cheers,

 

Ross

 

Ross McKenzie, Melbourne Australia

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

so why do people set register contents using stuff like SOME_REGISTER = (1 << 3) instead of '8'?   [...] Why not just load the 'raw' value straight in?

 

This horse has been beaten to death here more times than we can count. If you manage to search this site you will find hundreds of discussions. Short list of arguments for doing this:

 

1. If you want to set e.g. bits 3, 5 and 6 of SOME register, many think it is clearer to

SOME_REGISTER = 1<<6 | 1<<5 | 1<<3;

than

SOME_REGISTER = 104;

or

SOME_REGISTER = 0x68;

In the first case it takes less than a second to think "bits 6, 5 and 3". For the other two you must do some "decoding", converting the decimal or hexadecimal number into binary. Lots of us can do that fairly easy, especially from hex, but it is still slower and unsafer than the first example.

 

Some use a macro to hide the shift operator

#define _BV(bit) (1<<bit)
  .
  .
  .
SOME_REGISTER = _BV(6 )| _BV(5) | _BV(3);

 

For bits in a I/O port register you could perhaps debate the technique, but when it comes to bits in the SFRs (Special Function Registers), e.g. a timer control register, writing the raw numerical values makes it very hard to decode what those bits actually are/do - unless you have a really good memory you must go into the data sheet to check each bit up. Using the symbolic names for the bits makes it a lot clearer.

 

Compare

TIMSK0 |= 1<<TOIE0;

with

TIMSK0 |= 0x01;

In the first case, there is a good chance you will read "Timer Overflow Interrupt Enable for timer/counter 0". In the second case you most likely need to consult the data sheet just to figure out what bit 0 is.

 

Or even weirder, why do I see stuff like (1 << 0)?

Yes, that is a case you might think of as "degenerated", but it is just a special case and a matter of doing things in a similar way throughout.

 

 

So... This is the reason - you did ask "why do people [...]?".  You might try to lure someone into a debate we've had for possibly hundreds of times, but I'm not your Huckleberry.. ;-)

 

----------

 

On a general note regarding all this - remember that code is read much more often than it is written.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

Last Edited: Fri. Oct 3, 2014 - 08:40 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

valusoft wrote:
What do I mean by specificity? Well let's imagine that your SOME_REGISTER already "contains" the number 5, ie 0b00000101 and you want to set another bit without changing the existing others. If you used SOME_REGISTER = ob00001000 or your '8', what happens to b0 and b2? They get clobbered. By using (1<<3), you retain all the other bits.
Not quite.

SOME_RESIGTER=8;
SOME_REGISTER=0b00001000;
SOMR_REGISTER=1<<3;
// are all the same and do not preserve 1 bits in SOME_REGISTER.
// To preserve 1 bits in SOME_REGISTER use |= .
SOME_RESIGTER|=8;
SOME_REGISTER|=0b00001000;
SOMR_REGISTER|=1<<3;

Just proves that I cannot expect to be able to cook 2 medium rare steaks and type accurately at the same time. The steaks were perfect though...

Moderation in all things. -- ancient proverb

Last Edited: Mon. Oct 6, 2014 - 01:56 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, I got into the habit of specifying bits that way ALL the time 'cause when I didn't, I sometimes didn't see where I had it wrong or right. Realize that the compiler turns (1<<3) into 8 by itself, and (1<<0) into 1 by itself.

 

So I do it just so it stands out in my dyslexic sight that I'm dealing with a bit. It's just a matter of readability. For example, in my train odometer code, I specified the divider between feet and miles as 5280 rather than 0x14a0, though some put ALL numbers in a hex.

 

I also use my defines thusly:

#define TriggerBit 3
#define TriggerPort PINC
#define TriggerDDR DDRC

// Set the port to input
TriggerDDR &= ~(1<<TriggerBit);

// Test the trigger pin
if (TriggerPort & (1<<TriggerBit))

I used to define the trigger bit as (1<<3) but then I was always getting it wrong in the code. "Should I use (1<<TriggerBit) or just (TriggerBit)?"

 

In xMega, it's even easier:

#define TriggerPort PORTC
#define TriggerBit 3

// Set the pin to input
TriggerPort.DIRCLR = (1<<TriggerBit);

// Test the trigger pin
if (TriggerPort.In & (1<<TriggerBit))

 

If you don't know my whole story, keep your mouth shut.

If you know my whole story, you're an accomplice. Keep your mouth shut. 

Last Edited: Fri. Oct 3, 2014 - 07:41 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I specified the divider between feet and miles as 5280 rather than 0x14a0

Why on Earth would anyone use hex in that situation? Neither the compiler nor the processor care at all. The choice of base is for the human reading it. You use hex or binary only when it makes sense.

I used to define the trigger bit as (1<<3) but then I was always getting it wrong in the code. "Should I use (1<<TriggerBit) or just (TriggerBit)?"

That is simply a problem of naming. (1<<3) is not a bit, it is a bit mask, so the name should reflect that. 

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you all for your patience & experience! Great community...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Koshchi wrote:

Why on Earth would anyone use hex in that situation? Neither the compiler nor the processor care at all. The choice of base is for the human reading it. You use hex or binary only when it makes sense.

I would wonder that too, but I've seen people do sillier things. Like putting "Hello World" in as {0x48,0x65,0x6c,0x6c,0x6f,0x20,0x57,0x6f,0x72,0x6c,0x64}

 

(I probably have that wrong.)

 

If you don't know my whole story, keep your mouth shut.

If you know my whole story, you're an accomplice. Keep your mouth shut.