c*****e 发帖数: 737 | 1 "abc" is in .rodata section, not heap.
# objdump -s -j .rodata str
Contents of section .rodata:
80486e8 03000000 01000200 00000000 61626300 ............abc.
80485c5: 89 44 24 08 mov %eax,0x8(%esp)
80485c9: c7 44 24 04 f4 86 04 movl $0x80486f4,0x4(%esp)
80485d0: 08
80485d1: 8d 45 ec lea -0x14(%ebp),%eax
80485d4: 89 04 24 mov %eax,(%e... 阅读全帖 |
|
r****o 发帖数: 1950 | 2 void foo()
{
int a=3;
}
int main()
{
foo();
return 0;
}
上面的常数3是不是先放在RODATA 数据段,在main()函数执行foo()的时候再从RODATA读
出来赋给stack上面的a变量。
这样,RODATA和stack都有一个地方存了这个3。
对吗? |
|
y*****a 发帖数: 171 | 3 下面是汇编代码,string "abcde" is in readonly section (.rodata). 除非你修改
gcc default linker script, you cannot write to this address
.file "l.c"
.section .rodata
.LC0:
.string "abcde"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
andl $-16, %esp
movl $0, %eax
addl $15, %eax
addl $15, %eax
shrl $4, %eax
sall $4, %eax
|
|
y*****a 发帖数: 171 | 4 "string literal" is pre-allocated in .rodata section at compile time (no memory lead proble). a[] is local to the stack but not directly point to the string (see the assemble code). p directly points to "string literal".
.section .rodata
.LC0:
.string "string literal" |
|
r****o 发帖数: 1950 | 5 Thanks.
So in ARM, if the array initiazation is a little large, for example,
void foo()
{
int a[5][100] = {{1,2,...,100},{2,3,...,101},{3,4,...,102},{4,5,...,103},{
5,6,...,104}};
//some operation that will use a[][];
}
Then the initialization
{{1,2,...,100},{2,3,...,101},{3,4,...,102},{4,5,...,103},{5,6,...,104}}
will always be in RODATA. Correct?
And when foo() is executed, the CPU will copy the initialized data above
from RODATA to the stack for a[][] array. Correct? |
|
r****o 发帖数: 1950 | 6 谢谢,
我比较了一下当initilization data是large array和short array的两种情况下的ARM
assembly code,发现确实前者会被stored 到RODATA,并且function执行的时候RODATA的
数据会被copy到stack。而short array就是直接在stack上用数值初始化了。
I |
|
w***g 发帖数: 5958 | 7 前面的回复了的除了SSA以外,别的都是不懂装懂,一看就知道有多少水平。竟然还有
人说这个不是c的强项。你这个问题问得挺好,我给你演示一下。源程序叫hello.c,
贴在最后
$ make hello
$ objdump -t hello | grep XXX
00000000004006ec g F .text 00000000000001b1 XXX_TEXT
0000000000601070 g O .data 0000000000000004 XXX_DATA
0000000000400968 g O .rodata 0000000000000001 XXX_RODATA
0000000000601078 g O .bss 0000000000000004 XXX_BSS
$ ./hello
Global:
&XXX_DATA: 0x601070
&XXX_BSS: 0x601078
... 阅读全帖 |
|
S*A 发帖数: 7142 | 8 是 .rodata 啦。
这个 “abc” 是 const, 不应该被改变的。
rodata 有可能被 mmap read only。
你试图改变就会 segfault。 |
|
y*****a 发帖数: 171 | 9 how could it be in the heap, you never call alloc for this, do you. it is
done by the compiler. you got it clear?
l.c
char *x1="abc1";
char x2[]="abc2";
gcc -s -c l.c
cat l.s
.file "l.c"
.globl x1
.section .rodata
.LC0:
.string "abc1"
.data
.align 4
.type x1, @object
.size x1, 4
x1:
.long .LC0
.globl x2
.type x2, @object
.size x2, 5
x2:
.string "abc2"
.ident "GCC: (GNU) 4.1.2 2008 |
|
h*********e 发帖数: 56 | 10 windows不知道,以linux gcc为例:
the address map of a process is as follows:
(starting from 0x00000000 to 0xbfffffff)
1. text section: program code (read only)
2. data section: initialized global variables, and static vars (in
function)
3. bss section: uninitialized global variables\
4. heap section: dynamically allocated memory by malloc (new)
5. shared library or memory mapped files
6. stack: function activation frames and local variables
还有一些无关紧要的section,比如 rodata 用来存放 string literals。但直到以上
几个主要的sect |
|
c***p 发帖数: 221 | 11 According to gcc/g++, "abc" is located at .rodata section, will loaded to a
read only segment by loader.
location of variable c depends, will be in .data section if it is global, in
stack if it is local |
|
l*****e 发帖数: 276 | 12 我试了一下不开 -O3 ,float 还是比 double 慢一倍。 对了,我用的是gcc 4.1.2
这是不开 -O3 的 float:
.file "test.cpp"
.section .rodata
.align 8
.LC1:
.long 3944497965
.long 1058682594
.align 4
.LC2:
.long 1065353216
.text
.align 2
.globl main
.type main, @function
main:
.LFB2:
pushq %rbp
.LCFI0:
movq %rsp, %rbp
.LCFI1:
movl $0x00000000, %eax
movl %eax, -8(%rbp)
jmp .L2
.L3:
movl $0x00000000, %eax
movl %eax, -4(%rbp)
jmp .L4
.L5:
cvtss2sd -4(%rbp), %xmm0
movsd .LC1(%rip), %xmm1
addsd %xmm1, %xmm0
cvtsd2ss %xmm0, %xmm0
movss %x |
|
j*******d 发帖数: 8834 | 13 depending on your machine/arch/compiler
"hello" could be in text segment, or the .rodata, or even data segment.
如果是前二,大多数OS会直接seg fault你
如果是data segment,应该没问题。 |
|
r****t 发帖数: 10904 | 14 字符串常量的初始化是在 compile time. ROData 节里面。 |
|
m********2 发帖数: 89 | 15 It depends on the compiler and architech.
I think, for example, arm-gcc will, in general, try to embed numbers into
instructions as immediate numbers before try the .rodata section and the
numbers you give can be used as immediate numbers. |
|
m********2 发帖数: 89 | 16 It make sense for a large array of initialization data to be stored in .
rodata section to be read later with ldm instructions. But I am not sure. I
need to try some cases and get back to you.
,{ |
|
V*********r 发帖数: 666 | 17 使得其中的不同变量分布在virtual address space的不同segments
(code,data,bss,heap,stack,rodata,constant,...)
里面,并指出那个变量在哪个segment? |
|
S*A 发帖数: 7142 | 18 因为我最近在 hack 这个 Pogoplug V4 mobile。我顺便帮
你看了以下。
我从 UBoot 上面去掉了 serial cosole。这个是 dmesg。
时钟初始化是在 12 妙开始, 并不是 Linux 真正启动了 12 妙。
所以走到 systemd 启动也才 3.5 秒钟。注意其中有 USB 硬盘
访问,因为那个 rootfs 是在 USB 上面。仔细看 demsg,去掉
USB 硬盘访问,去掉 SATA 寻找硬盘,去掉 Ethernet 寻找
Link 的时间,剩下初始化应该就在 2 秒钟以内了。这个 3.5
秒钟很多时间是在和 USB storage 的东西相关。你只要
rootfs 不在 USB flash 上面,这些都可以启动的时候不做。
所以 2 秒钟启动应该是可以的,不需要特别多定制。
基本上改改 kernel config 或者启动参数就可以了。
[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Initializing cgroup subsys cpuset
[ ... 阅读全帖 |
|
S*A 发帖数: 7142 | 19 因为我最近在 hack 这个 Pogoplug V4 mobile。我顺便帮
你看了以下。
我从 UBoot 上面去掉了 serial cosole。这个是 dmesg。
时钟初始化是在 12 妙开始, 并不是 Linux 真正启动了 12 妙。
所以走到 systemd 启动也才 3.5 秒钟。注意其中有 USB 硬盘
访问,因为那个 rootfs 是在 USB 上面。仔细看 demsg,去掉
USB 硬盘访问,去掉 SATA 寻找硬盘,去掉 Ethernet 寻找
Link 的时间,剩下初始化应该就在 2 秒钟以内了。这个 3.5
秒钟很多时间是在和 USB storage 的东西相关。你只要
rootfs 不在 USB flash 上面,这些都可以启动的时候不做。
所以 2 秒钟启动应该是可以的,不需要特别多定制。
基本上改改 kernel config 或者启动参数就可以了。
[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Initializing cgroup subsys cpuset
[ ... 阅读全帖 |
|
c****p 发帖数: 6474 | 20
is
static
1. 文件内可见?
2. 在全局变量区分配空间?
3. 文件内可见?
them?
理论上函数传参都是对实参的数据拷贝(而不是实参本身)进行操作。因而对函数参数
的任何修改在函数返回后都不会影响实参的值。传值不说;传址实际是传递某变量所在
的内存地址,通过修改该地址指向的内存空间就可以实质上修改该变量的值。一般情况
下,需要在函数中修改变量值的行为都会使用传址。
const,不可修改,一般放在只读数据区(.rodata),尝试对其修改可能会引发段错(好
像编译器实现决定的);volatile,访问被其限定的变量时必须从内存中获取,实质上
使该变量成为non-cachable,常见于被I/O访问的内存空间。
大多数十进制小数转化成二进制存储时会有截断误差,表面上相等的两个浮点数实际并
不相等,一般用误差小于某阈值来判定相等。
not at all
stack:FILO,可重入式函数必须的结构;heap,memory pool,由OS管理,用户通过
malloc/free和new/delete实现动态内存的申请和释放。
pree
这个不懂,猜下:task不可打断当前in... 阅读全帖 |
|
c****p 发帖数: 6474 | 21
is
static
1. 文件内可见?
2. 在全局变量区分配空间?
3. 文件内可见?
them?
理论上函数传参都是对实参的数据拷贝(而不是实参本身)进行操作。因而对函数参数
的任何修改在函数返回后都不会影响实参的值。传值不说;传址实际是传递某变量所在
的内存地址,通过修改该地址指向的内存空间就可以实质上修改该变量的值。一般情况
下,需要在函数中修改变量值的行为都会使用传址。
const,不可修改,一般放在只读数据区(.rodata),尝试对其修改可能会引发段错(好
像编译器实现决定的);volatile,访问被其限定的变量时必须从内存中获取,实质上
使该变量成为non-cachable,常见于被I/O访问的内存空间。
大多数十进制小数转化成二进制存储时会有截断误差,表面上相等的两个浮点数实际并
不相等,一般用误差小于某阈值来判定相等。
not at all
stack:FILO,可重入式函数必须的结构;heap,memory pool,由OS管理,用户通过
malloc/free和new/delete实现动态内存的申请和释放。
pree
这个不懂,猜下:task不可打断当前in... 阅读全帖 |
|