为什么文字值在放入堆之前先从只读内存复制到堆栈?

Why are literal values copied from read-only memory to the stack before being placed in the heap?

当我尝试使用 Rust 时,我注意到如果盒装数组是从带有 Box::new 的文字创建的,则会从只读内存额外复制到堆栈。为什么 Rust 编译器不能直接从只读内存复制到堆上分配的 space?

Rust代码片段:

fn main() {
    let v: Box<[u32]> = Box::new([1u32,2,3456,4,5,6]);
    println!("vector {}", v.len());
}

合适的汇编片段:

00000000000049d4         mov        rax, qword [ds:0x39ad0]
00000000000049db         mov        qword [ss:rsp+arg_F8], rax
00000000000049e3         movaps     xmm0, xmmword [ds:const1050]
00000000000049ea         movaps     xmmword [ss:rsp+arg_E8], xmm0
00000000000049f2         mov        ecx, 0x18
00000000000049f7         mov        edi, ecx                                    ; argument #1 for method _ZN4heap15exchange_malloc20h356508549306a536JeaE
00000000000049f9         mov        ecx, 0x4
00000000000049fe         mov        esi, ecx                                    ; argument #2 for method _ZN4heap15exchange_malloc20h356508549306a536JeaE
0000000000004a00         call       _ZN4heap15exchange_malloc20h356508549306a536JeaE ; heap::exchange_malloc::h356508549306a536Jea
0000000000004a05         mov        rsi, qword [ss:rsp+arg_F8]
0000000000004a0d         mov        qword [ds:rax+0x10], rsi
0000000000004a11         movaps     xmm0, xmmword [ss:rsp+arg_E8]
0000000000004a19         movups     xmmword [ds:rax], xmm0

数组驻留在二进制文件中的 0x39ad0const1050 处:

0000000000039ac8         db  0x80 ; '.'
0000000000039ac9         db  0x0d ; '.'
0000000000039aca         db  0x00 ; '.'
0000000000039acb         db  0x00 ; '.'
0000000000039acc         db  0x04 ; '.'
0000000000039acd         db  0x00 ; '.'
0000000000039ace         db  0x00 ; '.'
0000000000039acf         db  0x00 ; '.'
0000000000039ad0         dq  0x0000000600000005                          ; XREF=_ZN4main20h90e2c514439f0097eaaE+52

您的发现是正确的;这是 Box::new() 是常规函数的结果。

将值直接放在堆上的正确方法是使用放置运算符;然而,目前 Rust 中没有这样的东西,但是有两个 RFC,this (accepted) and this(待定,但似乎可能被接受)。另外,如果你每晚都在使用 Rust,你可以使用不稳定的 box 语法:

let v: Box<[u32]> = box [1u32,2,3456,4,5,6];