Understanding the Jumps in the ATMEGA 328p with Assembler

Check your definitions

Rick
7 min readFeb 27, 2023

Program counter: the purpose of the Program Counter is to store or keep track of the current instruction that is being executed at a given time.

Cycle Counter: keeps track of the amount of cycles that have happened since the start of the code.

ATMEGA 328P Pin out

The Atmega328P has 3 ports: B, C and D

Port B has 8 pins, each pin corresponds to a bit of information. The can also be used as I/O. In addition they’re used as an input for an oscillator or a crystal which gives a relatively stable square signal. These signals give synchrony to our digital system.

Some manufacturers build an oscillator circuit within the chip. Some of these resonators are based on RLC circuits. However they’re not so accurate because some factors like heat can change the resistance and humidity can affect the capacitors. For these reasons these oscillators tend to be low frequency. So if we want a higher frequency we need to use an external component called Crystals. These crystals are made out of quartz. The manufacturers often give a datasheet where we can see the optimal way of setting an oscillator circuit with this crystal and some capacitors. If we decide to use an external oscillator, we have to consider that we are losing two pins or two bits on the port B.

Port C has 7 pins, one of them is the reset button pin PC6 is the one that can be used as a reset button. In the Datasheet or in the image above you can see that it has the function PCINT14, PCINT stands for PC interruption. We will be discussing interruptions in a different class.

Port D has 8 pins Among these pins we can find INT0/INT1 which are special interruptions (they can be used to have fast and immediate interruption; more of their uses also on a different class).

tips and tricks: leave some unused ports as inputs Always be sure of what pins are used for what in your application. What you don’t want to happen is that you have to use a certain pin INT0/INT1 to do a specific task you discovered late in development and find out you’re using that pin already to turn on a LED.

With the cycle counter we could calculate the power usage per hour. If we know the supply voltage and the current drawn we calculate power. Now we can use the Cycle Counter to figure out how many cycles would the microcontroller make while executing a certain piece of code. So then we can calculate W/h and also how much a battery would last. Directives are used so that the assembler knows what parts of the code goes to what part of the memory inside the flash memory, RAM memory or the EEPROM memory. .CSEG is used to decide where the code segment is going to start in the memory. For example:

.CSEG
.ORG 0x0A
Start:
ldi r16, 0x00
Out DDRB, r16
Out DDRC, r16 // here we initialize port B and C as inputs
ldi r16, 0xff
Out DDRD, r16 // port D as the output

AndOperation:
In r16, pinb // first operand through port B
In r17, pinc // Second operand through port C
And r16, r17 // B and C
Out Port,r16 // D = B and C (port D shows the product of B & C)
rjmp AndOperation // we close our loop.

note: the code above is written in assembler not C++

The .CSEG / .ORG 0A portion of the code defines that the code segment (.CSEG) is going to start at the memory address 0x0A (10 in Hex). So that would imply that the next line of code would be at 0x0B.

directives do not occupy memory space because they tell the assembler where to put what in the flash program. The Flash memory only receives Instructions which have an opcode.

Note that the same applies to labels, for instance, the label «Start’’ doesn’t occupy any memory space. What it does is point to a memory address so that when the microcontroller makes a jump instruction it knows where to jump.

Jumps

There are two types of jumps, conditional and unconditional

Conditional jumps

which naturally depend on the output of a condition such as an If statement. Also, you could consider instructions of the type branch.

CPSE: Compares and skips the next line of code if the operands are equal.

SBIC / SBIS: The next line of code is skipped if a I/O register is on low(for sbic) or high(for sbis). Also like in the MIPS processor we have instruction of the type Branch.

Unconditional jumps

just like the name implies, don’t need a given reason to jump to another instruction address.

rjmp: A relative jump means, relative to your position, move toward this position.It’s Formula: PC+k+1, meaning that if i declare a jump, for example 10 memory addresses in front of you, the rjmp is going to jump 10 addresses + 1. This particular Instruction takes two Clocks cycles to be executed.

ijmp: An indirect jump to (Z) it mainly depends on the value of the Z flag of the ALU.

eijmp: An extended indirect jump to (Z), has more range to jump than ijmup

jmp: An absolute jump has way more range than rjmp, the rjmp instruction can only jump up to a certain point, the jmp instruction can jump way further. Also since it takes more time to execute and it also takes up more memory space; down below we can observe that when we use a jmp instruction the memory address skips 1 extra spot.

representation of assembler code in memory

The numbers in black represent the address number inside the flash memory (the part of the memory that contains the code) The numbers in the dark redish color represent the machine code (which is in hexadecimal) As you can see the Jmp instruction has more numbers, that is because it’s a 32 bit Instruction. (In class the teacher didn’t say why and nobody asked why. I assume that not only it was determined by the designers but also (and pretty obviously) it has some advantages like the ability to jump to anywhere in the code)

The second interesting thing is that the next line of code (the one below the Jmp instruction) is saved to the address 000003 and not 000002. That’s not a mistake. Earlier we said that the Jmp Instruction occupies two memory addresses so the next line is in address 000003 not 000002.(remember that labels and directive don’t occupy memory space).

Understanding a relative jump

Let’s try to make sense of this code part by part.

Let’s see the comments in green first. We already know the difference between relative and normal jump, so we’re gonna check the positive and negative. A positive jump is just a jump forward. A jump to a memory address that’s later in the code. Similarly, a negative jump is a jump backwards.

The numbers in cyan and yellow are the instruction codes in binary instead of hexadecimal. If we check the AVR instruction set we can see that the light blue part corresponds to the Opcode (which is what the processor uses to identify what resources to use with a given instruction, most of the time it’s used by the ALU).

The yellow part corresponds to the constant k. This constant k is defined in the Instruction set manual as a generic constant, in this case we use it to identify where or how far the jump needs to go.

Now let’s take a moment to analyze step by step each jump or rjmp instruction and make sense of where in the code it will jump to. For the first jump it’s pretty straightforward, the first jump is set to go to label_1, this is in the address 000100 so naturally the machine code has as the constant k equal to 0x0100 (in binary it would be 1 0000 0000). The next jump instruction is of type relative jump. So this is a bit different.

Remember that in the AVR instruction-set manual we can see the formula for this instruction, which is PC <- PC + k + 1. In this case remember that the rjmp works by adding the current PC(program counter) value plus k plus 1. So for the first rjmp, the value of k can be determined like:

  • Current address = 0x0101
  • label_2’s address = 0x0110
  • label_2 address — Current Address — 1 = k
  • 0x0110–0x0101–1 = E or 1110 in binary or 14 in decimal

And as we can see the machine code is = 1100 0000 0000 1110 . Remember that the yellow part is k and the cyan is the OpCode The rest of the code can be easily analyzed if we understand these concepts.

--

--

Rick
Rick

Written by Rick

I blog about everything I learn, Digital Image Processing, Data Science, IoT, Videogame design and much more :)

No responses yet