Search code examples
assemblyavr

AVR assembly, incrementing and decrementing values from data memory


So I was giving a project to write a program that stores a value in a data memory location, 0x200, the program then decrements the value and stores it the next memory location. I just started assembly programming and I tend to write it with the mentality of writing with a high level language. Here's the code I created (it looks a lot but that's just cause of comments):

.cseg
.org 0x200 ;Trying to get the program to start assemblimg from memory location, 0x200

.DSEG
store: .BYTE 1 ;Trying to "create a variable called store to represent memory location, 0x200"

.CSEG
    lds r17, store ;loading variable store into registry 17

.def count = r16
    ldi count, 0x04 ;the first value, 0x04 assigned to variable, count and stored in registry 16


lp: 

    sts store, r16 ;stores value in r16, i.e. 0x04, into store which should point to memory location 0x200

    cpi count, 0x00 ;check if value is zero yet

    breq done ;if value is zero end program

    dec count ;decrement the value of count, i.e. 0x04

    inc r17 ;increment content of r17, which is store which refers to memory locaion, 0x200

    rjmp lp ;restart loop


done: jmp done ;end of program

I know it's a bit messy cause of the comments, sorry for that If it helps this was the first code I tried but r15 doesn't work with sts:

.cseg
.org 0

lds r15, 0x200
lds r17, 0x001

.def count = r16
    ldi count, 0x04


lp:
    sts r15, r16
    cpi count, 0x00
     done
    dec count
    ADD r15, r17
    rjmp lp

done: jmp done

Solution

  • STS k,Rr: Stores one byte from a Register to the data space. For parts with SRAM, the data space consists of the Register File, I/O memory, and internal SRAM (and external SRAM if applicable).

    ST Z, Rr,ST Z+, Rr,ST -Z, Rr,STD Z+q, Rr: Stores one byte indirect with or without displacement from a register to data space. For parts with SRAM, the data space consists of the Register File, I/O memory, and internal SRAM (and external SRAM if applicable).

    You need to use ST instruction and one of the pointer registers (X, Y, and Z) to store one byte from a register to special RAM address.

    Like this :

    .def count = r16
    .equ array_size = 5
    
    .dseg
    .org    0x200
    array_region: .BYTE array_size
    
    .cseg
    .org    0
    
    ; Vector Table ( Offset 0 -> Rest )
    JMP start
    
    
    
    .org    INT_VECTORS_SIZE*2 ; Here is end of vector table
    RJMP    start
    .include "m32def.inc" ; We should specify a special AVR for using its definitions
    
    ; Start From Here
     start:
    
    ; Initializing Stack Pointer ( to the end of RAM ). You must do it for returning from subroutines and Interrupts.
    ;LDI        R16,LOW(RAMEND)
    ;LDI        R17,HIGH(RAMEND)
    ;OUT        SPL,R16
    ;OUT        SPH,R17
    
    
    LDI XL, LOW(array_region) ; Low byte of X
    LDI XH, HIGH(array_region) ; High byte of X
    
    LDI count, array_size
    
    lp:
    ST X+, R16
    DEC count
    BREQ done ; 'DEC' instruction will effect on Z flag.
    RJMP lp
    
    done: JMP done
    

    Note that pointer registers are equal to the R26 to R31 registers ([R27:R26] => X , [R29:R28] => Y , [R31:R30] => Z).