From: Herbert Kleebauer on
Have to write some AVR code and therefore have read the
AVR Instruction Set manual and tried the assembler included
in AVR studio. I think the used syntax is completely
unusable, so I decided to write my own assembler. A very
first version can be downloaded from:

ftp://137.193.64.130/pub/assembler/adela.zip

Maybe there are some AVR experts who can give some suggestions
for an improvement or are even willing to do some testing.

The used syntax:


*******************************************************************
* Instruction set *
*******************************************************************

add.b ri,rj ; i,j=0..31 ADD
addc.b ri,rj ; i,j=0..31 ADC
addq.w #imm6u,ri|rj ; j=24,26,28,30 i=k+1 ADIW
and.b #imm8,rj ; j=16..31 ANDI
and.b ri,rj ; i,j=0..31 AND
asr.b #1,rj ; j=0..31 ASR

bcc.b label ; C=0 BRCC
bcs.b label ; C=1 BRCS
beq.b label ; Z=1 BREQ
bge.b label ; S=(N eor V) = 0 BRGE
bhcc.b label ; H=0 BRHC
bhcs.b label ; H=1 BRHS
bhs.b label ; C=0 BRSH
bic.b label ; I=0 BRID
bis.b label ; I=1 BRIE
blo.b label ; C=1 BRLO
blt.b label ; S=(N eor V) = 1 BRLT
bmi.b label ; N=1 BRMI
bne.b label ; Z=0 BRNE
bpl.b label ; N=0 BRPL
btc.b label ; T=0 BRTC
bts.b label ; T=1 BRTS
bvc.b label ; V=0 BRVC
bvs.b label ; V=1 BRVS

br.w label RJMP
bsr.w label RCALL

cmp.b #imm8,rj ; j=16..31 CPI
cmp.b ri,rj ; i,j=0..31 CP
cmpc.b ri,rj ; i,j=0..31 CPC
dec.b rj ; j=0..31 DEC
eor.b ri,rj ; i,j=0..31 EOR
fmuls.b ri,rj,r1|r0 ; i,j=16..23 FMULS
fmulsu.b ri,rj,r1|r0 ; i,j=16..23 FMULSU
fmulu.b ri,rj,r1|r0 ; i,j=16..23 FMUL
halt BREAK
inc.b rj ; j=0..31 INC

jmp.l (*|r31|r30) EIJMP
jmp.l label JMP
jmp.w (r31|r30) IJMP
jsr.l (*|r31|r30) EICALL
jsr.l label CALL
jsr.w (r31|r30) ICALL

lsr.b #1,rj ; j=0..31 LSR

move.b #imm8,rj ; j=16..31 LDI
move.b ri,rj ; i,j=0..31 MOV
move.b adr,rj ; j=0..31 LDS
move.b ri,adr ; i=0..31 STS

move.b (r27|r26),rj ; j=0..31 LD
move.b imm6(r29|r28),rj ; j=0..31 LDD
move.b imm6(r31|r30),rj ; j=0..31 LDD
move.b ri, (r27|r26) ; i=0..31 ST
move.b ri,imm6(r29|r28) ; i=0..31 STD
move.b ri,imm6(r31|r30) ; i=0..31 STD

move.b -(r27|r26),rj ; j=0..31 LD
move.b -(r29|r28),rj ; j=0..31 LD
move.b -(r31|r30),rj ; j=0..31 LD
move.b ri,-(r27|r26) ; i=0..31 ST
move.b ri,-(r29|r28) ; i=0..31 ST
move.b ri,-(r31|r30) ; i=0..31 ST

move.b (r27|r26)+,rj ; j=0..31 LD
move.b (r29|r28)+,rj ; j=0..31 LD
move.b (r31|r30)+,rj ; j=0..31 LD
move.b ri,(r27|r26)+ ; i=0..31 ST
move.b ri,(r29|r28)+ ; i=0..31 ST
move.b ri,(r31|r30)+ ; i=0..31 ST

move.b +(sp),rj ; j=0..31 POP
move.b rj,(sp)- ; j=0..31 PUSH

move.b ?adr6,rj ; adr6=0..63 j=0..31 IN
move.b ri,?adr6 ; adr6=0..63 i=0..31 OUT


move.bit rj[imm3],sr[6] ; j=0..31 BST
move.bit sr[6],rj[imm3] ; j=0..31 BLD
move.bit #0,sr[imm3] ; ITHSVNZC BCLR
move.bit #1,sr[imm3] ; ITHSVNZC BSET
move.bit #0,?adr5[imm3] ; adr5=0..31 CBI
move.bit #1,?adr5[imm3] ; adr5=0..31 SBI

move.w ri|rj,rk|rm ; j,m=0,2,..,30 i=j+1 k=m+1 MOVW

movePM.b (r31|r30),r0 LPM
movePM.b (r31|r30),rj ; j=0..31 LPM
movePM.b (r31|r30)+,rj ; j=0..31 LPM
movePM.b (*|r31|r30),r0 ELPM
movePM.b (*|r31|r30),rj ; j=0..31 ELPM
movePM.b (*|r31|r30)+,rj ; j=0..31 ELPM

muls.b ri,rj,r1|r0 ; i,j=16..31 MULS
mulsu.b ri,rj,r1|r0 ; i,j=16..23 MULSU
mulu.b ri,rj,r1|r0 ; i,j=0..31 MUL
neg.b rj ; j=0..31 NEG
nop NOP
not.b rj ; j=0..31 COM
or.b #imm8,rj ; j=16..31 ORI
or.b ri,rj ; i,j=0..31 OR
prog SPM
rocr.b #1,rj ; j=0..31 ROR
rol.b #4,rj ; j=0..31 SWAP
ror.b #4,rj ; j=0..31 SWAP
rte RETI
rts RET

skipeq.b ri,rj ; i,j=0..31 CPSE
skipeq.bit #0,?adr5[imm3] ; adr5=0..31 SBIC
skipeq.bit #0,rj[imm3] ; j=0..31 SBRC
skipeq.bit #1,?adr5[imm3] ; adr5=0..31 SBIS
skipeq.bit #1,rj[imm3] ; j=0..31 SBRS

sleep SLEEP
sub.b #imm8,rj ; j=16..31 SUBI
sub.b ri,rj ; i,j=0..31 SUB
subc.b #imm8,rj ; j=16..31 SBCI
subc.b ri,rj ; i,j=0..31 SBC
subq.w #imm6u,ri|rj ; j=24,26,28,30 i=k+1 SBIW
wdog_reset WDR


BRBC -> branch Befehle
CBR -> and.b
CLR -> eor.b
CLC,CLH,CLI,CLN,CLS,CLT,CLV,CLZ -> move.bit
LSL -> add.b
ROL -> addc.b
SBR -> or.b
SEC,SEH,SEI,SEN,SES,SET,SEV,SEZ -> move.bit
SER -> or.b
TST -> and.b




*******************************************************************
* Opcode list *
*******************************************************************


0000 0000 0000 0000 nop
0000 0001 jjjj iiii move.w ri|rj,rk|rm ; j,m=0,2,..,30 i=j+1 k=m+1
0000 0010 jjjj iiii muls.b ri,rj,r1|r0 ; i,j=16..31
0000 0011 0jjj 0iii mulsu.b ri,rj,r1|r0 ; i,j=16..23
0000 0011 0jjj 1iii fmulu.b ri,rj,r1|r0 ; i,j=16..23
0000 0011 1jjj 0iii fmuls.b ri,rj,r1|r0 ; i,j=16..23
0000 0011 1jjj 1iii fmulsu.b ri,rj,r1|r0 ; i,j=16..23
0000 01ij jjjj iiii cmpc.b ri,rj ; i,j=0..31
0000 10ij jjjj iiii subc.b ri,rj ; i,j=0..31
0000 11ij jjjj iiii add.b ri,rj ; i,j=0..31

0001 00ij jjjj iiii skipeq.b ri,rj ; i,j=0..31
0001 01ij jjjj iiii cmp.b ri,rj ; i,j=0..31
0001 10ji jjjj iiii sub.b ri,rj ; i,j=0..31
0001 11ij jjjj iiii addc.b ri,rj ; i,j=0..31

0010 00ij jjjj iiii and.b ri,rj ; i,j=0..31
0010 01ij jjjj iiii eor.b ri,rj ; i,j=0..31
0010 10ji jjjj iiii or.b ri,rj ; i,j=0..31
0010 11ij jjjj iiii move.b ri,rj ; i,j=0..31

0011 #### jjjj #### cmp.b #imm8,rj ; j=16..31
0100 #### jjjj #### subc.b #imm8,rj ; j=16..31
0101 #### jjjj #### sub.b #imm8,rj ; j=16..31
0110 #### jjjj #### or.b #imm8,rj ; j=16..31
0111 #### jjjj #### and.b #imm8,rj ; j=16..31

10#0 ##0j jjjj 0### move.b imm6(r31|r30),rj ; j=0..31
10#0 ##0j jjjj 1### move.b imm6(r29|r28),rj ; j=0..31
10#0 ##1i iiii 0### move.b ri,imm6(r31|r30) ; i=0..31
10#0 ##1i iiii 1### move.b ri,imm6(r29|r28) ; i=0..31

1001 000j jjjj 0000 move.b adr,rj ; j=0..31
#### #### #### ####
1001 000j jjjj 0001 move.b (r31|r30)+,rj ; j=0..31
1001 000j jjjj 0010 move.b -(r31|r30),rj ; j=0..31
1001 000j jjjj 0100 movePM.b (r31|r30),rj ; j=0..31
1001 000j jjjj 0101 movePM.b (r31|r30)+,rj ; j=0..31
1001 000j jjjj 0110 movePM.b (*|r31|r30),rj ; j=0..31
1001 000j jjjj 0111 movePM.b (*|r31|r30)+,rj ; j=0..31
1001 000j jjjj 1001 move.b (r29|r28)+,rj ; j=0..31
1001 000j jjjj 1010 move.b -(r29|r28),rj ; j=0..31
1001 000j jjjj 1100 move.b (r27|r26),rj ; j=0..31
1001 000j jjjj 1101 move.b (r27|r26)+,rj ; j=0..31
1001 000j jjjj 1110 move.b -(r27|r26),rj ; j=0..31
1001 000j jjjj 1111 move.b +(sp),rj ; j=0..31
1001 001i iiii 0000 move.b ri,adr ; i=0..31
#### #### #### ####
1001 001i iiii 0001 move.b ri,(r31|r30)+ ; i=0..31
1001 001i iiii 0010 move.b ri,-(r31|r30) ; i=0..31
1001 001i iiii 1001 move.b ri,(r29|r28)+ ; i=0..31
1001 001i iiii 1100 move.b ri,(r27|r26) ; i=0..31
1001 001i iiii 1101 move.b ri,(r27|r26)+ ; i=0..31
1001 001i iiii 1010 move.b ri,-(r29|r28) ; i=0..31
1001 001i iiii 1110 move.b ri,-(r27|r26) ; i=0..31
1001 001j jjjj 1111 move.b rj,(sp)- ; j=0..31

1001 010j jjjj 0000 not.b rj ; j=0..31
1001 010j jjjj 0001 neg.b rj ; j=0..31
1001 010j jjjj 0010 rol.b #4,rj ; j=0..31
1001 010j jjjj 0010 ror.b #4,rj ; j=0..31
1001 010j jjjj 0011 inc.b rj ; j=0..31
1001 010j jjjj 0101 asr.b #1,rj ; j=0..31
1001 010j jjjj 0110 lsr.b #1,rj ; j=0..31
1001 010j jjjj 0111 rocr.b #1,rj ; j=0..31

1001 0100 0### 1000 move.bit #1,sr[imm3] ; ITHSVNZC
1001 0100 1### 1000 move.bit #0,sr[imm3] ; ITHSVNZC
1001 0101 0000 1000 rts
1001 0101 0001 1000 rte
1001 0101 1000 1000 sleep
1001 0101 1001 1000 halt
1001 0101 1010 1000 wdog_reset
1001 0101 1100 1000 movePM.b (r31|r30),r0
1001 0101 1101 1000 movePM.b (*|r31|r30),r0
1001 0101 1110 1000 prog

1001 0100 0000 1001 jmp.w (r31|r30)
1001 0101 0001 1001 jsr.l (*|r31|r30)
1001 0100 0001 1001 jmp.l (*|r31|r30)
1001 0101 0000 1001 jsr.w (r31|r30)

1001 010j jjjj 1010 dec.b rj ; j=0..31
1001 010# #### 110# jmp.l label
#### #### #### ####
1001 010# #### 111# jsr.l label
#### #### #### ####

1001 0110 ##jj #### addq.w #imm6u,ri|rj ; j=24,26,28,30 i=k+1
1001 0111 ##jj #### subq.w #imm6u,ri|rj ; j=24,26,28,30 i=k+1
1001 1000 jjjj j### move.bit #0,?adr5[imm3] ; adr5=0..31
1001 1001 jjjj j### skipeq.bit #0,?adr5[imm3] ; adr5=0..31
1001 1010 jjjj j### move.bit #1,?adr5[imm3] ; adr5=0..31
1001 1011 jjjj j### skipeq.bit #1,?adr5[imm3] ; adr5=0..31
1001 11ij jjjj iiii mulu.b ri,rj,r1|r0 ; i,j=0..31

1011 0##j jjjj #### move.b ?adr6,rj ; adr6=0..63 j=0..31
1011 1##i iiii #### move.b ri,?adr6 ; adr6=0..63 i=0..31

1100 #### #### #### br.w label

1101 #### #### #### bsr.w label

1110 #### jjjj #### move.b #imm8,rj ; j=16..31

1111 00## #### #000 bcs.b label ; C=1
1111 00## #### #000 blo.b label ; C=1
1111 00## #### #001 beq.b label ; Z=1
1111 00## #### #010 bmi.b label ; N=1
1111 00## #### #011 bvs.b label ; V=1
1111 00## #### #100 blt.b label ; S=(N eor V) = 1
1111 00## #### #101 bhcs.b label ; H=1
1111 00## #### #110 bts.b label ; T=1
1111 00## #### #111 bis.b label ; I=1
1111 01## #### #000 bcc.b label ; c=0
1111 01## #### #000 bhs.b label ; C=0
1111 01## #### #001 bne.b label ; Z=0
1111 01## #### #010 bpl.b label ; N=0
1111 01## #### #011 bvc.b label ; V=0
1111 01## #### #100 bge.b label ; S=(N eor V) = 0
1111 01## #### #101 bhcc.b label ; H=0
1111 01## #### #110 btc.b label ; T=0
1111 01## #### #111 bic.b label ; I=0
1111 100j jjjj 0### move.bit sr[6],rj[imm3] ; j=0..31
1111 101j jjjj 0### move.bit rj[imm3],sr[6] ; j=0..31
1111 110j jjjj 0### skipeq.bit #0,rj[imm3] ; j=0..31
1111 111j jjjj 0### skipeq.bit #1,rj[imm3] ; j=0..31







*******************************************************************
* example program for STK500 (Mega32) *
*******************************************************************

; connect port B to LED

port_b_dir=$17
port_b_dat=$18

move.b #$ff,r16
move.b r16,?port_b_dir

eor.b r0,r0
move.b #$7f,r16
move.b #$3f,r17
move.b #$1f,r18
move.b #$0f,r19

loop: move.b r16,?port_b_dat
move.b #255,r20
_10: dec.b r20
bne.b _10

move.b r17,?port_b_dat
move.b #128,r20
_20: dec.b r20
bne.b _20

move.b r18,?port_b_dat
move.b #64,r20
_30: dec.b r20
bne.b _30

move.b r19,?port_b_dat
move.b #32,r20
_40: dec.b r20
bne.b _40
dec.b r4
bne.b loop

add.b r16,r16
addc.b r0,r16
add.b r17,r17
addc.b r0,r17
add.b r18,r18
addc.b r0,r18
add.b r19,r19
addc.b r0,r19

br.w loop

From: Jeroen on

"Herbert Kleebauer" <klee(a)unibwm.de> schreef in bericht
news:42DFDF98.DC5D4AC9(a)unibwm.de...
> Have to write some AVR code and therefore have read the
> AVR Instruction Set manual and tried the assembler included
> in AVR studio. I think the used syntax is completely
> unusable, so I decided to write my own assembler. A very
> first version can be downloaded from:
>
> ftp://137.193.64.130/pub/assembler/adela.zip
>
> Maybe there are some AVR experts who can give some suggestions
> for an improvement or are even willing to do some testing.

I fail to see what's so unusable about the AVR assembler syntax. Your effort
resembles 68000 code. Writing a good assembler takes time, are you writing
it from scratch? I think that's a complete wombat; better invest in learning
the AVR syntax, which is really not that difficult and not unusual.

Also nice for the one that has to maintain your code, long after you've
left. Are you going to write an assembler for every uC or uP come across,
redefining it's assembly language every time?


From: Herbert Kleebauer on
Jeroen wrote:
> "Herbert Kleebauer" <klee(a)unibwm.de> schreef in bericht


> I fail to see what's so unusable about the AVR assembler syntax. Your effort
> resembles 68000 code. Writing a good assembler takes time, are you writing
> it from scratch? I think that's a complete wombat; better invest in learning
> the AVR syntax, which is really not that difficult and not unusual.

What makes an assembler a "good assembler"? I think a good assembler
should allow you to write bug free code in a minimum of time. And
to do this you don't need a powerful macro system or a high speed
assembler or an integrated development system but you surely need
a well designed instruction syntax. And to write a simple assembler
(without a macro system and which is neither optimized for speed
nor size) isn't a big deal. Yes, you have to spend a few hours to
write the assembler, but this will save you much more time when
you write and debug your assembler programs.

> Also nice for the one that has to maintain your code, long after you've
> left. Are you going to write an assembler for every uC or uP come across,
> redefining it's assembly language every time?

Not every uP I come across, but every uP I have to program in
assembler and which uses an awful syntax like the Intel x86 or
the Atmel AVR (I liked the PDP11 or 68k syntax).
From: larwe on


> What makes an assembler a "good assembler"? I think a good assembler
> should allow you to write bug free code in a minimum of time. And

A good assembler should use the mnemonics and rules specified by the
device manufacturer, where there is such a specification. It should
assemble, with the minimum possible modification, code intended for
other assemblers targeting the same part.

An assembler that doesn't follow the device manufacturer's rules is a
very low-level HLL, not an assembler.

From: CBFalconer on
Herbert Kleebauer wrote:
> Jeroen wrote:
>
.... snip ...
>
>> Also nice for the one that has to maintain your code, long after
>> you've left. Are you going to write an assembler for every uC or
>> uP come across, redefining it's assembly language every time?
>
> Not every uP I come across, but every uP I have to program in
> assembler and which uses an awful syntax like the Intel x86 or
> the Atmel AVR (I liked the PDP11 or 68k syntax).

And then every time you want to use some code from outside, or from
the chip manufacturer, you have to laboriously transcribe it into
your 'better' mnemnonics and syntax, without error. Similarly for
the joker out there in either space or time who has to use your
special code.

I strongly advise letting the manufacturer set the assembly
language. Even small deviations can have evil consequences, as I
have found out in the past.

--
Chuck F (cbfalconer(a)yahoo.com) (cbfalconer(a)worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!

 |  Next  |  Last
Pages: 1 2 3 4 5 6 7 8 9 10 11
Next: int 10h AX = 4F00h