【问题标题】:Align Address 4 bytes off of an 8-byte boundary将地址与 8 字节边界对齐 4 字节
【发布时间】:2023-03-25 13:13:01
【问题描述】:

对于我正在处理的程序,我需要将地址四舍五入到最近的 8 字节边界之外的 4 字节。也就是说,地址必须以这样的方式修改,即它们以 0x4 或 0xC 结尾并且大于或等于它们的当前值。每个地址都是一个 64 位整数,指向内存中的一个字节 (sizeof(*addr) = 1)。地址保证是无符号的。

我知道可以使用以下代码 sn-p 找到最接近的 8 字节边界,简单的答案是简单地将 0x4 添加到该值,但是,这会导致一些高估该值的问题。

#define align_8(addr) (((addr) + 7) & (~7))

例如,假设我们有地址0x500B。我希望它对齐的值是0x500C,但是如果我们对齐到最近的 8 字节边界 (0x5010),然后添加 0x4,我们将以 0x5014 结尾。这会跳过我不想被跳过的 8 个字节。

我希望能够使用类似于我在此处提供的 8 字节对齐宏的简单宏来执行此操作。任何帮助将不胜感激,谢谢!

【问题讨论】:

  • while (addr %8 != 4) addr++; 有效。其他想法可以避免循环。
  • @chux 谢谢,我暂时用这个。
  • 提示:注意失败的解决方案addr < 4
  • @chux 可能会在算术之前转换为uintptr_tsizeof(*addr) 可能不是 1
  • @AjayBrahmakshatriya 好点。 OP 没有说明 addr 的类型,除了隐含在 let's say we have the address 0x500B 之类的东西中,所以 addr 似乎已经被整数化了。

标签: c bit-manipulation


【解决方案1】:

有时它有助于向后看问题。

   A    B  C    D    E    F
5003 5004 +1 4FFE 4FF8 5004
5004 5004 +0 4FFF 4FF8 5004
5005 500C +7 5000 5000 500C
5006 500C +6 5001 5000 500C
5007 500C +5 5002 5000 500C
5008 500C +4 5003 5000 500C
5009 500C +3 5004 5000 500C
500A 500C +2 5005 5000 500C
500B 500C +1 5006 5000 500C
500C 500C +0 5007 5000 500C
500D 5014 +7 5008 5008 5014
500E 5014 +6 5009 5008 5014

观察:

(A) What you have
(B) What you want
(c) Distance A to B

构建算法以酌情添加 0...7:

(D) Subtract 5 from (A)
(E) And (D) with 0xFFFFFFFFFFFFFFF8 to get rid of the 3 LSBs
(F) Add decimal 12 to (E)

由于 (F) = (B),通过这些操作实现了目标:

((Addr - 5) & 0xFFFFFFFFFFFFFFF8) + 12

【讨论】:

  • 注意:~7idea需要补齐正确的类型。 ~7 可能只有 0xFFFFFFF8,但地址大于 32 位。
【解决方案2】:

需要将地址四舍五入到最近的 8 字节边界之外的 4 字节

假设addr 是某种整数类型,例如(u)intptr_t,具有非负值或可转换为一的地址:

// Only evaluates `addr` once.
#define align8_plus4(addr) ((void*)(((uintptr_t)(addr) + 4 - 1)/8)*8 + 4))

char *addr_aligned = align8_plus4(addr_unaligned)

角落案例:
1) 0-3 作品。
2) (uintptr_t)(addr) + 4 - 1溢出时,由于没有正确答案,无法提供正确答案。


注意:这不是高度可移植的代码,生成这样的地址不知道是有效的。然而应该适用于 OP 的选择案例。一种可移植的方法会考虑更高级别的目标,即为什么需要这个 +4。

【讨论】:

  • 这个宏不起作用。我已经在多种情况下进行了尝试,它给出了不同数量的不正确的偏移量。例如,22 应该导致偏移量为 2,而这个宏产生的结果是 5。同样,85 应该导致结果为 7,但它产生的结果是 4。
猜你喜欢
  • 2017-07-28
  • 1970-01-01
  • 2015-03-10
  • 2011-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-13
  • 1970-01-01
相关资源
最近更新 更多