2010-10-04 4 views
0
#include<stdio.h> 
int main() 
{ 
    char *p="mystring"; 
    return 0; 
} 

Строка литерала «mystring», где будет храниться (в каком сегменте)? Я предполагаю, что адрес «mystring» хранится в «p», «p» будет в сегменте данных, а «mystring» будет храниться в сегменте кода. Если мое предположение написано, я могу сказать, что «р» - дальний указатель? Пожалуйста, поправьте меня, если я ошибаюсь.c-program и сегменты

ответ

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 (защита выполнения данных), будут намного сложнее.

Вы хотите, чтобы оба кода и данные только для чтения были доступны только для чтения, но вы также хотите, чтобы код исполнялся - вы не обычно хотят, чтобы данные только для чтения были исполняемыми.

+0

В среде unix, когда c-программа становится процессом (виртуальное адресное пространство разделено на сегменты), будет ли строковый литерал храниться в сегменте данных или сегменте кода ...? – Jagan

+1

@Jagan, я думаю, их обычно называют секциями, а не сегментами. Я склонен резервировать сегменты этого великого преступления против человечества, которое давно навязало нам Intel. В любом случае данные могут идти в любом месте (сам стандарт не предусматривает, где). Скорее всего, он будет помещен в постоянное запоминающее устройство, но это отнюдь не требуется. – paxdiablo

1

Строка, вероятно, будет сохранена в текстовом сегменте, где она будет доступна только для чтения.

Вы можете сказать: «p - дальний указатель», если вам это нравится, но этот термин больше не имеет никакого реального значения. В дни yore (когда могучий 80286 был в чем-то в CPU), тогда «дальний указатель» имел некоторое значение - и в основном означал указатель, который не входил в один 16-разрядный адресный регистр. Вам нужен регистр сегмента адресов, а также регистр адресов, чтобы справиться с невероятным 1 МБ адресного пространства. В наши дни в большинстве систем (кроме (некоторых) встроенных систем) это уже не актуально.

Смежные вопросы