【问题标题】:Why are we adding 0 to a double void pointer here?为什么我们在这里将 0 添加到双 void 指针?
【发布时间】:2019-08-07 05:42:04
【问题描述】:

就上下文而言,这是从引导加载程序调用的代码,该引导加载程序应该引导到主应用程序。这个 sn-p 来自一个带有参数 uintptr_t address 的函数,该参数指定了主应用程序已写入的地址。我相信sppc 分别是堆栈指针和程序计数器。

代码如下:

sp = *((void **)address + 0);
pc = *((void **)address + 1);
start_new_application(sp, pc);

完整上下文here

然后我去打印了地址、sp、pc,发现如下:

address -> 0x08010000
sp ------> 0x20050000
pc ------> 0x080132DD

这让我很困惑。我不确定为什么 sp 行中有一个 + 0 。是否可以将 sp 行重写为:

sp = (void *)address;

然后做同样的事情?

我的理解是地址已被静态转换为双空指针,然后sp 被赋予了地址的取消引用值(0x08010000),pc 被赋予了地址的取消引用值(0x08010001)。然后,在我的 printf 语句中,显示的这些值是 那些 地址的取消引用值。

我的理解正确吗?

【问题讨论】:

  • 冗余;放在那里是为了对齐/漂亮的打印目的?
  • address 可能包含指针数组的地址。顺便说一句,不要用int 这样做。它们并不总是与指针大小相同。如今,int 通常是 32 位,而指针是 64。使用 intptr_t 来处理此类内容。
  • @user4581301 :地址是一个 uintptr_t ,可以在完整的上下文代码中看到。请参阅 github 链接。

标签: c++ pointers embedded program-counter stack-pointer


【解决方案1】:

+ 0 只是为了便于阅读。

sp = *((void **)address + 0);
pc = *((void **)address + 1);

做同样的事情

sp = *((void **)address);
pc = *((void **)address + 1);

或使用 C++ 强制转换和下标运算符:

sp = reinterpret_cast<void**>(address)[0];
pc = reinterpret_cast<void**>(address)[1];

sp 行是否可以改写为:

sp = (void *)address;

不,这会使sp 等于address,这不是原始代码所做的。原码从指向的地址中提取一个void**address

【讨论】:

    猜你喜欢
    • 2021-02-02
    • 1970-01-01
    • 2021-07-22
    • 2013-12-18
    • 2011-06-15
    • 1970-01-01
    • 1970-01-01
    • 2020-12-10
    • 1970-01-01
    相关资源
    最近更新 更多