我的老师希望我们对装配有一个基本的了解,因为在未来的路上,这可能会有所帮助。我很好,但是我的大学提供了关于这个主题的零文档,除了4个小例子。我想弄清楚这个发生了什么:
.DEVICE ATmega32
.CSEG
main:
ldi ZL,low(varclist<<1)
ldi ZH,high(varclist<<1)
.CSEG
varclist:
.db 1, 2
.db 3, 4
.db 5, 6
.db 7, 8
.db 9, 0
我正在使用AVR studio 5,并查看“处理器”标签。我似乎无法找到'varclist'中的值与寄存器显示的十六进制值之间的任何关系。我怎么看这个?
我希望Z寄存器包含0x0100,因为我认为“最重要”的位是第一个声明的位,而最后一个声明的位最不重要。不过,我看到了0x0070。不过,我不确定这种转变是什么。
答案 0 :(得分:2)
为了回答你对移位的疑惑,它的作用是将所有位向左移一,将第一位加零。换句话说,它将变量varclist
的高(相应低)值乘以2。
varclist
是内存中字节数组[0x01,0x02,... 0x00]的地址=&gt; varclist
是指向此数组的第一个字节的指针。要获得原始地址,我们只需要除以2(乘法的反向运算),我们得到
0x0070 >> 1 = 0000 0000 0111 0000 >> 1 = 0000 0000 0011 1000 = 0x0038
varclist
地址为0x0038
。我不知道你怎么认为这是0x0100,但我希望你现在能理解这段代码。
我认为该地址乘以2,因为程序存储空间的地址以字偏移量表示,在这种情况下,您需要乘以2以获取字节偏移量中的地址。之后,由于r0
汇编指令,您可以将该字节(数组的第一个字节)加载到LPM
。
我建议你阅读this pdf的章节5.2以及其他章节。 AVR Assembler User Guide也可能是一个不错的选择。