【问题标题】:why choose one's complement when writing to a register为什么在写寄存器时选择一个补码
【发布时间】:2012-01-23 10:12:09
【问题描述】:

有什么好处,例如写第一个语句与第二个语句:

第一句话:

ANCON1 = ~0x0C;

第二句话:

ANCON1 = 0xF3;

我认为第二个选择是我会做出的明确选择,因为它比第一个更直接。写我们想要的东西这么简单,为什么还要使用 One's Complement。

【问题讨论】:

    标签: c microcontroller pic microchip operands


    【解决方案1】:

    Benoit 说得差不多了。一个是补码,除了这些位,另一个是这些位。

    something&=~3;
    

    通常意味着您专注于这两个位,而 0xFC 则专注于其他位。 ~ 版本直接映射到一些平台上的一个有点清晰的指令,它让作者感觉更好地用这种方式编写它。并且 ~ 版本不太容易出现错误和错误,如果您更改变量的大小(不移动这两位),您的代码仍然可以工作,使用 0xFC 代码会损坏并且必须在使用变量的任何地方触摸。 (使用#define 隐藏常量会使调试变得更糟。如果重用定义可能会更好,但损坏已经造成)。

    在一天结束的时候,虽然它是一种风格的东西,就像

    if(!(x&something) {
    

    if((x&something)==0) {
    

    对比

    if(x&something) ; else {
    

    在绘画或绘画课上,你可能会被教导要专注于底片、背景,不要画物体的轮廓,而是要画出不是物体的轮廓。

    在大学里(电子工程,至少在计算机工程出现之前的几十年前),我们被鼓励从否定逻辑的角度进行思考。有时断言意味着积极的逻辑,有时是消极的逻辑,不要只思考一种方式。 (同样认为断言或打开是正电压,VCC,而取消断言或关闭是接地)

    通过这种按位运算,尤其能够以任何一种方式读取代码,“我将这些位归零”与“我没有将这些位归零”。因为两者都是正确的,只是风格不同。

    将 0xC 写为 0xF3 就像“简单”一样,例如,如果您被口头告知或数据表说 bits[3:2] 是某物,当为零时。大脑将其处理为 0xC 并不是一件容易的事,要将其处理为 0xF3,您必须找到有关事物长度的更多信息,然后在到达 0xF3 之前和之后处理位。或者你从 0x0C 在你的脑海中做了 0xF3,你可以只使用 ~0x0C 并保存该步骤。如果有一个图表显示所有位并排并标有字段,那么它变成一个玻璃是半空或半满的东西,你和你的眼睛可能很容易集中在负片上并直接拉 0xF3 或集中在 0x0C 然后反转为获得 0xF3 或专注于 0xF3 并且必须反转才能获得 0x0C。

    这两个优点远不及另一个重要的是,在少数处理器上,它直接与一条指令相关联,优化器不必努力工作,(微优化),另一个是避免软件错误的习惯。如果您在几年前使用带有 0xFFFFFFF3 的 int,然后在今天编译该代码而没有针对 64 位机器进行任何修改,您可能已经陷入了一个错误。如果在代码中习惯性地使用该方法,则需要进行大量移植。如果使用了 ~0xC,那么该代码可能会更顺利地移植。一个暗示变量的大小,另一个不暗示。

    【讨论】:

      【解决方案2】:

      我读了第一个All but 00001100 和第二个11110011。我发现更容易理解哪些位不是在心理上设置的,因为更少。

      【讨论】:

      • @Mitch Wheat,只是出于好奇,在谈到比特时说“他们更少”在英语中是不正确的还是不习惯用语?
      • 我认为在这种情况下它是不正确的(但很高兴得到纠正!)
      • 此外,寄存器实际上可能会倒计时,就像 8 位 Microchip 的定时器持续时间寄存器一样。
      【解决方案3】:

      没有区别,因为这两个值都是常量,并且第一个值将被您的编译器计算并优化为第二个值。使用让你和其他程序员更容易理解代码的那个。

      另一件事是,如果您使用 variable-to 否定,然后在大多数微控制器上将变量写入寄存器使用 2 个命令,而仅将变量写入寄存器使用 1。

      【讨论】:

        【解决方案4】:

        首先,~ 表示按位补码。不要将其与反码混淆,反码是将十六进制转换为有符号整数格式的一种方式。

        关于好的/坏的做法,你的两个例子都不好,因为它们使用的是“幻数”。编写相同代码的好方法是

        #define MASK 0x0C
        
        ANCON1 = ~MASK;
        

        由于 MASK 是有意义的,而 0xF3 是一些随机幻数,您应该使用前者,然后将其取反。

        请注意,用于整数常量的 ~ 运算符在编译时进行了预处理。实际的机器代码仍然类似于LOADx $F3

        【讨论】:

        • 感谢您解决恭维问题。如果您认为这个面具有意义,那么您可能已经从事了一段时间的编程并且了解很多。也许应该做的只是声明 0b11110011
        【解决方案5】:

        这通常只是风格问题。第一个,x = ~y 是一个惯用语,通常用于表示设置x 中的所有位,y 中的位除外

        它更常与&= 运算符一起使用。例如x &= ~y 表示清除x 中设置在y 中的位。在这种情况下,写起来更易读,例如x &= ~0x40 而不是x &= 0xFC

        【讨论】:

        • 谢谢,我自己发现并立即更新了答案。
        猜你喜欢
        • 2011-02-22
        • 2012-01-18
        • 2019-04-11
        • 2014-04-06
        • 2014-10-31
        • 1970-01-01
        • 1970-01-01
        • 2020-09-14
        相关资源
        最近更新 更多