Yahoo Groups archive

AVR-Chat

Index last updated: 2026-04-28 22:41 UTC

Thread

This assembly oughta be something silly...

This assembly oughta be something silly...

2005-06-14 by Alex De Lara

Ok, this must be something idiotic that I cannot figure out.
The Z register is being properly loaded with the correct
address of the string, but the string's bytes are never
loaded in r16. 
Why it always gets 0xff ? Obviously it is reading from 
somewhere else :-)
What's the trick ? 


; ----------------------------------------------------------
.include "m162def.inc"  ; includes the 162 definitions file
.cseg
.org 0x0000

    rjmp    INIT               ; this is a very silly program     
INIT:
    ldi     r16,LOW(RAMEND)    ; Initiatize Stackpointer
    out     SPL,r16            ; Needed otherwise returns from
    ldi     r16,HIGH(RAMEND)   ; calls go to 0000h
    out     SPH,r16            ;
;;    rcall   USART_init         ; will implement later.
String_out:                   ; load begin of string in Z
    ldi     ZH,high(Test_str)  ; Load Z register high    
    ldi     ZL,low(Test_str)   ; Load Z register low
loop1:                         ; come back here till done
    ld      r16,Z+             ; get byte and incr ptr
    cpi     r16,0              ; found the end ?
    breq    String_out         ; restart the loop
char_spit:
;;    rcall   USART_spit       ; will implement later
    rjmp    loop1      ;

.dseg    
Test_str:
    .db      "The old brown fox jumps over the lazy dog."
    .db      0x0d, 0x0a, 0

Re: [AVR-Chat] This assembly oughta be something silly...

2005-06-15 by Leon Heller

----- Original Message ----- 
Show quoted textHide quoted text
From: "Alex De Lara" <alex_de_lara@yahoo.com>
To: <AVR-Chat@yahoogroups.com>
Sent: Wednesday, June 15, 2005 1:43 AM
Subject: [AVR-Chat] This assembly oughta be something silly...


> Ok, this must be something idiotic that I cannot figure out.
> The Z register is being properly loaded with the correct
> address of the string, but the string's bytes are never
> loaded in r16. 
> Why it always gets 0xff ? Obviously it is reading from 
> somewhere else :-)
> What's the trick ? 

IIRC, you have to multiply the string address by two:

  ldi     ZH,high(Test_str*2)  ; Load Z register high    
    ldi     ZL,low(Test_str*2)   ; Load Z register low

There is an app. note on this.

Leon



-- 
No virus found in this outgoing message.
Checked by AVG Anti-Virus.
Version: 7.0.323 / Virus Database: 267.7.3/15 - Release Date: 14/06/2005

---
[This E-mail has been scanned for viruses but it is your responsibility 
to maintain up to date anti virus software on the device that you are
currently using to read this email. ]

Re: [AVR-Chat] This assembly oughta be something silly...

2005-06-15 by Zack Widup

On Wed, 15 Jun 2005, Alex De Lara wrote:

> Ok, this must be something idiotic that I cannot figure out.
> The Z register is being properly loaded with the correct
> address of the string, but the string's bytes are never
> loaded in r16.
> Why it always gets 0xff ? Obviously it is reading from
> somewhere else :-)
> What's the trick ?
> 
> 
>     ldi     ZH,high(Test_str)  ; Load Z register high   
>     ldi     ZL,low(Test_str)   ; Load Z register low

Change the above two lines to:

     ldi   ZH, high (Test_str*2)
     ldi   ZL, low  (Test-str*2)

See if that works.

Zack

Re: [AVR-Chat] This assembly oughta be something silly...

2005-06-15 by Dave VanHorn

>
>     ldi     ZH,high(Test_str)  ; Load Z register high
>     ldi     ZL,low(Test_str)   ; Load Z register low

As a couple of others have pointed out, you need to mult the string 
address by two.
This is because Z is a BYTE pointer, pointing to data that is stored as WORDS.

The string "ABCD" has two words of storage, "AB" and "CD"
The least significant bit then selects which byte you want. a 0 would 
get you "A", and a 1 would get you a "B", and so on.

Also, be aware, the data is stored as words by the asembler/compiler, 
so if you store "ABC" you'll end up with $41,$42,$43,$00

Re: This assembly oughta be something silly...

2005-06-15 by Alex De Lara

--- In AVR-Chat@yahoogroups.com, Dave VanHorn <dvanhorn@d...> wrote:
> >     ldi     ZH,high(Test_str)  ; Load Z register high
> >     ldi     ZL,low(Test_str)   ; Load Z register low
> 
> As a couple of others have pointed out, you need to mult 
> the string address by two. This is because Z is a BYTE pointer, 
> pointing to data that is stored as WORDS.

Ok, I see that.
 
> Also, be aware, the data is stored as words by the
> asembler/compiler, so if you store 
> "ABC" you'll end up with $41,$42,$43,$00

That's exactly what I expect if I store strings. (yeah, that
0x00 at the end is fine.)

So, I am looking at the code right now. 
Just opened the "Memory" window so I could browse all 
"spaces" (data, program, eeprom, registers, etc)
My string is actually in the code space, which is fine since 
right now I just need it to be in someplace.

What I see is that the instruction
    ld    r16,Z+
is not retrieving the byte stored there.

The address of the begining of the string is physically 
0x0016 but when the instruction is executed, some other 
value comes back to the register (0xFF or 0x00 whenever 
I use .dseg or leave it out)

So the question becomes: is there anything else to be set
so I can tell the Z register to grab the byte located
in the [code segment]:0x0020 ?

It seems it is not reading from the code segment, i.e. the
place where the string is right now.

Thanks the help.

-Alex

Re: [AVR-Chat] Re: This assembly oughta be something silly...

2005-06-15 by Leon Heller

----- Original Message ----- 
Show quoted textHide quoted text
From: "Alex De Lara" <alex_de_lara@yahoo.com>
To: <AVR-Chat@yahoogroups.com>
Sent: Wednesday, June 15, 2005 8:20 PM
Subject: [AVR-Chat] Re: This assembly oughta be something silly...


> --- In AVR-Chat@yahoogroups.com, Dave VanHorn <dvanhorn@d...> wrote:
>> >     ldi     ZH,high(Test_str)  ; Load Z register high
>> >     ldi     ZL,low(Test_str)   ; Load Z register low
>> 
>> As a couple of others have pointed out, you need to mult 
>> the string address by two. This is because Z is a BYTE pointer, 
>> pointing to data that is stored as WORDS.
> 
> Ok, I see that.
> 
>> Also, be aware, the data is stored as words by the
>> asembler/compiler, so if you store 
>> "ABC" you'll end up with $41,$42,$43,$00
> 
> That's exactly what I expect if I store strings. (yeah, that
> 0x00 at the end is fine.)
> 
> So, I am looking at the code right now. 
> Just opened the "Memory" window so I could browse all 
> "spaces" (data, program, eeprom, registers, etc)
> My string is actually in the code space, which is fine since 
> right now I just need it to be in someplace.
> 
> What I see is that the instruction
>    ld    r16,Z+
> is not retrieving the byte stored there.
> 
> The address of the begining of the string is physically 
> 0x0016 but when the instruction is executed, some other 
> value comes back to the register (0xFF or 0x00 whenever 
> I use .dseg or leave it out)
> 
> So the question becomes: is there anything else to be set
> so I can tell the Z register to grab the byte located
> in the [code segment]:0x0020 ?
> 
> It seems it is not reading from the code segment, i.e. the
> place where the string is right now.

Try lpm. It puts the byte addressed by the Z register in R0.

Leon

---
[This E-mail has been scanned for viruses but it is your responsibility 
to maintain up to date anti virus software on the device that you are
currently using to read this email. ]

Re: [AVR-Chat] Re: This assembly oughta be something silly...

2005-06-15 by Dave VanHorn

>
>What I see is that the instruction
>     ld    r16,Z+
>is not retrieving the byte stored there.

This needs to be LPM  (Load Program Memory)
LD is load from ram

Otherwise, what you did before is fine for strings stored in RAM.
Ram is bytes, and is addressed that way.

Re: [AVR-Chat] Re: This assembly oughta be something silly...

2005-06-15 by Leon Heller

Sorry, I should have given the more general form:

    lpm   Rx, Z+

Leon

---
[This E-mail has been scanned for viruses but it is your responsibility 
to maintain up to date anti virus software on the device that you are
currently using to read this email. ]

Re: [AVR-Chat] Re: This assembly oughta be something silly...

2005-06-15 by John Samperi

At 05:20 AM 16/06/2005, you wrote:
>My string is actually in the code space, which is fine since
>right now I just need it to be in someplace.

 >.dseg
 >Test_str:
?    .db      "The old brown fox jumps over the lazy dog."
 >    .db      0x0d, 0x0a, 0


I think you are confused. You CANNOT store your string
in ram that way. You can use either .cseg and put it in
flash and then use the LPM instruction as others have
pointed out.

You can put into EEPROM using .eseg and then use an EEPROM
reading routine to get it out of EEPROM.

OR

You can put it in flash as above, copy it to ram at run
time and THEN use ld    r16,Z+ to retrieve it. At present
you are to reading from ram that may not be there
(i.e. 0xff data)



Regards

John Samperi

******************************************************
                         Ampertronics Pty. Ltd.
   11 Brokenwood Place Baulkham Hills, NSW 2153 AUSTRALIA
          Tel. (02) 9674-6495       Fax (02) 9674-8745
                Email: samperi@ampertronics.com.au
                  Website  http://www.ampertronics.com.au
* Electronic Design   * Custom Products   * Contract Assembly
******************************************************

Re: [AVR-Chat] Re: This assembly oughta be something silly...

2005-06-15 by Zack Widup

On Wed, 15 Jun 2005, Alex De Lara wrote:

> 
> What I see is that the instruction
>     ld    r16,Z+
> is not retrieving the byte stored there.
> 
> The address of the begining of the string is physically
> 0x0016 but when the instruction is executed, some other
> value comes back to the register (0xFF or 0x00 whenever
> I use .dseg or leave it out)
> 
> So the question becomes: is there anything else to be set
> so I can tell the Z register to grab the byte located
> in the [code segment]:0x0020 ?
> 

I go about it a little differently.  Here's a little subroutine I use to 
do the same thing you're doing. ZL and ZH are set up in the main program 
just before calling the subroutine.

SENDIT:
        sbi     UCSRB, TXEN     ; Enable transmit
SENDLOOP:
        lpm                     ; Load character 
        adiw    ZL, $01         ; Increment Z reg
        tst     R0              ; Test for zero
        breq    SENDDONE        ; If so, done
        out     UDR, R0         ; send ASCII character
XMITWAIT:
        sbis    UCSRA, UDRE     ; loop till character shifted out
        rjmp    XMITWAIT
        rjmp    SENDLOOP        ; get next character when done
SENDDONE:
        ret                     ; go home

Re: This assembly oughta be something silly...Thanks

2005-06-15 by alex_de_lara

No, I am not confused. 

I wasn't intending to store anything in SRAM. I just wanted it 
defined and reserved, no matter where, as long as I could 
get the bytes one by one.

Since this is a fixed text there is no need to copy to RAM
or EEPROM to use it later. That yes, would be waste of cpu :-)

What I was missing are the specific concepts :

LD  - loads from the SRAM 
LPM - loads from the FLASH (which they call it program)

The instruction set doc is a little confusing, since I was 
trying to apply previous concepts ( z80, 8085, 8088 etc...)
It's probably more than enough once I get the full hang of 
the AVR family.

>> then use an EEPROM reading routine to get it

So I am assuming from this that there will be similar quirks 
to access eeprom... alright !

Thank you all for the enlightenments.

-Alex

--- In AVR-Chat@yahoogroups.com, John Samperi <samperi@a...> wrote:
Show quoted textHide quoted text
> At 05:20 AM 16/06/2005, you wrote:
> >My string is actually in the code space, which is fine since
> >right now I just need it to be in someplace.
>  >.dseg
>  >Test_str:
>     .db      "The old brown fox jumps over the lazy dog."
>     .db      0x0d, 0x0a, 0

> I think you are confused. You CANNOT store your string
> in ram that way. You can use either .cseg and put it in
> flash and then use the LPM instruction as others have
> pointed out.
 
> You can put into EEPROM using .eseg and then use an EEPROM
> reading routine to get it out of EEPROM.
> 
> OR
> 
> You can put it in flash as above, copy it to ram at run
> time and THEN use ld    r16,Z+ to retrieve it. At present
> you are to reading from ram that may not be there
> (i.e. 0xff data)

Re: [AVR-Chat] Re: This assembly oughta be something silly...Thanks

2005-06-16 by Kathy Quinlan

alex_de_lara wrote:
> No, I am not confused. 
> 
> I wasn't intending to store anything in SRAM. I just wanted it 
> defined and reserved, no matter where, as long as I could 
> get the bytes one by one.
> 
> Since this is a fixed text there is no need to copy to RAM
> or EEPROM to use it later. That yes, would be waste of cpu :-)
> 
> What I was missing are the specific concepts :
> 
> LD  - loads from the SRAM 
> LPM - loads from the FLASH (which they call it program)
> 
> The instruction set doc is a little confusing, since I was 
> trying to apply previous concepts ( z80, 8085, 8088 etc...)
> It's probably more than enough once I get the full hang of 
> the AVR family.

The instruction set documents cover all the AVR range, and should be 
read in conjunction with the relevant DEVICE documents.

Regards,

Kat.

Re: [AVR-Chat] Re: This assembly oughta be something silly...Thanks

2005-06-16 by Dave VanHorn

>
> >> then use an EEPROM reading routine to get it
>
>So I am assuming from this that there will be similar quirks
>to access eeprom... alright !

Not that odd.

Wait for the busy flag to not be true, address WDT issues if necessary
Set EARL and EARH, issue a read command, and pick up the result.
Put the address register to non-existent space in case of a rouge write.

This routine assumes Z is set with the address in EEspace, and data is in TEMP
TEMP2 is just a scratch register.

Read_EE:
         in      TEMP2,EECR              ;Poll for EECR,2=0 before continuing!
         andi    TEMP2,$03               ;Not sure you need ALL 
flags=0 but it's harmless
                                         ;See bug description in Write_EE
         brne    Read_EE                 ;Potential to loop forever.

         out     EEARH,ZH                ;Set up the address
         out     EEARL,ZL                ;
         sbi     EECR,EERE               ;Set EE Read Enable
         in      TEMP,EEDR               ;Get the data

         adiw    ZL,1                    ;Inc the pointer

         ldi     TEMP2,$FF               ;Point at non-existent location
         out     EEARL,TEMP2             ;when not in active use.
         out     EEARH,TEMP2             ;

         ret                             ;

Re: [AVR-Chat] Re: This assembly oughta be something silly...Thanks

2005-06-16 by John Samperi

At 08:12 AM 16/06/2005, you wrote:
>No, I am not confused.

You are contradicting me. :-D

>The instruction set doc is a little confusing, since I was
>trying to apply previous concepts ( z80, 8085, 8088 etc...)

The problem is that the AVR is a Modified Harvard architecture
device where you have separate data and program busses as against
a Josephson( spell?) architecture (z80, 6800 etc) where you have
a single bus for program and data. i.e. the 68HC711 has ram at
0x00, EEPROM at 0xf800 and Rom at 0xe000 and they can be accessed
with the same instruction as they are on the same memory block. In
fact you can run programs from ram, eeprom ot rom.

With the AVR you can ONLY run programs from the program memory area/bus
(i.e. flash in this case) and both the EEPROM and ram are in the
data area/bus. The modified Harvard architecture allows data to be stored
in the program area.

So the poor assembler needs to know where you want to keep your
string before it can assemble your program.

To tell it where to put things you have 3 directives.

.cseg  (code segment) puts things in program memory space.
That's where your code is located along with any strings or
constants you may want to have.

.cseg
program code etc

strings in flash
Test_str:
     .db      "The old brown fox jumps over the lazy dog."
     .db      0x0d, 0x0a, 0

you need to use LPM to get data from the flash

.dseg (data segment)

this is where you allocate your variable spaces in ram

you were trying to locate your string here. It should really
come up with an error or at least a warning as it cannot be
done at run time.

.dseg ******** can't be done
Test_str:
     .db      "The old brown fox jumps over the lazy dog."
     .db      0x0d, 0x0a, 0

.eseg (EEPROM segment)

you can store data or strings here but as the EEPROM is in a serial
bus you need a small program to get the data out as Dave as shown you.

Armed with the above you are up and running at full speed :-)
Once you get used to the Harvard architecture it's very easy.
I miss not being able to run stuff from ram though.....


Regards

John Samperi

******************************************************
                         Ampertronics Pty. Ltd.
   11 Brokenwood Place Baulkham Hills, NSW 2153 AUSTRALIA
          Tel. (02) 9674-6495       Fax (02) 9674-8745
                Email: samperi@ampertronics.com.au
                  Website  http://www.ampertronics.com.au
* Electronic Design   * Custom Products   * Contract Assembly
******************************************************

Re: [AVR-Chat] Re: This assembly oughta be something silly...Thanks

2005-06-16 by Leon Heller

----- Original Message ----- 
Show quoted textHide quoted text
From: "John Samperi" <samperi@ampertronics.com.au>
To: <AVR-Chat@yahoogroups.com>
Sent: Thursday, June 16, 2005 6:54 AM
Subject: Re: [AVR-Chat] Re: This assembly oughta be something silly...Thanks


> At 08:12 AM 16/06/2005, you wrote:
>>No, I am not confused.
>
> You are contradicting me. :-D
>
>>The instruction set doc is a little confusing, since I was
>>trying to apply previous concepts ( z80, 8085, 8088 etc...)
>
> The problem is that the AVR is a Modified Harvard architecture
> device where you have separate data and program busses as against
> a Josephson( spell?) architecture (z80, 6800 etc) where
      ^^^^^^^^

It's "von Neumann". 8-)

Leon
--
Leon Heller, G1HSM
leon.heller@bulldoghome.com
http://www.geocities.com/leon_heller



-- 
No virus found in this outgoing message.
Checked by AVG Anti-Virus.
Version: 7.0.323 / Virus Database: 267.7.3/15 - Release Date: 14/06/2005

---
[This E-mail has been scanned for viruses but it is your responsibility 
to maintain up to date anti virus software on the device that you are
currently using to read this email. ]

Re: [AVR-Chat] Re: This assembly oughta be something silly...Thanks

2005-06-16 by John Samperi

At 05:29 PM 16/06/2005, you wrote

>It's "von Neumann". 8-)

Of course!! I have been up since 5 am...it's a wonder
I'm still awake!! :-(

Regards

John Samperi

******************************************************
                         Ampertronics Pty. Ltd.
   11 Brokenwood Place Baulkham Hills, NSW 2153 AUSTRALIA
          Tel. (02) 9674-6495       Fax (02) 9674-8745
                Email: samperi@ampertronics.com.au
                  Website  http://www.ampertronics.com.au
* Electronic Design   * Custom Products   * Contract Assembly
******************************************************

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.