## [ASM] Opcode collision in AVR instruction set ?

13 posts / 0 new
Author
Message

Hello,

LDS (16-bit version) is defined as 1010 0kkk dddd kkkk (big endian)

and

LDD (using Z-pointer with displacement) is defined as 10q0 qq0d dddd 0qqq (big endian)

Now given following opcode

0xa400 (big endian) in hexadecimal and 1010 0100 0000 0000 (big endian) in binary,

this might be

lds r16, 0x20

because of

1010 0100 0000 0000 (0xa400)
1010 0kkk dddd kkkk (LDS 16-bit)

and ADDR[7:0] := (¬INST[8], INST[8], INST[10], INST[9],
INST[3], INST[2], INST[1],  INST[0])

==> ADDR[7:0] = 2^5 (INST[10] = 1) = 32 = 0x20

and r16 because of dddd = 0, with 16 <= d <= 31 ==> rd = 16

but the same opcode might be

ldd r0, Z+40

because of

1010 0100 0000 0000 (0xa400)
10q0 qq0d dddd 0qqq (LDD, Z + disp.)

so q = 2^3 + 2^5 = 40 (decimal) ==> Z+40

and d = 0 ==> rd = r0

Now "ldd r0, Z+40" and "lds r16, 0x20" are obviously not the same instruction.

The only way in which this collision can not cause problems would be that both instructions
are never supported by a microcontroller at the same time.

Does anyone know more ?

I'm confused but maybe I never came across this conundrum in the past 21+ years of using the assembler.

John Samperi

Ampertronics Pty. Ltd.

https://www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

Okay, I have tried to find an opcode for LDS without colliding with LDD.

The result is that I can not find an opcode for LDS-only. Whenever I try to manipulate some bits in order to find one, it collides with either LDD (Z pointer), LDD (Y pointer), STD (Y pointer).

So my assumption is that there exists either LDS or Load/Store with displacement instructions on a single type of microcontroller, but never both.

Your decoder needs to track which CPU version you have: AVRe vs AVRxm vs AVRxt vs AVRrc.

Look at the instruction manual.

EDIT: look at the last line below

Last Edited: Fri. Mar 12, 2021 - 01:00 AM

Finally, the AVRtiny core deletes the 2-word LDS LDS and STS STS instructions for direct RAM addressing, and instead uses the opcode space previously assigned to the load/store with displacement instructions for new 1-word LDS LDS and STS STS instructions which can access the first 128 locations of general-purpose RAM, addresses 0x40 to 0xBF. https://en.wikipedia.org/wiki/At...

So they removed 32-bit STS/LDS from AVRtiny core and replaced the displacement instructions by 16-bit LDS/STS.

Good old Studio 4 mentions this:

(note this is prob from 10 years ago):

Devices using the AVR8L CPU: ATtiny10, ATtiny20, ATtiny40.

The AVR8L CPU core is a low-cost version of the AVR, and lacks certain features found in regular AVR, most notably:

• Register file is 16 registers instead of 32 (R16-R31). The assembler will produce an error message if registers R0-R15 are used.

• Instruction set is reduced, see table below. Notice that the LDS/STS instructions are different from regular AVRs, it is a 1-word instruction with an addressing range of 128 bytes. Also notice that the LPM instruction is eliminated; the Flash memory is mapped into data memory and can be read by means of using the LD instruction.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

avrcandies wrote:

Good old Studio 4 mentions this:

(note this is prob from 10 years ago):

Devices using the AVR8L CPU: ATtiny10, ATtiny20, ATtiny40.

The AVR8L CPU core is a low-cost version of the AVR, and lacks certain features found in regular AVR, most notably:

• Register file is 16 registers instead of 32 (R16-R31). The assembler will produce an error message if registers R0-R15 are used.

• Instruction set is reduced, see table below. Notice that the LDS/STS instructions are different from regular AVRs, it is a 1-word instruction with an addressing range of 128 bytes. Also notice that the LPM instruction is eliminated; the Flash memory is mapped into data memory and can be read by means of using the LD instruction.

Thank you. I just found an article on wikipedia mentioning this.

MattRW wrote:

Your decoder needs to track which CPU version you have: AVRe vs AVRxm vs AVRxt vs AVRrc.

Look at the instruction manual.

EDIT: look at the last line below

Yep, I see. Thank you. I knew that some instructions are not supported by all controllers, but I did not know that there are possible opcode collisions if I simply support all of them.

Quote:

Yep, I see. Thank you. I knew that some instructions are not supported by all controllers, but I did not know that there are possible opcode collisions if I simply support all of them.

It matters also if you want to install breakpoints and/or provide instruction timing.

MattRW wrote:

Quote:

Yep, I see. Thank you. I knew that some instructions are not supported by all controllers, but I did not know that there are possible opcode collisions if I simply support all of them.

It matters also if you want to install breakpoints and/or provide instruction timing.

Another question: Are there any other possible opcode collisions besides LDS ?

Milo-D wrote:

Are there any other possible opcode collisions besides LDS ?

I think STS and STD.

MattRW wrote:

Milo-D wrote:

Are there any other possible opcode collisions besides LDS ?

I think STS and STD.

Thank you for the quick respond ^^ I am currently looking at the appendix...so all the other cores (AVRe, AVRe+, etc.) are basically extensions (or reduced sets) of the classic instruction set (except AVRrc which has two special instructions lds/sts 16-bit version) ?

Well, yeah.  Otherwise they'd (hopefully) call them something besides "AVR."
Major departures:

AVRrc only has 16 registers.

Very old RAM-less chips (AT90S1200, for example) are missing RAM-specific instructions (no X or Y, no stack instructions.)

Newer chips do not have the CPU registers (R0-R31) mapped into the memory space.

There are pretty good tables in the new Instruction-set manual...