问题描述
我的理解是ARMv8 A64程序集中的立即参数可以是12位长.如果是这种情况,为什么这行汇编代码:
My understanding is that immediate parameters in ARMv8 A64 assembly can be 12 bits long. If that is the case, why does this line of assembly code:
AND X12, X10, 0xFEF
产生此错误(使用gcc编译时)
Produce this error (when compiled with gcc)
Error: immediate out of range at operand 3 -- `AND X12, X10, 0xFEF'
有趣的是,这一行汇编代码可以很好地编译:
Interestingly enough, this line of assembly code compiles fine:
ADD X12, X10, 0xFEF
我正在使用aarch64-linux-gnu-gcc(Linaro GCC 2014.11)4.9.3(预发行版)
I'm using aarch64-linux-gnu-gcc (Linaro GCC 2014.11) 4.9.3 (prerelease)
推荐答案
与A32的灵活的第二操作数"不同,A64中没有通用的立即数格式.对于立即操作数数据处理指令(忽略无聊而直接的指令,如移位),
Unlike A32's "flexible second operand", there is no common immediate format in A64. For immediate-operand data-processing instructions (ignoring the boring and straightforward ones like shifts),
- 算术指令(
add {s}
,sub {s}
,cmp
,cmn
)12位无符号立即数,并可以选择左移12位. - 移动指令(
movz
,movn
,movk
)采用16位立即数,可以选择移动到其中的任何16位对齐位置寄存器. - 地址计算(
adr
,adrp
)采用21位带符号立即数,尽管没有实际的语法可以直接指定它-为此,您必须借助汇编程序表达式技巧来生成适当的标签". - 逻辑指令(
和{s}
,orr
,eor
,tst
)采用立即数位掩码",我不确定我什至不能解释,因此我只引用令人难以置信的复杂定义:
- Arithmetic instructions (
add{s}
,sub{s}
,cmp
,cmn
) take a 12-bit unsigned immediate with an optional 12-bit left shift. - Move instructions (
movz
,movn
,movk
) take a 16-bit immediate optionally shifted to any 16-bit-aligned position within the register. - Address calculations (
adr
,adrp
) take a 21-bit signed immediate, although there's no actual syntax to specify it directly - to do so you'd have to resort to assembler expression trickery to generate an appropriate "label". - Logical instructions (
and{s}
,orr
,eor
,tst
) take a "bitmask immediate", which I'm not sure I can even explain, so I'll just quote the mind-bogglingly complicated definition:
这篇关于ARMv8 A64汇编中的立即值范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!