How can I understand what the opcode is from reading the instruction set?

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

Good day,

 

I am trying to understand what the opcode might be for SUB when using 8-bit AVR. I have this to look up in http://lyons42.com/AVR/Opcodes/A... and when I look up SUB, I get opcodes 18xx, 19xx,1Axx and 1Bxx all depending on how the registers are being mixed together. How can I understand this, does the Micro-

Controller have four opcodes for SUB: 18xx, 19xx,1Axx and 1Bxx or 18,19,1A,1B depending on what registers its being used with?

 

I also looked up instruction set for AVR in general http://ww1.microchip.com/downloa...

and get for SUB 16-bit opcode, but that can not be right for 8-bit controller, right?

Last Edited: Tue. Oct 6, 2020 - 12:11 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


LeonSteinn wrote:
for SUB 16-bit opcode, but that can not be right for 8-bit controller, right?

Both of the resources you cited show 16-bit opcodes.

 

Picking an AVR datasheet at random:

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

LeonSteinn wrote:
I get opcodes 18xx, 19xx,1Axx and 1Bxx all depending on how the registers are being mixed together. How can I understand this,

The Instruction Set document from Microchip shows you how they are encoded into the 16-bit opcode

 

http://ww1.microchip.com/downloads/en/DeviceDoc/AVR-Instruction-Set-Manual-DS40002198A.pdf - see section 5.119 on page 141.

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

If I build:

#include <avr/io.h>

uint8_t a,b;

int main(void)
{
	a = a - b;
	while(1) {
	}
}

The .LSS file shows:

	a = a - b;
    80d4:	80 91 01 20 	lds	r24, 0x2001	; 0x802001 <a>
    80d8:	90 91 00 20 	lds	r25, 0x2000	; 0x802000 <__DATA_REGION_ORIGIN__>
    80dc:	89 1b       	sub	r24, r25
    80de:	80 93 01 20 	sts	0x2001, r24	; 0x802001 <a>

The bytes of the SUB opcode are 0x89, 0x1B but this is little endian so the 16 bit opcode is actually 0x1B89. The opcode manual says:

 

 

so if you write 0x1B89 as 0001 1011 1000 1001 then the 0001 10 at the start are fixed and tell you this is "SUB" but then the r and d bits contains the encoding of the specific registers used (r24, r25). rrrrr is given by the 3rd bit in the second nibble then all the bits of the 4th nibble so it is 1 1001. 0b11001 is 25 so that is the encoding for R25. The d bits are the last bit of the 2nd nibble and the four bits of the third nibble so is 1 1000. 0b11000 is 24. So that is the encoding of R24.

 

The complete opcode is 0x1B89.

 

All AVR opcodes are some multiple of 16 bits. More complex instructions like JMP might take two lots of 16 bits for example. When the AVR makes an opcode fetch it reads TWO consecutive bytes from memory. This is actually why Atmel have a rather nasty habit of always referring to flash memory in terms or word size/addressing not byte addressing. So in a 32K (bytes) 328P they would tell you the flash is 16K words. That's because the most opcodes you could get into it (assuming you picked to use only single word opcodes) would be 16384 operations.

 

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


as clawson said:

 

Note that this pattern of encoding the registers appears in many (all?) similar instructions

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

LeonSteinn wrote:
and get for SUB 16-bit opcode, but that can not be right for 8-bit controller, right?
This seems to the initial source of confusion - the idea that an "8bit micro" can only make 8 bit opcode fetches (like a Z80 or 6502 or something). Even something like a  Z80 would make multiple byte opcode fetches. The LD HL,12345 opcode for example has 0x21 in the first byte then the binary value for 12345 in the next two bytes. Of course with a CISC chip like Z80 this didn't all happen in a single cycle. In fact the minimum instruction timing for Z80 was four cycles and a LD HL,nnnn was 10 cycles. Some of those cycles would be involved in getting the 3 bytes of the opcode. What's different about AVR is that it is RISC so it manages to do most things in a single cycle and that involves picking up two bytes at a time from flash.