【问题标题】:What does this do in assembly这在汇编中有什么作用
【发布时间】:2012-01-17 20:51:01
【问题描述】:

我的老师希望我们对组装有一个基本的了解,因为以后可能会有所帮助。我对此很好,但我的大学提供了关于该主题的零文档,除了 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。不过,我不确定这种转变的作用。

【问题讨论】:

  • 因为它是你的作业,我认为你应该添加那个标签。出于同样的原因,确切地告诉您代码可能不是帮助您的最佳方式。你能说出你认为应该在你的寄存器中出现什么以及你得到什么价值吗?一旦你这样做了,我们当然可以解释你的推理出了什么问题:)
  • 这很公平,我不是在寻找答案,我想了解。我会添加更多信息。
  • 我建议先组装,然后再反汇编代码。然后查看 avr 指令集手册,了解每条指令的信息。您应该能够在 avr 指令集文档和 atmega32 数据表/手册中的核心/cpu 章节之间弄清楚 z 寄存器是什么,它如何映射到 gprs,以及指令在编码时实际执行的操作。从那里向后工作到汇编语言

标签: assembly avr atmega


【解决方案1】:

为了回答您对移位的疑惑,它所做的是将所有位向左移动一位,并添加一个零作为第一位。换句话说,它将变量 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 才能得到字节偏移量中的地址。稍后您可以将该字节(数组的第一个字节)加载到r0,这要归功于LPM 汇编指令。

我建议您阅读this pdf 的第 5.2 章,可能还阅读其他章节。 AVR Assembler User Guide 也可能是一个不错的选择。

【讨论】:

    猜你喜欢
    • 2015-05-15
    • 2016-06-03
    • 2019-11-02
    • 1970-01-01
    • 2017-06-01
    • 2011-11-09
    • 1970-01-01
    • 2013-09-30
    • 1970-01-01
    相关资源
    最近更新 更多