用户名: 密码: 忘记密码? 注册

指针与数组

作者:  时间: 2010-09-26
1. 今天好好的看了一下这个程序,分析起来还挺有意思的。

void foo ()
{
    char str1[] = "123456789";
    char *str2 = "456";
    str1[0] = 'X';
    str2[0] = 'Y';
}
int main ( void )
{
    foo();
    return 0;
}

下面这条语句很容易明白 char *str2 = "456"; str2[0] = 'Y'; 456放在了只读数段,str2要修改只读区的数据,所以会出错。但是不太明白为什么str1的内容可以改变?反汇编后的代码:

    .file    "test.c"
    .section    .rodata
.LC1:
    .string    "456"
.LC0:
    .string    "123456789"
    .text
.globl foo
    .type    foo, @function
foo:
    pushl    %ebp
    movl    %esp, %ebp
    subl    $16, %esp
    movl    .LC0, %eax      ;将1234复制到栈中
    movl    %eax, -14(%ebp)
    movl    .LC0+4, %eax    ;将5678复制到栈中
    movl    %eax, -10(%ebp)
    movzwl    .LC0+8, %eax   ;将9\0复制到栈中
    movw    %ax, -6(%ebp)
    movl    $.LC1, -4(%ebp)
    movb    $88, -14(%ebp)
    movl    -4(%ebp), %eax
    movb    $89, (%eax)
    leave
    ret
    .size    foo, .-foo
.globl main
    .type    main, @function
main:
    leal    4(%esp), %ecx
    andl    $-16, %esp
    pushl    -4(%ecx)
    pushl    %ebp
    movl    %esp, %ebp
    pushl    %ecx
    call    foo
    movl    $0, %eax
    popl    %ecx
    popl    %ebp
    leal    -4(%ecx), %esp
    ret
    .size    main, .-main
    .ident    "GCC: (GNU) 4.1.2 20070626 (Red Hat 4.1.2-14)"
    .section    .note.GNU-stack,"",@progbits

现在明白了,呵呵。原来 :123456789 456 都放在只读代码段中的,char str1[] = "123456789"; 中char str1[]  是放在栈中的,只不过是复制了"123456789" 这个数据。所以看起来好像是"123456789" 放在了栈中(或者说,好像是str1修改了只读代码段的内容)。