AVR汇编,递增和递减数据存储器中的值

时间:2017-01-19 07:30:04

标签: assembly 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

2 个答案:

答案 0 :(得分:1)

我不太确定问题是什么,但我会尽力帮助。

STS k, Rd        ; stores Rd to address k.

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

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

ST Y+, R16

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

在您的示例中,您在.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

答案 1 :(得分:0)

  

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] =&gt; X,[R29:R28] =&gt; Y,[R31:R30] =&gt; Z)。