我刚开始武装世界。在ARM Cortex-A系列:程序员指南(第71页)中,有一个关于BIC指令的例子:
BIC R0, R0, #0x800根据文本,这基本上清除了R0中的第11位。我知道BIC在这里的工作方式类似于R0 = R0 & (~val) (请纠正我)。但我不明白的是,#0x800是如何被理解为- is并被翻译成1000 0000 0000的。相反,它应该按照直接编码规则分成4位:8位部分。
根据我对ARM常量编码的理解:
0x800 = 0000 1000 0000 0000在这些比特中,我们只考虑最后12位用于编码,在这12位中,前4位决定2步的右旋转,最后8位是正确旋转的数(考虑32位)。所以在这种情况下,由于最后8个位都是零,我应该在2*8正确旋转后得到FFFF 0000。
对于上述完整的BIC指令,应将其视为:
R0 = R0 & (0000 FFFF)我知道我错了。谁能帮我纠正一下。
发布于 2020-08-11 14:51:12
简单地说,您没有在程序集中包含编码的文字字段,而是包含了实际想要使用的有意义的值。汇编程序的工作包括确定指定程序集的指令编码(如果有一个最好的话)。
汇编程序负责将程序集中提供的值编码到指令的文字字段中。#0x800是字面意思。作为一个汇编程序程序员,您只需要确保文字是可编码的。
这将是烦人和难以置信的错误,必须计算编码旋转。这种类型的转换是程序集和机器代码之间很大的区别。要查看实际生成的文字字段,请查看组装后的结果。
这也导致了一些ISAs中的程序集和机器代码之间的一些非1到1的关系。
值0x800直接是0b1000_0000_0000。
拼装
BIC R0, R0, #0x800给我
02 0B C0 E3所以Operand2字段是0xB02。这意味着直接的是0x02,旋转是0xB。取0x00000002,通过2 * 0xB旋转,得到期望的0x800。
发布于 2020-08-11 16:15:59
你自己试试就行了。
.syntax unified
bic r0,r0,#0x800
.thumb
bic r0,r0,#0x800
Disassembly of section .text:
00000000 <.text>:
0: e3c00b02 bic r0, r0, #2048 ; 0x800
4: f420 6000 bic.w r0, r0, #2048 ; 0x800A1编码
e3c00b02
101100000010 (b02)
1011 00000010将位模式00000010右移11*2位,与左10位置相同
00000010 0000000000
000000100000000000
000000 1000 0000 0000
0x800T1编码
f420 6000
1111010000100000 0110000000000000
xxxxx1xxxxxxxxxx x110xxxx00000000
11100 0000000
11100 abcdefg
1bcdefg0 shifted left 3
1abc defg 0000
1000 0000 0000
0x800在ARM文档中都有清楚的描述。指令指向文档( ARM )的一部分,该部分显示直接位的编码。这不是mips,这是ARM;它不一定直接映射到指令中,ARM因其桶形移位器而闻名。
我避免使用ARM的一个文档(类型)是程序员指南,它不是他们更好的文档之一。
您需要有关核心的技术参考手册(ARM TRM)和该核心中的体系结构的架构参考手册( ARM ) (本例中为armv7 7-ar)。
对于ARM (现在缺少一个更好的术语的aarch32)来说,有8个重要的比特可以被平数地移动,所以
bic r0,r0,#0x102
100000010 (0x102)
10000001 (0x81)不管用
so.s:2: Error: invalid constant (102) after fixup但
bic r0,r0,#0x20430 (0x81 >> 30)
大拇指
bic r0,r0,#0x00220022很好,但对手臂来说不是
so.s:3: Error: invalid constant (220022) after fixup只需阅读ARM的文档,就可以清楚地描述。
https://stackoverflow.com/questions/63360646
复制相似问题