首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >理解为什么这个程序集代码添加0x20和0x1f。

理解为什么这个程序集代码添加0x20和0x1f。
EN

Ethereum用户
提问于 2021-08-30 08:26:28
回答 1查看 585关注 0票数 1

在MakerDAO的执行中定义的DSProxy函数包含以下组装代码:

代码语言:javascript
复制
assembly {
    let succeeded := delegatecall(sub(gas, 5000), _target, add(_data, 0x20), mload(_data), 0, 0)
    let size := returndatasize

    response := mload(0x40)
    mstore(0x40, add(response, and(add(add(size, 0x20), 0x1f), not(0x1f))))
    mstore(response, size)
    returndatacopy(add(response, 0x20), 0, size)

    switch iszero(succeeded)
    case 1 {
        revert(add(response, 0x20), size)
    }
}

在高层,我明白这是怎么回事。它在_target存储的上下文中委托对DSProxy契约上的函数的调用。它从剩余的津贴中减去5000股气体,以确保剩余的气体能够用于执行其余的装配代码。它将_data (定义为bytes memory的变量)传递为回调数据。然后,它将返回的值打包到response变量中(再次定义为bytes memory)。最后,它检查合同调用是否失败,如果失败,则恢复。

我很难理解这句话:

代码语言:javascript
复制
mstore(0x40, add(response, and(add(add(size, 0x20), 0x1f), not(0x1f))))

为什么他们将0x20添加到size中,0x1f添加到它的值中,最后又否定了0x1f?我理解这些是指针,但我不知道它们为什么要从这些特定的值中读取。

EN

回答 1

Ethereum用户

回答已采纳

发布于 2021-08-30 11:34:26

信息: 0x40是一个特殊地址:https://docs.soliditylang.org/en/v0.8.7/assembly.html#example

稳健性以以下方式管理内存。内存中的0x40位置有一个“空闲内存指针”。如果要分配内存,请从指针指向的位置开始使用该内存并更新它。

所以代码读为

代码语言:javascript
复制
// how much memory do we need to allocate for the response ?
    let size := returndatasize 

// load the response at the address given by the free memory pointer
    response := mload(0x40)

// save at the free memory pointer address (0x40) the next position of the available memory
    mstore(0x40, add(response, and(add(add(size, 0x20), 0x1f), not(0x1f)))) 

这是为了更新空闲内存指针(0x40)

!0x1f的下一个位置是32:

的倍数。

  • 空闲内存指针应指向圆角位置。
  • 返回数据大小不能是32的倍数(例如,可能只有5个字节)

所以这基本上是

“将空闲内存指针(0x40)设置为响应起始位置(响应)之后下一个32字节的倍数,我通过添加响应大小(大小)来计算响应起始位置(响应)”

票数 1
EN
页面原文内容由Ethereum提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://ethereum.stackexchange.com/questions/108022

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档