【问题标题】:In AVR assembly, what is the value in register r24 after code executes?在 AVR 汇编中,代码执行后寄存器 r24 中的值是多少?
【发布时间】:2018-04-23 22:25:47
【问题描述】:

我刚刚开始了解数组是如何存储在寄存器中的,我对指针的工作方式感到非常困惑。

假设指针Z指向内存中的以下字符数组,地址为0xABCD

['1', '3', '2']

给定以下 sn-p:

ld r23, Z+
ld r24, Z

代码执行后r24的值是多少?

Z 会是索引 0 吗?还是索引0处的值是1,还是与地址0xABCD有关?

请客气。我真的很想学这个东西,我的老师不擅长解释。任何帮助将不胜感激!

【问题讨论】:

  • 第一条语句将 Z ('1') 处的值加载到 r23 中并向前移动 Z。然后第二条语句将 Z ('3') 处的值加载到 r24 中。

标签: c arduino avr cpu-registers


【解决方案1】:

共有三个指针寄存器:X - 实际上是一对寄存器 r27:r26, Y - r29:r28 和 Z - r31:r30

并且有四种不同的间接访问模型来使用该指针读/写内存:

1) 普通间接访问:

ld r16, X
st Y, r16

仅用于从这些寄存器指向的地址加载和存储数据。

2) 后增量间接访问:

ld r16, X+
st Z+, r16

这些操作使用当前存储在指针寄存器中的地址进行写入和读取。在这些操作之后,存储在相应寄存器对中的值增加一。

3) 带有预减量的间接访问:

ld r16, -Y
st -X, r16

这些操作首先将存储在相应寄存器对中的值减一,然后对新的计算地址进行读/写。

4) 带位移的间接访问(仅适用于 Y 和 Z):

ldd r16, Y+1
std Z+30, r16

这些不会更改存储在指针寄存器中的值,而是使用指针寄存器指定的地址加上给定的偏移量来读取和写入内存。偏移量在 0 到 63(含)之间始终为正数。 X 寄存器没有lddstd

注意。在具有 256 字节和更少可寻址数据空间的设备上,仅使用指针寄存器对的低字节,并且后​​递增和前递减也不会修改它们。 在能够寻址超过 64KB 的设备上,还有额外的 I/O 寄存器(RAMPX、RAMPY、RAMPZ)用于获取地址的高位。当与后增量或前减一起使用时,这些寄存器也会更新。

另请注意,当使用前置递减或后置递增来存储包含在指针对寄存器之一中的数据时,例如:

st X+, r26 // r26 is a part of X register
st -Y, r29 // r29 is a part of Y register
etc.

那么这些操作的结果是不确定的。

所以,回答你的问题:

如果 Z 指向 char 数组的第一个字节,则操作 ld r23, Z+ 会将第一个字节值加载到 r23 中,然后将 Z(即寄存器 r31:r30)的值增加一个。因此,Z 将指向数组的第二个字节。 然后,下一个操作ld r24, Z 会将第二个字节加载到 r24 中,并且 Z 指针将保持不变。

【讨论】:

    猜你喜欢
    • 2014-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-24
    • 2013-09-21
    • 2019-12-26
    • 2012-10-23
    • 1970-01-01
    相关资源
    最近更新 更多