c-program和细分

时间:2010-10-04 04:17:15

标签: c

#include<stdio.h>
int main()
{
   char *p="mystring";
   return 0;
}

字符串文字“mystring”,将在哪里存储(在哪个段中)?  我假设“mystring”的地址存储在'p'中,'p'将存储在数据段中,“mystring”将存储在代码段中。如果我的假设是写,我可以说'p'是远指针吗?如果我错了,请纠正我。

2 个答案:

答案 0 :(得分:2)

C本身没有段(也不是远指针)的概念,这将是底层实现或体系结构(您尚未指定)的一个特性。分段架构和近/远/微小指针是8086天以来的古老东西 - 现在大多数代码(嵌入式东西除外)为您提供了一个平坦的内存模型,您无需担心这一点。

所有标准状态都是字符串的实际字符将是您不允许修改的字符。

它的价值(不多)。我的实现将字符串本身存储在标记为只读的内存中(这可能是也可能不是代码段,您可以轻松地将其他段标记为只读)和p(第一个字符的地址)在运行时放在堆栈上。

如果运行编译器以生成汇编程序输出:

gcc -S qq.c

你会看到类似的内容(在我的案例中为qq.s):

        .file   "qq.c"
        .def    ___main;        .scl    2;      .type   32;     .endef
        .section .rdata,"dr"
LC0:
        .ascii "mystring\0"
        .text
.globl _main
        .def    _main;  .scl    2;      .type   32;     .endef
_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
        movl    %eax, -8(%ebp)
        movl    -8(%ebp), %eax
        call    __alloca
        call    ___main
        movl    $LC0, -4(%ebp)
        movl    $0, %eax
        leave
        ret

您可以从中看到,它位于自己的rdata部分(只读数据),而不在text部分。

将它放入text的一个可能的缺点是DEP(数据执行保护)之类的东西会更难。

您希望代码和只读数据都是只读的,但您还希望代码可执行 - 您通常希望只读数据可执行。

答案 1 :(得分:1)

字符串可能会存储在文本段中,它将是只读的。

如果你愿意,你可以说'p是一个很远的指针',但这个词已经没有真正意义了。在昔日的日子里(强大的80286是CPU中的东西),那么'远指针'具有一定的意义 - 并且基本上意味着指针不适合单个16位地址寄存器。您需要一个地址段寄存器以及地址寄存器来处理令人难以置信的1 MB可寻址空间。目前,在大多数系统(除了(某些)嵌入式系统之外),这已不再具有相关性。