((((long)*(ptr))<< 1)> 1; [英] (((long)*(ptr)) << 1) >> 1;

查看:70
本文介绍了((((long)*(ptr))<< 1)> 1;的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的一个朋友问我这个问题,我不知道该函数的含义.也许像上面的注释/* sign-extend to 32 bits */.但是我想知道该函数如何实现符号扩展"角色的详细信息到32位".

One of my friends asked me this question,and I do else not know the meaning of the function.Maybe like the note above them /* sign-extend to 32 bits */.But I want to know the detail how the function realize role "sign-extend to 32 bits".

Linux内核中的功能.全部.

The function from Linux kernel. thx all.

就像@unwind说的那样,该函数的完整定义是这样的:

Like @unwind said, the complete definition of the function is this:

/* Convert a prel31 symbol to an absolute address */
#define prel31_to_addr(ptr)                         \
({                                                  \
    /* sign-extend to 32 bits */                    \
    long offset = (((long)*(ptr)) << 1) >> 1;       \
    (unsigned long)(ptr) + offset;                  \
})

,它将在函数中使用:

int __init unwind_init(void)
{
    struct unwind_idx *idx;

    /* Convert the symbol addresses to absolute values */
    for (idx = __start_unwind_idx; idx < __stop_unwind_idx; idx++)
        idx->addr = prel31_to_addr(&idx->addr);

    pr_debug("unwind: ARM stack unwinding initialised\n");

    return 0;
}

推荐答案

查看它的命名位置

Look at where it's called here as an example:

else if ((idx->insn & 0x80000000) == 0)
    /* prel31 to the unwind table */
    ctrl.insn = (unsigned long *)prel31_to_addr(&idx->insn);

因此,我们知道ptr在取消引用时传递给某个未设置其最高(第31位)位的值.如果与 prel31 名称绑定,则表示该值仅使用(低)31位.

so, we know the ptr passed in dereferences to some value whose top (31st) bit is not set. That sort if ties in with the prel31 name, implying only (the low) 31 bits are used in this value.

要将有符号的31位值转换为有符号的32位值,我们需要修正最高位:仍然只有31个 significant 位,但是负值应具有最高位.将最高位设置为与现有31位值的符号相匹配的方法是符号扩展.

To convert a signed 31-bit value into a signed 32-bit value, we need to fix up the top bit: there are still only 31 significant bits, but a negative value should have the top bit set. Setting the top bit to match the sign of the existing 31-bit value is sign extension.

通过左移一位,现有的最高位被丢弃;当我们再次向右移动时,最高位将被填充以保留符号(因此,如果原始31位值为负,则它将为1,否则为零).

By left-shifting one bit, the existing top bit is discarded; when we shift right again, the top bit will be filled to preserve the sign (so it will be 1 if the original 31-bit value was negative, and otherwise zero).

例如0x7FFFFFFF当解释为31位值(-1)时为,但是当解释为32位值(2,147,483,647)时为.要获得与31位版本具有相同含义的32位编码,我们:

eg. 0x7FFFFFFF is a negative when interpreted as a 31-bit value (-1), but positive when interpreted as a 32-bit value (2,147,483,647). To get a 32-bit encoding with the same meaning as the 31-bit version, we:

  • 向左移动以丢弃未使用的高位:0x7FFFFFFF << 1 => 0xFFFFFFFE(现在为负32位值)
  • 再次右移以恢复低31位的原始模式,但根据符号0xFFFFFFFE >> 1 => 0xFFFFFFFF = -1
  • 填充高位
  • shift left to discard the un-used top bit: 0x7FFFFFFF << 1 => 0xFFFFFFFE (which is now a negative 32-bit value)
  • shift right again to restore the original pattern in the low 31 bits, but fill the top bit dependent on the sign 0xFFFFFFFE >> 1 => 0xFFFFFFFF = -1

请注意,此(符号扩展名)行为是特定于平台的,但是所有这些代码也是如此.要理解为什么为什么(不只是 sign扩展的含义以及位模式会发生什么),您需要研究所有寻址方法(而不是简单地理解符号扩展的含义)正在使用方案.

Note this (sign extension) behaviour is platform specific, but then so is all this code. To understand why it makes sense to do all this (rather than simply the meaning of sign extension, and what happens to the bit patterns) you'll need to research the addressing scheme being used.

这篇关于((((long)*(ptr))&lt;&lt; 1)&gt; 1;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆