代码之家  ›  专栏  ›  技术社区  ›  Summer_More_More_Tea

如何使用arm中的mov指令,并将immediate数作为第二个操作数

  •  16
  • Summer_More_More_Tea  · 技术社区  · 15 年前

    我刚开始学习ARM汇编语言,不清楚如何使用MOV将一个立即数转移到寄存器中。

    从ARM参考手册和我的教科书来看,MOV指令后的即时数范围是0-255。但是当我在自己的电脑上测试ADS1.2IDE时,说明

    MOV     R2, #0xFFFFFFFF
    

    表现很好。数字0xffffffff是否超出规格范围?

    希望有人能帮我一把。

    当做。

    6 回复  |  直到 10 年前
        1
  •  13
  •   Michael Burr    15 年前

    记住,ARM可以对即时值执行特定的操作集,作为合并到ARM操作码中的桶移位器的一部分。

    这篇小文章对ARM汇编程序可以用来将大量即时数放入ARM指令的小可用空间的一些技巧进行了最清晰的解释:

    本文讨论了在生成MVN操作码以加载即时值的位补码的特定示例中可能使用的技巧。

    这些类型的操作不能用所有的即时值来完成,但是ARM汇编程序被认为是非常聪明的(C编译器当然是这样)。如果无法执行移位/补码技巧,则通常会从PC相关位置加载该值,或者通过从多个指令中“构建”该值来加载该值。

        2
  •  11
  •   Matthew Slattery    15 年前

    单臂指令只能对一个立即数常量进行编码,该常量可以表示为一个8位立即数,由任意移位。 即使 二的力量。

    但是,还有一个 MVN 指令,就像 MOV 但把所有的部分都颠倒过来。所以,当 MOV R2, #0xFFFFFFFF 不能编码为 压敏电阻 指令,它可以编码为 MVN R2, #0 . 汇编程序可以很好地为您执行这个转换。

        3
  •  2
  •   user4219605    10 年前

    MOV指令可以接受imm16值或operator2值(由于指令长度与内存对齐相反),这必须符合以下任何规则(从Cortexm指令集手册复制,x和y是任何十六进制值):

    • 通过将一个8位值移到一个 32位字。
    • 形式为0x00xy00xy的任何常量。
    • 形式为0xXY00XY00的任何常数。
    • 任何形式的常数。

    这就是为什么接受0xffffffff(符合第4条规则)。

    如果您希望组装自己的32位常量,可以使用指令 莫特 写入寄存器的上半部分。

        4
  •  1
  •   dthorpe    15 年前

    您可能会看到原始值的符号扩展中的工件。如果用于查看反汇编的工具将0..255作为有符号字节处理,那么当它将其加载到更大的int类型(或寄存器)时,它将用原始值的符号位填充所有的高位。或者换句话说,如果0xff是有符号字节,则其十进制值为-1。把它放入一个32位寄存器,十六进制看起来像0xffffffff,它的十进制值仍然是-1。

    尝试使用不带高位集的值,如0x7F。由于未设置符号位,因此我猜想当加载到更大的int类型寄存器或字段时,它将用零填充高位。

    编译器/汇编程序也可能截断您提供的任何值。我会认为这是源代码错误,但汇编程序是有趣的野兽。如果给它0x7ff,它编译为0x7ff(未截断,且大于0..255)还是0xffffffff(截断为0..255,有符号字节)?

        5
  •  1
  •   Jake 'Alquimista' LEE    13 年前

    很难确定给定的常量是否在有效范围内。

    正如Matthew已经提到的,汇编程序通过用类似的、否定的指令(如mov/mvn、cmp/cmn、tst/tne等)替换给定的指令来帮助您。

        6
  •  -1
  •   Bill    15 年前

    一种可能是ARM汇编程序丢弃了数字的有效位,只使用最低的FF。

    MOV指令是许多CPU指令集中的主食,通常汇编程序解析目标寄存器的大小和所提供的立即值。

    例如,来自x86集的以下MOV指令是

    MOV BL, 80h, ; 8bit
    MOV BX, ACACh ;16bit
    MOV EBX, 12123434h ; 32bit