【问题标题】:How do low() and high() functions work in AVRlow() 和 high() 函数在 AVR 中如何工作
【发布时间】:2020-06-14 15:56:12
【问题描述】:

我试图了解一些汇编代码,但我不了解如何找到某些值。如果代码:

ldi     ZL, low(2*table)        
ldi     ZH, high(2*table)

与表一起执行:

table:      .db     32, 34, 36, 37, 39, 41, 43, 45, 46, 48, 50, 52, 54, 55, 57, 59, 61, 63, 64, 66

我正在查看表格中的元素 5,即 41。

在这个例子中 ldi 操作符做了什么?第一个ldi执行完后,SRAM中ZL位置存了14,但是为什么是14呢?

第二个执行后,02存储在ZH位置。

【问题讨论】:

  • 它与您的表格内容无关。它正在加载基地址,显然是0x020e
  • 那么这个值来自表值的存储位置,而不是基于表值本身?
  • 没错。
  • 加载表的地址乘以2的目的是什么?
  • @ndim:我认为这对 AVR 来说是正常的;出于某种原因,标签地址是字号,您需要缩放以获得字节地址。对我来说似乎完全疯了,但我想我以前见过这个。 (虽然它可能对代码地址有意义,但如果指令是对齐的。)

标签: assembly avr


【解决方案1】:

闪存是“字寻址”的,汇编标签table 给出了表的字地址。 * 2 以字节为单位给出正确的地址。我更喜欢使用<< 1 而不是* 2,因为对我来说,这会让事情更清楚。

要实际访问表格的第 5 个元素,您需要执行以下操作:

    ldi ZL, low(table << 1)  ; (or you could use `table * 2`)
    ldi ZH, high(table << 1) ; Z Register points to start of table
    ldi r25, 5               ; register r25 contains required offset in table
    clr r1                   ; (I always have r1 set to zero all the time)
    add ZL, r25              ; add offset to base pointer
    adc ZH, r1               ; if the low byte of the Z register "pointer"
                             ; overflowed, add the carry flag to the high byte
    lpm r24, Z               ; read the 5th element of the table into r24

这也包含在以下 SO 问题中:

【讨论】:

  • “字节对齐”地址是什么意思?我以为table 会用文字告诉你地址,例如内存中的第 10 个字,您需要 &lt;&lt;1 才能获得一个字节地址,例如内存中的第 20 个字节,因为 AVR 是字节可寻址的。
  • @PeterCordes “我想”:你真是太外交了!当然你是对的,我会立即编辑我的答案。
  • 我必须对某些事情完全错误敞开大门,因为我对 AVR 的了解都是基于看到关于它的 SO 问题,并且出于好奇而偶尔在谷歌上搜索。地址缩放似乎是一个奇怪的设计选择,没有多大意义。但是,是的,我花了几次尝试来表达我的理解,这就是我决定的。 :P
猜你喜欢
  • 2013-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-02
  • 2013-03-14
  • 2020-01-23
  • 1970-01-01
相关资源
最近更新 更多