为链接的字符串列表解释此AVR宏

时间:2017-03-30 13:53:59

标签: assembly avr atmega

您好我正在使用微处理器类并尝试创建一个递归函数,该函数返回链表结构中某些字符串的长度。

我已经获得了这个宏,并且希望有人可以帮助我理解它。特别是我想知道如何使用这个宏创建一个链表。

.set NEXT_STRING = 0x0000
.macro defstring 
    .set T = PC 
    .dw NEXT_STRING << 1 
    .set NEXT_STRING = T 
    .if strlen(@0) & 1 
    .db @0, 0
    .else 
    .db @0, 0, 0
    .endif    
.endmacro

使用方法如下:

defstring“somestring”
defstring“另一个”

然后据说,创建了一个链表,这些字符串作为每个节点上的数据保存。

感谢任何帮助,谢谢!

1 个答案:

答案 0 :(得分:3)

下面的行声明了一个名为magick mogrify -format tif *NEF 的汇编程序常量,其值为0.只要NEXT_STRING出现在程序中,它就会被NEXT_STRING替换。

0

我认为名字.set NEXT_STRING = 0x0000 可能令人困惑。它实际上是指向您在程序集文件中声明的 last 字符串的指针。

此行将NEXT_STRING设置为等于当前程序计数器(PC)。这就是汇编程序正在写入闪存的当前位置。

T

下面的.set T = PC 指令将16位字写入闪存,具有指定值。该单词将存储指向列表中下一个节点的指针,因此我们将其设置为.dw。位移部分可能是因为PC以字计数,但AVR指针以字节计数,因此在将PC值转换为指针时必须乘以2。这是代码的第一部分,它实际上写了任何东西到flash。

NEXT_STRING

您生成的第一个指针将是一个空指针,因为.dw NEXT_STRING << 1 为0.但是我们将NEXT_STRING设置为NEXT_STRING,这样当您下次调用宏时,指针将指向闪存中存储最后一个指针的位置。

T

此时,我认为您可以看到正在形成链接列表。第一次调用.set NEXT_STRING = T 时,空指针存储在flash中,有一天它将成为链表的末尾。然后再次调用它,它会生成指向第一个指针的第二个指针。然后再次调用它,它会产生指向第二个指针的第三个指针。

链接列表仅在其中包含一些数据时才有用,因此宏所做的下一步是使用下面的代码添加字符串数据。无论谁写这个都决定了他们想要总是用空字节结束字符串(这是C语言字符串的标准),如果字符串的长度是奇数,他们还决定添加一个额外的填充字节,确保所占用的空间链表中的节点始终是偶数。这称为 2-alignment ,它可能使AVR更容易加载2字节指针。我不相信这种对齐是必要的,但如果是这样,我宁愿在宏的开头和/或结尾使用defstring指令而不是做这个黑客。

.align 2

除此之外:这不是在AVR中存储字符串列表的唯一方法。您在C程序中看到的更标准的方法是将所有字符串放在一个位置,然后在另一个位置放置一个指针数组。数组的长度可以是常量,也可以用空指针终止数组。 Windows注册表中的REG_MULTI_SZ数据使用的另一个选项是将字符串一个接一个地存储在内存中,没有指针,由空字节分隔,并以两个空字节结束。每种方法都为您提供不同的空间/性能权衡,最后一种方法不能存储空字符串。