【问题标题】:Difference between LEA and MOVE.L?LEA 和 MOVE.L 的区别?
【发布时间】:2012-05-24 15:08:11
【问题描述】:

有什么区别

LEA $1000,A0

MOVE #$1000,A0

将地址放入地址注册表?

【问题讨论】:

    标签: assembly 68000


    【解决方案1】:

    在这种情况下,不会有可观察到的差异(与公认的答案声称不同 - MOVE 示例将组装为 MOVEA,它不会改变 CCR,请参阅 M68K 参考手册第 4-116 页到4-120)。

    【讨论】:

      【解决方案2】:

      lea 指令不会影响标志,而move 指令会。具体ZC会在move #$1000,a0之后被清除。

      【讨论】:

      • @yes123 现在我很少在汇编中写一些东西,但我仍然经常查看 gcc 生成的汇编 - 检查它是否再次搞砸了 :-) 但当时我拥有一台基于 68k 的计算机(Atari ST :-))编写程序集是加速关键例程的一项非常常见的任务。
      • 如果您有兴趣,还有一个小区别:) stackoverflow.com/questions/10766855/…
      • 一个不同的答案说这个特定的move 不会影响标志(因为它正在写入地址寄存器)。
      【解决方案3】:

      Durandal 是正确的,涉及地址寄存器的操作通常对处理器标志没有影响,在这种特殊情况下,两条指令的行为相同并且占用完全相同的 CPU 时间(使用短寻址模式为 8 个周期或使用长寻址模式为 12 个周期)模式)。

      MOVE xx,an 不是真正的指令,它是汇编程序允许的,但如果您查看反汇编结果,您会发现实际指令是 MOVEA。

      【讨论】:

        【解决方案4】:

        拥有 LEA 而不仅仅是 MOVE,其动机是 LEA 允许访问基于不同寻址模式的地址计算结果。

        MOVE #$1000,A0 指令将立即数 $1000 移动到 A0 寄存器中,因为在助记符中使用了立即数指示“#”。 LEA $1000,A0 指令指向内存地址 $1000,并将此地址加载到 A0 寄存器中。在这个简单的示例中,结果是相同的,看起来只是一些简单的语法问题,缺少立即指示“#”。

        查看以下差异时,LEA 的实际作用可能更容易理解:

        LEA (A0),A1
        

        和:

        MOVE (A0),A1
        

        使用LEA (A0),A1A1 寄存器加载A0 值,如A1 := A0,其中MOVE (A0),A1A0 寄存器中的内存位置加载字(默认大小)值, 符号将值扩展为 long(地址寄存器总是整个寄存器)并将值保存在 A1 寄存器中。

        所以LEA 提供了在地址实际进行内存访问之前地址计算的地址结果。这也是为什么没有任何LEA #<data> 格式(寻址模式)的原因,因为#<data> 的地址将在程序空间(PC 相对)中,因为立即数数据是指令的一部分。

        当使用更复杂的寻址模式时,LEA 的真正优势显而易见,否则需要大量代码来计算地址。

        因此,原始问题中LEAMOVE 的实际区别可以用地址寄存器目标(可能用于数据寄存器目标)的非法代码更好地说明:

        LEA ($1000),A0
        

        和:

        MOVE #$1000,A0
        

        这更清楚地表明LEA 提供了间接地址,而不实际进行内存访问。

        【讨论】:

        • 你确定LEA (A0),A1 相当于一个简单的A1 := A0 赋值吗?我觉得这很令人惊讶,因为(A0) 是间接寻址模式,人们期望它的意思是:A0 指向的数据加载到A1
        • 问问自己,(A0)给出的间接地址是什么?而当LEA给出源参数的地址时,那么LEA (A0), ...中源的值是多少?
        • 我明白你的意思,但是如果A0的值只是被复制到A1中,我在这里无法弄清楚括号符号(A0)的含义,除非@ 987654356@ 行为暗示提取源参数的地址。考虑到这一点,LEA Table,A0(文档中的示例)会做什么? (我猜每种语言都有其不合逻辑/令人困惑的特征)
        • (A0) 中的括号表示法是间接的,所以在做MOVE 时,会访问A0 给出的地址处的数据。对于LEA Table,A0,则意味着获取Table 的地址,因为table 是地址值,而不是立即数,上面的答案也涵盖了这一点。你可以下载EASy68K模拟器试试这个。
        • 请注意,LEA ($1000).w,A0LEA ($1000).l,A0 实际上是 LEA 的有效有效寻址模式。
        【解决方案5】:

        当我学习如何用汇编语言 (68k) 编程时,在处理地址寄存器时,LEAMOVE.L 的这个例子中指出了不同之处。在使用标签方面,肯定有很大的不同。

        假设你有一个标签Foo 代表一些DC.*

        LEA Foo, A0       ;Loads Foo into Address Register A0
        
        MOVE.L #Foo, A0   ;Loads Foo into Address Register A0
        

        教训是,在正常情况下,上述两条指令实际上会完成同样的事情。但是,由于现实系统中的“可重定位性”,底部的可能会导致问题。

        只使用LEA 方法是最安全的。使用$1000 时是否会出现问题 - 我不确定。但是,在处理地址寄存器时要谈论这个LEAMOVE.L 之间的区别,这绝对是必须考虑的事情。

        【讨论】:

        • 我认为这种说法并不完全正确。 “可重定位性”确实有不同,但前提是您使用 pc 相对模式进行 lea。 LEA Foo(pc),A0 确实与位置无关,但是 LEA Foo,A0 像 move.l #Foo,A0 将使汇编器为标签引用生成重定位表。当然 pc 相对版本有一些缺点,引用的标签必须在指令的 +/-32k 字节处。
        猜你喜欢
        • 2011-02-17
        • 1970-01-01
        • 2010-12-14
        • 2016-05-30
        • 2016-07-26
        • 2023-04-02
        • 2012-07-12
        相关资源
        最近更新 更多