avr assembler and supported instructions

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

Hello i'm writting a assembler for the avr8 (octasm).First i wrote a list of instructions and assemble it using the avr studio configured for the atmega16u4 (the one i have) and i found a few problems:
From the docs there is a 32 and 16 bits versions of 'lds' instruction,but avr assembler only produces the 32 bit opcode,why?
what happens if there is a invalid or unsupported instruction?
interrupt,reset,crash?

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

I don't know about octasm (only one for 80x86 platforms).
Information about the opcodes can be found here
I would never rely on a particular behaviour of unsupported instructions if it is not specified by the manufactorer (which AFAIK is in case of AVR8).

Edit: Please pay attention, that not all opcodes are implemented in all devices. Also take a look at the device-specific datasheet.

/Martin.

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

mtaschl wrote:
I don't know about octasm (only one for 80x86 platforms).
Information about the opcodes can be found here
I would never rely on a particular behaviour of unsupported instructions if it is not specified by the manufactorer (which AFAIK is in case of AVR8).

Edit: Please pay attention, that not all opcodes are implemented in all devices. Also take a look at the device-specific datasheet.


the device datasheet has a list of instructions but nothing about encoding ,and 'lds' has 2 posible encodings.Perhaps the avr assembler uses the 32bit form because programmers were to lazy to make optimizations.
X86 cpus have a invalid instruction exception (int6)
does the avr8 have such a thing?
And of course ,octasm is for x86 since i'm still working on the avr8 implementation.

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

This has come up before. Atmel have ruined the opcode manual (IMHO) by trying to cover Xmega and the braindead Tiny10 family in addition to the traditional tiny/mega. I actually keep an old copy of the manual that was before these recent additions because it's much easier to read for tiny/mega. I could send you a copy if you are interested?

I think a recent thread said that the shortened form of LDS was for the tiny10 family which has very limited SRAM (like never more than 64 bytes or something?)

There are no exceptions in the AVR and it appears (as the recent thread about 0xFFFF has shown) to execute the nearest instruction to an invalid one - IOW it's not doing complete decode.

I have to ask why you think the world needs yet another AVR assembler? What is your one going to offer that Atmel Asm2, avr-as, avra or all the rest don't already offer? And do you think it wise for someone who doesn't already fully understand the AVR mnemonics to attempt to write an assembler anyway?

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

clawson wrote:

I have to ask why you think the world needs yet another AVR assembler? What is your one going to offer that Atmel Asm2, avr-as, avra or all the rest don't already offer? And do you think it wise for someone who doesn't already fully understand the AVR mnemonics to attempt to write an assembler anyway?

Thanks for the answers.
I'm not yet interested on atiny.
I already found in the avr studio the header files for specific chips ,but wich are the ones with the suported instructions used by the avr assembler?

I have been programing with the avr studio for a month and already wrote some small programs ,like a dc-dc converter or one that reads the temperature sensor and prints the result on a display.After this i found that the avr assembler is the second worst assembler i know,just after the awl used in siemens plcs.
First with Octaos i can assemble and program the chip via usb
with only one key press.while the flip program is not integrated on avr studio.This reduces the program-test cycle time.
Second ,the avr assembler is a very old style assembler with multiple instructions for doing similar things,
for example,the in and lds instructions read from memory
but the programmer must know the memory adress to decide wich instruction is best ,making useless the use of symbols.
Or the jmp-rjmp or-ori etc..,with octasm i just wrote '[port]=r0' or 'jmp label' and leave the assembler to select the best encoding.Also since i'm a experienced x86 programmer i prefer the x86 nemonics jc isntead of brcs etc...
There was not really needed but i already have octasm and like it(i wrote a operating system with it),and is not to much work for me to add a new instruction set,is mostly done now.

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

Quote:

After this i found that the avr assembler is the second worst assembler i know

So how did you find avr-as as an alternative?
Quote:

for example,the in and lds instructions read from memory
but the programmer must know the memory adress to decide wich instruction is best ,making useless the use of symbols.

Not if you use the AVR001 macros.

As for a list of opcodes - why would they be in header files? They are built into avrasm2.exe bt you may find this page from the avr-as manual useful:

http://sourceware.org/binutils/d...

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

I second Cliff's understanding of the 16-bit versus 32-bit LDS op-codes.

If you're using an ATtiny10 (or the handful of other AVRs based on the AVR8L core), then the 16-bit LDS exists, and the 32-bit LDS is not supported.

If you're using any other 8-bit AVR, including the XMegas, then the 32-bit LDS exists, and the 16-bit LDS is not supported -- in fact, the byte pattern associated with the 16-bit LDS has a different meaning in the rest of the 8-bit AVR family.

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

IMO, the chance of bugs (which will add computer-generated bugs to your own user-generated bugs) in your (self-written) assembler is much higher than any possible pain using a prooven existing one.
The reason for in/lds and out/sts is the hardware (avr8) and not the assembler. And as already posted above, this can be fixed with macros.
And if you don't want to mess with the chip-architecture, than you could switch to a high-level language, where the compiler will do this for you.

/Martin.

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

Quote:

Second ,the avr assembler is a very old style assembler with multiple instructions for doing similar things,
for example,the in and lds instructions read from memory

I guess a LOL on that one. The assembler has mnemonics that carry out the instruction set of the AVR. That instruction set has op codes to deal with different address spaces (in that example). there are a few mnemonics that are aliases such as CLR (IIRC), but it sounds like you are really railing primarily at the AVR architecture.

The Atmel AVR assembler(s) are indeed simple and perhaps "old style" being monolithic and with no linker and/or locator passes. It is what it is. IIRC user "js" has lived with it in production for many years; I suspect others as well. And at least one well-know AVR C compiler uses the Atmel assembler as the back end.

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

Quote:

being monolithic and with no linker and/or locator passes

Except that avr-as breaks those bounds anyway.

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

Quote:
what happens if there is a invalid or unsupported instruction?
interrupt,reset,crash?
If you mean "what happens if I put an instruction in my code that the device that I am using does not support?", then the answer is: the assembler will complain when you assemble the code. There will not be any interrupt, reset or crash since the code would never make it into your device.
Quote:
the avr assembler is a very old style assembler with multiple instructions for doing similar things,
for example,the in and lds instructions read from memory
But in many cases it is important that the programmer knows which instruction is actually being used, particularly if timing is critical since the different instructions take different amounts of time to execute.

Regards,
Steve A.

The Board helps those that help themselves.

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

I feel like I'm one of the few who understand the OP's thougts :D

When I first seen the AVR instruction set and the Atmel AVR Assembler many years ago, I was just shocked of how ugly and irrationally they are PRESENTED. Being mostly an x51 ASM user, I decided to create the x51-style translation of them. I found a brilliant multiplatform assembler - the AS by Alfred Arnold - which supported the operand/keyword overload (like in C++), and have written the appropriate macros to substitute the tons of ld/ldi/mov/std/sts etc. with a good old MOV macro implementation which automatically detected the addressing mode and operands and generated the appropriate native AVR instruction, i.e.:

mov  r1,r2     -> mov r1,r2
mov  r16,#45   -> ldi r16,45
mov  r16,45    -> lds r16,45
mov  [X+],r2   -> st X+,r2
mov  r2,[Y+31] -> ldd Y+31,r2
movw r2,r4     -> movw r2,r4
movc r0,Z      -> lpm
movc r2,Z+     -> lpm r2,Z+
movc Z,r0      -> spm

The same was done with all instructions which natively required different syntax for immediate and register operations - "and/andi" etc. were unified to simple "and" and so on.

Finally I replaced the "rcall" with "call", "rjmp" with "jmp", "call/jmp" with "lcall/ljmp" and "brXX" with "jYY" (e.g. brcs -> jc, breq -> jz etc.) and "eor" with "xor" - and the life became much easier :D

I do agree with the OP and do undoubtfully confirm that the Atmel AVR Assembler(2) is one of the most stupid and dumb assemblers I ever seen - and I have really seen lots of them :D

BTW, the OP - Octavio Vega Fernandez - perfectly knows what he's talking about - and I couldn't expect anything else from the person who wrote his own PC OS in pure assembler - the OctaOS. !Bravo, Octavio! :)

Warning: Grumpy Old Chuff. Reading this post may severely damage your mental health.

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

Quote:

Finally I replaced the "rcall" with "call", "rjmp" with "jmp", "call/jmp" with "lcall/ljmp"

That may make sense to you--given your background and the way you "translate" your experience and map it to AVR.

But it ain't a LCALL/CALL. It really >>is<< an RCALL--relative and CALL--absolute. If youcare to call (pun intended) that ACALL...

Much ado about nothing, for me. And I've worked in x51 and Moto and PDP and x86 and ... over the years. Fortunately for me right now, I'm primarily AVR.

Still, OP seems to be railing against the AVR architecture with multiple address spaces. I'd be curious whether in less experienced hands the overloaded MOV generates subtle hard-to-find errors.

Some years back, I suffered from "IDE overload" in the same manner. Each product/platform IDE was good enough in its own right. but mixing them on a daily/weekly basis and not having identical command structures made it annoying at best, and counter-productive at worst. So I switched all my bulk editing to MED and do little if any in the IDEs.

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

The reason I have cut the rcall/rjmp to call/jmp was only saving a bit of typing - the native AVR call/jmp are used much more rarely than rcall/rjmp, so cutting an R was appropriate. And in most cases I just don't care if the call/jmp is relative or absolute or short or long or whatever, so using L was just a coincidence.

After doing this simple work (I'm recalling it hardly took me more than a few hours) I was able to switch to a different instruction set seamlessly and very quickly. After some short "transient period" I came back to the native AVR instruction set and never returned to my "quasy instruction set" later.

BTW, some of ancient PIC users may remember the Parallax PIC assembler which used the same x51-like approach to this crazy PIC mnemonics (movlw, btfsc, addwf, decfsz, iorwf, retfie etc.). For me the x51/x86/Z80 mnemonics still are the most appropriate and logical ones in industry.

FYI the "overloaded mov" can not generate any "hard to find" error simply by its automatic nature, but the less (and even more) experienced PERSON can - because he's just a human :D

Warning: Grumpy Old Chuff. Reading this post may severely damage your mental health.

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

Quote:

only saving a bit of typing - the native AVR call/jmp are used much more rarely than rcall/rjmp, so cutting an R was appropriate.

Quote:

after doing this simple work

The Atmel AVR assembler gives an instruction count at the end of the listing. (e.g., 123 uses of "RCALL")

So, given your rationale you should order your ersatz mnemonic set so the most-used are single character mnemonics, etc. Lessee--for one of my 64kB projects:

ATmega1280 instruction use summary:
.lds  :   0 .lds.l:   0 .sts  :   0 .sts.l:   0 adc   : 179 add   : 215 
adiw  :1057 and   :  49 andi  : 207 asr   :   0 bclr  :   0 bld   :  73 
brbc  :   0 brbs  :   0 brcc  :   5 brcs  :   0 break :   0 breq  : 445 
brge  :  11 brhc  :   0 brhs  :   0 brid  :   0 brie  :   0 brlo  : 193 
brlt  :  17 brmi  :   4 brne  : 536 brpl  :   2 brsh  : 141 brtc  :   3 
brts  :   0 brvc  :   0 brvs  :   0 bset  :   0 bst   :   1 call  :2323 
cbi   :  17 cbr   :   1 clc   :   0 clh   :   0 cli   :   9 cln   :   0 
clr   : 282 cls   :   0 clt   :  12 clv   :   0 clz   :   0 com   :  34 
cp    : 165 cpc   : 137 cpi   : 892 cpse  :   0 dec   :  21 des   :   0 
elpm  :   0 eor   :   6 fmul  :   0 fmuls :   0 fmulsu:   0 icall :  10 
ijmp  :   0 in    :  54 inc   :  18 jmp   : 246 ld    : 489 ldd   :2046 
ldi   :3209 lds   :1649 lpm   :  76 lsl   :  69 lsr   :  27 mov   : 731 
movw  : 765 mul   : 166 muls  :   0 mulsu :   0 neg   :   3 nop   :   0 
or    :  79 ori   :  45 out   :  73 pop   :  98 push  :  98 rcall : 134 
ret   : 260 reti  :   7 rjmp  :1044 rol   :  73 ror   :  17 sbc   :  20 
sbci  : 324 sbi   :  24 sbic  :  12 sbis  :  16 sbiw  : 149 sbr   :   3 
sbrc  :  16 sbrs  : 140 sec   :   0 seh   :   0 sei   :   7 sen   :   0 
ser   :   1 ses   :   0 set   :  59 sev   :   0 sez   :   0 sleep :   0 
spm   :   0 st    :1842 std   : 555 sts   : 881 sub   :  18 subi  : 533 
swap  :  25 tst   :  22 wdr   :   7 
Instructions used: 75 out of 117 (64.1%)

So then obviously CALL is now C and LDI is L and ...

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

Quote:
with no linker and/or locator passes.
HC05, HC11 assemblers from PE micros.

I don't believe that a linker is required for the majority of embedded work nowdays, at least never with my kind of projects. I have only been given 1 good reason to use a linker in the case where one buys a library of sort from someone and they are not prepared to release the source file.

I love having multiple opcodes for the same instruction otherwise I'd be using a PIC. :shock:

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

In case someone is interested ,my assembler is available on my web page,there is one version for DOS 'OCTAS17.ZIP' ,it produces plain binary files,so a bin to hex converter is needed an also the atmel flip program.
And another included in Octaos 'FD25.ZIP',this one also includes a flip like program,so if the microcontroller is attached to the usb port it will be programmed too.