avr-gcc-list
[Top][All Lists]
Advanced

[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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]