2012-01-17 23 views
1

我的老师希望我们对装配有基本的了解,因为在以后的道路上,这可能会有所帮助。我很好,但是我的大学除了提供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

因为它是你的家庭作业,我认为你应该添加该标签。出于同样的原因,告诉你到底什么代码可能不是最好的方式来帮助你。你能说出你认为应该出现在你的登记册上吗?你得到的价值是什么?一旦你这样做了,我们当然可以解释你的推理有什么问题:) – 2012-01-17 21:02:42

+0

这很公平,我不想找到答案,我想了解。我会添加更多信息。 – Lg102 2012-01-17 21:05:57

+0

我建议组装,然后拆解代码。然后查看avr指令集手册了解每条指令的信息。您应该能够在avr指令集文档和atmega32数据手册/手册中的核心/ cpu章节之间找出z寄存器是什么,它如何映射到gprs以及指令实际上是如何编码的。从那里开始向后汇编到汇编语言 – 2012-01-17 21:36:00

回答

2

要回答你对换档的疑问,它所做的是将所有的位向左移一位,并将零作为第一位。换句话说,它将变量varclist的高(低)值乘以2。

varclist这里在你的程序中是内存中字节数组[0x01,0x02,... 0x00]的地址=>varclist是指向这个数组的第一个字节的指针。要获得原来的地址,我们只需要通过2(反向乘法的操作)来划分,我们得到

0x0070 >> 1 = 0000 0000 0111 0000 >> 1 = 0000 0000 0011 1000 = 0x0038 

所以varclist地址为0x0038。我不知道你认为这是0x0100,但我希望你现在了解代码。

我认为这个地址乘以2,因为程序存储空间的地址用字偏移来表示,在这种情况下,你需要乘以2来得到一个字节偏移量中的地址。稍后,可以通过LPM汇编指令将该字节(阵列的第一个字节)加载到r0中。

我建议你阅读this pdf的章节5.2以及其他章节。 AVR Assembler User Guide也可能是一个很好的选择。