Dom*_*ice 3 c arrays assembly stack-memory
让我们假设我int在函数中定义了一个默认值为0 的本地s 数组:
void test() {
int array[256] = {0};
}
Run Code Online (Sandbox Code Playgroud)
我对此的理解是:
通过将256个零推入堆栈并因此增加堆栈指针,数组将存储在堆栈中.如果数组没有默认值,那么增加堆栈指针就足够了.
现在这是前一个片段生成的汇编代码:
test:
.LFB2:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
pushl %edi
pushl %ebx
subl $1024, %esp
.cfi_offset 7, -12
.cfi_offset 3, -16
leal -1032(%ebp), %ebx
movl $0, %eax
movl $256, %edx
movl %ebx, %edi
movl %edx, %ecx
rep stosl
addl $1024, %esp
popl %ebx
.cfi_restore 3
popl %edi
.cfi_restore 7
popl %ebp
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE2:
.size test, .-test
Run Code Online (Sandbox Code Playgroud)
我意识到这可能是一个愚蠢的问题,我知道每个编译器可能采取不同的行为,但我想知道在哪里发生了256个零的数组分配.我的假设是正确的还是这种情况发生了不同?
(我已经很长时间没有写集会了,我在理解正在发生的事情上遇到了一些困难)
分配发生在这里:
subl $1024, %esp
Run Code Online (Sandbox Code Playgroud)
它是sub堆栈指针esp,因为堆栈增长了.
数组在这里清除:
movl $0, %eax
movl $256, %edx
movl %ebx, %edi
movl %edx, %ecx
rep stosl
Run Code Online (Sandbox Code Playgroud)
这样做是:
rep:重复字符串操作ecx次数stosl:存储eax在指向的内存中,edi并向edi添加4,或者减去4,具体取决于方向标志.如果它是clear(cld),则edi递增,否则递减.注意,ebx设置为在代码中稍早一点指向数组的开头.最后,这里发布了数组:
addl $1024, %esp
Run Code Online (Sandbox Code Playgroud)
pushl %ebp # preserve caller's ebp (decrements esp by 4)
movl %esp, %ebp # copy stack pointer to ebp
pushl %edi # preserve for caller
pushl %ebx # preserve for caller
subl $1024, %esp # allocate 1kb on the stack
leal -1032(%ebp), %ebx # esp + 1024 + 4 + 4 = ebp; equivalent to mov %esp, %ebx
movl $0, %eax # the {0}
movl $256, %edx # the repeat count - could have been stored in ecx directly
movl %ebx, %edi # init edi to the start of the array
movl %edx, %ecx # put 256 in ecx
rep stosl # repeat 'mov %eax, %(edi); add $4, %edi' ecx times
addl $1024, %esp # release the array
popl %ebx # and the preserved registers
popl %edi
popl %ebp
ret
Run Code Online (Sandbox Code Playgroud)