static数组
请问c++中static数组如何存储?为什么定义数组时,没有相应的汇编语言??超出数组范围的值却是0,而不是随机数。static数组中的赋值怎么赋进去的?我很奇怪,初始化这个static数组时它的汇编代码居然没有???输出的时候数值从哪来??最起码一般数组我看到通过通用寄存器来把数值赋进去,可他一句没有 定义static数组确实不会生成汇编代码,即使有初始值也不会生成汇编代码这个初始值是直接db到data段的,这个初始值最后保存在了可执行文件的data段
人造人 发表于 2020-2-6 23:04
定义static数组确实不会生成汇编代码,即使有初始值也不会生成汇编代码
这个初始值是直接db到data段的,这 ...
那对这个static数组是如何赋值进去的?请问 我这样解释,看看你能不能理解
首先有如下代码
编译得到可执行文件main
然后用nm得到arr数组的地址
有一个arr.2311的符号在data段
我们看一下这个程序的汇编文件
可以看到这个arr数组被编译器改名字了,改成了arr.2311
这个arr在data段,地址是 0x4030
data段从0x4020开始,也就是说arr数组在可执行文件中的偏移是 0x3030
可以看到,arr数组是保存在data段的
执行这个文件的时候,系统会把data段加载到内存,也就是arr的内容会一起加载到内存,会加载到地址 0x4030的位置
等执行到main函数的时候arr中的那些数据就已经在内存地址 0x4030的位置了
可以直接访问这个地址就可以读取到arr数组中的内容
这次是地址 0x4a90f0,可以看到在汇编代码中直接访问的这个内存地址
arr中的数据是保存在data段的,系统会把arr的内容加载到地址 0x4a90f0
在程序中直接访问这个地址就可以访问到arr数组了
人造人 发表于 2020-2-7 00:51
这次是地址 0x4a90f0,可以看到在汇编代码中直接访问的这个内存地址
arr中的数据是保存在data段的, ...
那请问超出数组范围的值为什么全是0呢?而不是任意值? suqiang357 发表于 2020-2-7 18:54
那请问超出数组范围的值为什么全是0呢?而不是任意值?
是吗?下面的截图如何解释?
本帖最后由 suqiang357 于 2020-2-7 20:01 编辑
人造人 发表于 2020-2-7 19:06
是吗?下面的截图如何解释?
当我把它定义为staticchar数组时,超出范围它直接不输出。。。staticint数组超范围它输出0 suqiang357 发表于 2020-2-7 19:55
当我把它定义为staticchar数组时,超出范围它直接不输出。。。staticint数组超范围它输出0
数组越界访问的行为本来就是未定义的,也就是编译器想怎么弄就怎么弄
不管输出了什么样的结果,也都是符合标准的
因为标准对此的定义就是”未定义”的
人造人 发表于 2020-2-7 20:14
数组越界访问的行为本来就是未定义的,也就是编译器想怎么弄就怎么弄
不管输出了什么样的结果,也都是符 ...
我以为static数组所在的地方,未初始化的地方系统就默认为0;我还有一个大胆的想法,static数组存放在data段,data段内存大小在编译连接时自动分配,它和程序大小没有关系,但和程序使用到的全局变量,常量数量相关,我以为我程序未定义其他的全局变量,常量,然后data段就只存放它,输出0的地方可能是我访问到了bss段了。、、、 suqiang357 发表于 2020-2-7 20:20
我以为static数组所在的地方,未初始化的地方系统就默认为0;我还有一个大胆的想法,static数组存放在dat ...
具体你可以让你的编译器在执行完编译阶段后停下来,你可以看一看编译后的汇编代码 #include <stdio.h>
int main(void)
{
static unsigned char arr[] = {1, 2, 3, 4, 5};
return 0;
}
void test(void)
{
static unsigned char arr[] = {11, 22, 33, 44, 55};
}
gcc -S main.c
.file "main.c"
.text
.def __main; .scl 2; .type 32; .endef
.globl main
.def main; .scl 2; .type 32; .endef
.seh_proc main
main:
pushq %rbp
.seh_pushreg %rbp
movq %rsp, %rbp
.seh_setframe %rbp, 0
subq $32, %rsp
.seh_stackalloc 32
.seh_endprologue
call __main
movl $0, %eax
addq $32, %rsp
popq %rbp
ret
.seh_endproc
.globl test
.def test; .scl 2; .type 32; .endef
.seh_proc test
test:
pushq %rbp
.seh_pushreg %rbp
movq %rsp, %rbp
.seh_setframe %rbp, 0
.seh_endprologue
nop
popq %rbp
ret
.seh_endproc
.data
arr.2979:
.byte 1
.byte 2
.byte 3
.byte 4
.byte 5
arr.2983:
.byte 11
.byte 22
.byte 33
.byte 44
.byte 55
.ident "GCC: (GNU) 7.4.0"
页:
[1]