Arm cortex-m3 mov 和 ldr
Arm cortex-m3 mov and ldr
我不明白为什么我不能写 mov r1, #5000
。为什么我必须改用 ldr
? R1 是 32 位寄存器,5000 在范围内。正如我发现的那样,我可以 mov r1, #255
但不能 mov r1, #256
。我觉得很奇怪。
阅读有关指令的文档,在这种情况下,指令是固定长度的,因此您在 16 位或 32 位指令中没有空间容纳指令信息(操作码等)和 32 位立即数,不是可能,因此需要对立即数进行一些限制。例如,对于 x86,它是可变指令长度,因此它们可以有很长的指令,但很容易争辩说,执行 pc-relative 加载或一些相同大小的固定长度指令不会对流水线产生显着的额外成本。所以六个中的六个。 mips 固定指令长度移动立即解决方案有其优点和缺点,并且对于每个 arm 指令集,每个都有自己的解决方案,具有优点和缺点。
对于 arm 汇编程序(当然是 gcc,可能是 arm toolchain、keil 等),您可以使用快捷方式,汇编程序将选择更简单的路径
ldr r1,=immediate
如果它不能将其编码为一条指令(请注意,有一些负向移动,程序计数器的数学运算以及它可以玩的其他技巧,您当时可能没有想到或者不知道 pc 可能不会能够使用),如果它不能那么它可以将它编码为多个指令 mov immediate 然后一个 orr,或者将它编码为 pc 相对负载。
每个指令集 mov immediate 的具体限制在 arm 体系结构参考手册中有详细记录,您可以只获得 armv7 一个,它具有该体系结构版本和先前体系结构版本的所有编码。有了这些知识,您应该能够在让汇编程序告诉您之前自己确定 mov 是否可以工作。
在 ARM Cortex-M3 中,MOV 是 16 位指令,定义如下 MOV<c>{<q>} <Rd>, #<imm8>
立即值作为操作码的一部分存储在 arm 指令中
opc[15:11]='b00100 =>which identifies instruction.
opc[10:8]=<register no>
opc[7:0]=<imm8 value>
因此,通过上述指令,您可以将 2^8 -1 =>255 作为最大立即数
虽然通过指定指令说明符 .W 可以强制汇编程序为 MOV 选择 32 位编码,但那只会有 11 位的立即数
您可以使用支持 16 位立即值的 T3 版本的 MOV
您可以将 0 到 65535 移动到寄存器
所以 mov r1, #5000
您可以使用以下指令将任何值加载到从 0 到 65535
的寄存器
MOVW r1, #5000
我不明白为什么我不能写 mov r1, #5000
。为什么我必须改用 ldr
? R1 是 32 位寄存器,5000 在范围内。正如我发现的那样,我可以 mov r1, #255
但不能 mov r1, #256
。我觉得很奇怪。
阅读有关指令的文档,在这种情况下,指令是固定长度的,因此您在 16 位或 32 位指令中没有空间容纳指令信息(操作码等)和 32 位立即数,不是可能,因此需要对立即数进行一些限制。例如,对于 x86,它是可变指令长度,因此它们可以有很长的指令,但很容易争辩说,执行 pc-relative 加载或一些相同大小的固定长度指令不会对流水线产生显着的额外成本。所以六个中的六个。 mips 固定指令长度移动立即解决方案有其优点和缺点,并且对于每个 arm 指令集,每个都有自己的解决方案,具有优点和缺点。
对于 arm 汇编程序(当然是 gcc,可能是 arm toolchain、keil 等),您可以使用快捷方式,汇编程序将选择更简单的路径
ldr r1,=immediate
如果它不能将其编码为一条指令(请注意,有一些负向移动,程序计数器的数学运算以及它可以玩的其他技巧,您当时可能没有想到或者不知道 pc 可能不会能够使用),如果它不能那么它可以将它编码为多个指令 mov immediate 然后一个 orr,或者将它编码为 pc 相对负载。
每个指令集 mov immediate 的具体限制在 arm 体系结构参考手册中有详细记录,您可以只获得 armv7 一个,它具有该体系结构版本和先前体系结构版本的所有编码。有了这些知识,您应该能够在让汇编程序告诉您之前自己确定 mov 是否可以工作。
在 ARM Cortex-M3 中,MOV 是 16 位指令,定义如下 MOV<c>{<q>} <Rd>, #<imm8>
立即值作为操作码的一部分存储在 arm 指令中
opc[15:11]='b00100 =>which identifies instruction.
opc[10:8]=<register no>
opc[7:0]=<imm8 value>
因此,通过上述指令,您可以将 2^8 -1 =>255 作为最大立即数
虽然通过指定指令说明符 .W 可以强制汇编程序为 MOV 选择 32 位编码,但那只会有 11 位的立即数
您可以使用支持 16 位立即值的 T3 版本的 MOV 您可以将 0 到 65535 移动到寄存器
所以 mov r1, #5000
您可以使用以下指令将任何值加载到从 0 到 65535
MOVW r1, #5000