gpt4 book ai didi

c - (((long)*(ptr)) << 1) >> 1;

转载 作者:太空狗 更新时间:2023-10-29 11:38:54 26 4
gpt4 key购买 nike

我的一个 friend 问我这个问题,我不知道这个函数的含义。可能就像他们上面的注释一样/* sign-extend to 32 bits */。但是我想知道函数如何实现“符号扩展到 32 位”的详细信息。

来自 Linux 内核的函数。谢谢大家。

如@unwind所说,函数的完整定义是这样的:

/* 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;
}

最佳答案

看哪里叫here举个例子:

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

所以,我们知道 ptr传递对某个值的取消引用,该值的最高(第 31)位未设置。该排序 if 与 prel31 名称相关联,暗示此值中仅使用(低)31 位。

要将带符号的 31 位值转换为带符号的 32 位值,我们需要修复最高位:仍然只有 31 有效位,但负值应该具有最高位设置。设置最高位以匹配现有 31 位值的符号是符号扩展

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

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

  • 向左移动以丢弃未使用的最高位:0x7FFFFFFF << 1 => 0xFFFFFFFE (现在是负 32 位值)
  • 再次右移以恢复低 31 位中的原始模式,但根据符号 0xFFFFFFFE >> 1 => 0xFFFFFFFF = -1 填充最高位。

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

关于c - (((long)*(ptr)) << 1) >> 1;,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12578934/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com