AVR组件,从数据存储器中递增和递减值



所以我给了一个项目来编写一个程序,该程序将值存储在数据内存位置0x200中,然后该程序将该值递减并将其存储在下一个内存位置。我刚开始汇编编程,我倾向于用高级语言写作。这是我创建的代码(看起来很多,但这只是评论的原因):

.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

我知道这是一个有点混乱的原因的评论,很抱歉如果有帮助的话,这是我尝试的第一个代码,但r15不适用于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, Rd        ; stores Rd to address k.

STS被称为直接数据寻址,它需要一个常量来存储数据。使用STS需要对每个存储进行硬编码,这并不是一个好的解决方案。您需要的是间接数据寻址,ST.

X、 Y和Z是指针寄存器,可用于指向特定地址。

ST Y+, R16

上面的代码将R16中的内容存储到地址Y中,然后将Y递增一。

在您的示例中,您在.cseg中调用了.org 0。这样做的目的是使起始地址(原点)存储在0x00,用于程序内存。要将数据内存中的原点设置为0x200,您需要在.dseg.中调用.org 0x200

我用你给出的代码做了这个,只是稍微调整了一下。它应该起作用。

.dseg
.org 0x200

示例:

.dseg               ;Data segment
.org 0x200          ;Start storing at 0x200
storage: .byte 1    ;Allocate 1 byte for storage
.cseg                  ;Code segment
ldi yH, high(storage)  ;storage <== Y
ldi yL, low(storage)
ldi r16, 0x2B          ;Load r16 with 0x2B
loop:
st Y+, r16     ;Address Y <== r16, increments Y by 1.
cpi r16, 0x00  ;Compare r16 to 0.
breq end       ;If zero status bit is 1, branch to end.
dec r16        ;Otherwise, decrement and loop.
rjmp loop
end:               ;End loop
jmp end

检查AVR装配说明集。ST允许您在X、Y或Z中存储增量/减量前或增量/减量后的值。如果您想将寄存器中的内容存储在连续的数据存储位置,请使用:

ST X, Rd

STS k,Rr:将寄存器中的一个字节存储到数据空间。对于部分与SRAM,数据空间包括寄存器文件,I/O存储器和内部SRAM(以及外部SRAM,如果适用的话)。

ST Z, RrST Z+, RrST -Z, RrSTD Z+q, Rr:存储一个字节间接的,有或没有从寄存器到数据空间的位移。对于带有SRAM的部件,数据空间由寄存器文件、I/O组成存储器和内部SRAM(以及外部SRAM,如果适用的话)。

您需要使用ST指令和其中一个指针寄存器(X、Y和Z)将一个字节从寄存器存储到特定的RAM地址。

像这样:

.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

请注意,指针寄存器等于R26到R31寄存器([R27:R26]=>X,[R29:R28]=>Y,[R31:R30]=>Z)。

最新更新