您好我正在使用微处理器类并尝试创建一个递归函数,该函数返回链表结构中某些字符串的长度。
我已经获得了这个宏,并且希望有人可以帮助我理解它。特别是我想知道如何使用这个宏创建一个链表。
.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“另一个”
然后据说,创建了一个链表,这些字符串作为每个节点上的数据保存。
感谢任何帮助,谢谢!
答案 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数据使用的另一个选项是将字符串一个接一个地存储在内存中,没有指针,由空字节分隔,并以两个空字节结束。每种方法都为您提供不同的空间/性能权衡,最后一种方法不能存储空字符串。