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
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).