1
2
选择7(以10为基数),因为其二进制表示为111(以2为基数的7)。 至于为什么设置8、9和10位,是因为你从错误的方向读取。二进制,就像正常的基数10一样,从右到左计数。 (我将此作为评论,但声誉不够高。) |
2
1
如果您想隔离和更改寄存器中的一些位,但不是理解诸如and和or以及xor之类的逐位操作所需的全部,并且不在单个位列上操作,则每个操作数的位3用于确定结果的位3,不涉及其他位。所以我有一些二进制位,用字母表示,因为它们可以是1或0
任何与一相关的事物都是一,任何与零相关的事物都是它本身。
因此,如果要隔离并更改此变量/寄存器中的两个位,即位5和位6,并将其更改为0b10(十进制中的2),常用方法是将其与零相加,然后将其与所需值相加
在c中
让我们深入研究一下(3<<5)
这将两个一放在我们感兴趣的位的顶部,但与该值anding将隔离位,并将其他位弄乱,因此为了将这些位归零,而不弄乱寄存器中的其他位,我们需要反转这些位 使用x=~ x将这些位反转为逻辑非运算。
现在我们有了想要的掩码,寄存器如上所示,将有问题的位归零,而其他位则保持j00mnopq 现在我们需要准备or(2<<5)的位
给出我们想要的位模式,或者给出我们写回寄存器的j10mnopq。又是j、m、n。。。位是位,它们要么是一,要么是零,我们不想改变它们,所以我们做了额外的掩蔽和移位工作。您可能/有时会看到简单写入寄存器的示例(blah,2<<5);要么因为他们知道其他位的状态,知道他们没有使用这些其他位,零是可以/需要的,要么不知道他们在做什么。
如果有一个3位字段,则二进制为0b111,十进制为数字7或十六进制0x7。一个4位字段0b1111,它是十进制15或十六进制0xF,当您超过7时,更容易使用十六进制IMO.6位字段0x3F,7位字段0x7F等等。 你可以在某种程度上进一步理解这一点,使其更加通用。如果有一个寄存器控制gpio引脚0到15的某些功能。从位0开始。如果您想更改gpio引脚5的属性,那么将是位10和11,5*2=10,有两个引脚,因此10和下一个引脚11。但一般来说,你可以:
因为2是2的幂
如果pin不能在编译时减少到特定值,编译器可能会进行优化。 但是如果它是每个字段3位,并且字段开始与零位对齐
编译器可能会用3乘法,但可能只是 pinshift=(pinshift<1)| pinshift; 得到乘以3的结果。取决于编译器和指令集。 总的来说,这被称为读-修改-写,当你读一些东西时,修改其中的一些,然后写回(如果你修改了所有的东西,你不需要费心读和修改,你会写整个新的值)。人们会说,为了修改的目的,或者如果你想读/看看上面的两位是什么,那么屏蔽和移位通常会覆盖隔离变量中的位
或先遮罩,然后移位
一个半打的另一个指令集中有六个指令集,通常都是相等的,一些指令集一个可能比另一个更有效(或者可能是相等然后移位,或者移位然后and)。对于某些人来说,其中一个可能比另一个更有视觉意义。 虽然从技术上讲,这是一个端值问题,因为某些处理器的位0是最重要的位。在C AFAIK中,位0是最低有效位。如果/当手册显示从左到右排列的位时,您希望您的左右移位与之匹配,因此如上所述,我显示了76543210以指示记录的位,并将其与jklmnopq关联,这是重要的从左到右信息,以继续关于修改位5和6的对话。一些文档将使用verilog或vhdl风格的符号6:5(意味着包含6到5位,更有意义的是4:2意味着4,3,2位)或[6到5],更可能只看到带有方框或线条的视觉图片,向您显示哪些位是什么字段。 |
3
0
要清除三个相邻的位。字底部的三个相邻位为1+2+4=7。
你想清除位21-23,而不是位1-3,所以你左移另一个20。 你的两个例子都错了。要清除15-17,您需要向左移动14;要清除21-23,您需要向左移动20。 不,不是。你数错了。 |
user3397008 · aeabi_fmul从哪里链接? 7 年前 |