[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [avr-gcc-list] ijmp usage
From: |
Theodore A. Roth |
Subject: |
Re: [avr-gcc-list] ijmp usage |
Date: |
Fri, 20 Dec 2002 11:14:08 -0800 (PST) |
On Fri, 20 Dec 2002, Christian Ludlam wrote:
:) On 20 Dec Steve Joiner wrote:
:)
:) > Ok, dumb question time. I'm writing a routine in assembly for the atmega8.
:)
:) > I've got some code that looks like this:
:)
:) > ldi ZL,lo8(foo)
:) > ldi ZH,hi8(foo)
:) > ijmp
:)
:) > Unfortunately, it doesn't seem to be doing what I want (which would be
:) > to jump to foo). If I replace that code, with this code:
:)
:) > ldi ZL,lo8(foo)
:) > ldi ZH,hi8(foo)
:) > rjmp foo
:)
:) > It works fine. (I know the two ldi's don't do anything, but I left
:) > them there to verify that I wasn't trashing some values in Z that I
:) > needed later).
:)
:) > I must be interpreting something wrong -- I would think both versions
:) > should do the same thing. Can someone give me a clue as to what I'm
:) > doing wrong?
:)
:) A guess: ijmp and the PC work with word addresses, whereas the label has a
:) byte address, so you need to divide it by 2.
This is correct due to the way avr-gcc and avr-as work.
:)
:) ldi ZL,lo8(foo) >> 1
:) ldi ZH,hi8(foo) >> 1
:) ijmp
Two things wrong here:
1) The assembler will puke on the ">> 1" part.
2) You would need to do the division before splitting up into bytes or you
could lose the low bit of ZH if it's set. First tought would be to but the
">> 1" inside the lo8() and hi8(), but the assembler pukes on that too.
I ran this code through gdb/simulavr and it seems to work (ijmp does jump
to foo):
foo:
rjmp foo
main:
ldi ZL,lo8(foo)
ldi ZH,hi8(foo)
lsr r31
ror r30
ijmp
Here's the disassemble of the elf file:
000001bc <foo>:
foo:
rjmp foo
1bc: ff cf rjmp .-2 ; 0x1bc
000001be <main>:
main:
ldi ZL,lo8(foo)
1be: ec eb ldi r30, 0xBC ; 188
ldi ZH,hi8(foo)
1c0: f1 e0 ldi r31, 0x01 ; 1
lsr r31
1c2: f6 95 lsr r31
ror r30
1c4: e7 95 ror r30
ijmp
1c6: 09 94 ijmp
This is not ideal.
You're probably better off just using the JMP or RJMP instructions.
Unless are trying to generate a array of jump pointers...
Beware that my method will be broken if you want to IJMP into the upper
64K of a mega128.
There should be a way for the compiler/assembler to deal with this, but I
haven't discovered it yet. ;-)
Ted Roth
avr-gcc-list at http://avr1.org