sizeof的字符串常量存储位置

时间:2012-10-15 13:59:28

标签: c linux

我写了以下程序:

#include <stdio.h>
int main()
{
   char *a = "Abcdefg";
   printf("%d\n",sizeof("Z"));
}

二进制文件的objdump具有以下结果:

    a.out:     file format elf32-i386

    Contents of section .interp:
     8048114 2f6c6962 2f6c642d 6c696e75 782e736f  /lib/ld-linux.so
     8048124 2e3200                               .2.             
    Contents of section .note.ABI-tag:
     8048128 04000000 10000000 01000000 474e5500  ............GNU.
     8048138 00000000 02000000 06000000 09000000  ................
    Contents of section .gnu.hash:
     8048148 02000000 04000000 01000000 05000000  ................
     8048158 00200020 00000000 04000000 ad4be3c0  . . .........K..
    Contents of section .dynsym:
     8048168 00000000 00000000 00000000 00000000  ................
     8048178 01000000 00000000 00000000 20000000  ............ ...
     8048188 30000000 00000000 9f010000 12000000  0...............
     8048198 29000000 00000000 39000000 12000000  ).......9.......
     80481a8 1a000000 88840408 04000000 11000e00  ................
    Contents of section .dynstr:
     80481b8 005f5f67 6d6f6e5f 73746172 745f5f00  .__gmon_start__.
     80481c8 6c696263 2e736f2e 36005f49 4f5f7374  libc.so.6._IO_st
     80481d8 64696e5f 75736564 00707269 6e746600  din_used.printf.
     80481e8 5f5f6c69 62635f73 74617274 5f6d6169  __libc_start_mai
     80481f8 6e00474c 4942435f 322e3000           n.GLIBC_2.0.    
    Contents of section .gnu.version:
     8048204 00000000 02000200 0100               ..........      
    Contents of section .gnu.version_r:
     8048210 01000100 10000000 10000000 00000000  ................
     8048220 1069690d 00000200 42000000 00000000  .ii.....B.......
    Contents of section .rel.dyn:
     8048230 7c950408 06010000                    |.......        
    Contents of section .rel.plt:
     8048238 8c950408 07010000 90950408 07020000  ................
     8048248 94950408 07030000                    ........        
    Contents of section .init:
     8048250 5589e583 ec08e879 000000e8 00010000  U......y........
     8048260 e8db0100 00c9c3                      .......         
    Contents of section .plt:
     8048268 ff358495 0408ff25 88950408 00000000  .5.....%........
     8048278 ff258c95 04086800 000000e9 e0ffffff  .%....h.........
     8048288 ff259095 04086808 000000e9 d0ffffff  .%....h.........
     8048298 ff259495 04086810 000000e9 c0ffffff  .%....h.........
    Contents of section .text:
     80482b0 31ed5e89 e183e4f0 50545268 c0830408  1.^.....PTRh....
     80482c0 68d08304 08515668 84830408 e8b7ffff  h....QVh........
     80482d0 fff49090 5589e553 83ec04e8 00000000  ....U..S........
     80482e0 5b81c3a0 1200008b 93fcffff ff85d274  [..............t
     80482f0 05e882ff ffff585b c9c39090 90909090  ......X[........
     8048300 5589e553 83ec0480 3da09504 0800753f  U..S....=.....u?
     8048310 b8ac9404 082da894 0408c1f8 028d58ff  .....-........X.
     8048320 a19c9504 0839c376 1f8db426 00000000  .....9.v...&....
     8048330 83c001a3 9c950408 ff1485a8 940408a1  ................
     8048340 9c950408 39c377e8 c605a095 04080183  ....9.w.........
     8048350 c4045b5d c38d7426 008dbc27 00000000  ..[]..t&...'....
     8048360 5589e583 ec08a1b0 94040885 c07412b8  U............t..
     8048370 00000000 85c07409 c70424b0 940408ff  ......t...$.....
     8048380 d0c9c390 8d4c2404 83e4f0ff 71fc5589  .....L$.....q.U.
     8048390 e55183ec 24c745f8 90840408 c7442404  .Q..$.E......D$.
     80483a0 02000000 c7042498 840408e8 e8feffff  ......$.........
     80483b0 83c42459 5d8d61fc c3909090 90909090  ..$Y].a.........
     80483c0 5589e55d c38d7426 008dbc27 00000000  U..]..t&...'....
     80483d0 5589e557 5653e85e 00000081 c3a51100  U..WVS.^........
     80483e0 0083ec1c e867feff ff8d8320 ffffff89  .....g..... ....
     80483f0 45f08d83 20ffffff 2945f0c1 7df0028b  E... ...)E..}...
     8048400 55f085d2 742b31ff 89c68db6 00000000  U...t+1.........
     8048410 8b451083 c7018944 24088b45 0c894424  .E.....D$..E..D$
     8048420 048b4508 890424ff 1683c604 397df075  ..E...$.....9}.u
     8048430 df83c41c 5b5e5f5d c38b1c24 c3909090  ....[^_]...$....
     8048440 5589e553 bba09404 0883ec04 a1a09404  U..S............
     8048450 0883f8ff 740c83eb 04ffd08b 0383f8ff  ....t...........
     8048460 75f483c4 045b5dc3                    u....[].        
    Contents of section .fini:
     8048468 5589e553 83ec04e8 00000000 5b81c30c  U..S........[...
     8048478 110000e8 80feffff 595bc9c3           ........Y[..    
    Contents of section .rodata:
     8048484 03000000 01000200 00000000 41626364  ............Abcd
     8048494 65666700 25640a00                    efg.%d..        
    Contents of section .eh_frame:
     804849c 00000000                             ....            
    Contents of section .ctors:
     80494a0 ffffffff 00000000                    ........        
    Contents of section .dtors:
     80494a8 ffffffff 00000000                    ........        
    Contents of section .jcr:
     80494b0 00000000                             ....            
    Contents of section .dynamic:
     80494b4 01000000 10000000 0c000000 50820408  ............P...
     80494c4 0d000000 68840408 f5feff6f 48810408  ....h......oH...
     80494d4 05000000 b8810408 06000000 68810408  ............h...
     80494e4 0a000000 4c000000 0b000000 10000000  ....L...........
     80494f4 15000000 00000000 03000000 80950408  ................
     8049504 02000000 18000000 14000000 11000000  ................
     8049514 17000000 38820408 11000000 30820408  ....8.......0...
     8049524 12000000 08000000 13000000 08000000  ................
     8049534 feffff6f 10820408 ffffff6f 01000000  ...o.......o....
     8049544 f0ffff6f 04820408 00000000 00000000  ...o............
     8049554 00000000 00000000 00000000 00000000  ................
     8049564 00000000 00000000 00000000 00000000  ................
     8049574 00000000 00000000                    ........        
    Contents of section .got:
     804957c 00000000                             ....            
    Contents of section .got.plt:
     8049580 b4940408 00000000 00000000 7e820408  ............~...
     8049590 8e820408 9e820408                    ........        
    Contents of section .data:
     8049598 00000000                             ....            
    Contents of section .comment:
     0000 00474343 3a202847 4e552920 342e312e  .GCC: (GNU) 4.1.
     0010 32203230 30383037 30342028 52656420  2 20080704 (Red 
     0020 48617420 342e312e 322d3436 29000047  Hat 4.1.2-46)..G
     0030 43433a20 28474e55 2920342e 312e3220  CC: (GNU) 4.1.2 
     0040 32303038 30373034 20285265 64204861  20080704 (Red Ha
     0050 7420342e 312e322d 34362900 00474343  t 4.1.2-46)..GCC
     0060 3a202847 4e552920 342e312e 32203230  : (GNU) 4.1.2 20
     0070 30383037 30342028 52656420 48617420  080704 (Red Hat 
     0080 342e312e 322d3438 29000047 43433a20  4.1.2-48)..GCC: 
     0090 28474e55 2920342e 312e3220 32303038  (GNU) 4.1.2 2008
     00a0 30373034 20285265 64204861 7420342e  0704 (Red Hat 4.
     00b0 312e322d 34382900 00474343 3a202847  1.2-48)..GCC: (G
     00c0 4e552920 342e312e 32203230 30383037  NU) 4.1.2 200807
     00d0 30342028 52656420 48617420 342e312e  04 (Red Hat 4.1.
     00e0 322d3438 29000047 43433a20 28474e55  2-48)..GCC: (GNU
     00f0 2920342e 312e3220 32303038 30373034  ) 4.1.2 20080704
     0100 20285265 64204861 7420342e 312e322d   (Red Hat 4.1.2-
     0110 34362900                             46).

“Abcdefg”和“%d”作为字符串常量存储在程序的只读部分。

我的问题是“Z”存储在哪里?它不应该出现在只读部分吗?我读到某处,在运行时内存分配给“Z”,并在其上应用了sizeof()。

我对这个解释持怀疑态度。即使它是真的,可执行文件的指示是只分配2个字节并且应该在其中存储“Z”?

干杯, VSN

P.S。 GCC版本:4.1.2 20080704

4 个答案:

答案 0 :(得分:4)

编译器很容易计算sizeof(“Z”)的结果,因此它将计算出的值放在编译时,而不是将“Z”保留在某处然后再进行。希望它能解释。

答案 1 :(得分:4)

考虑到sizeof(“Z”)是一个常量表达式,我可以想象编译器用结果整数值替换它。

答案 2 :(得分:3)

直接在汇编程序而不是objdump中查看内容更容易:

 .LC0:
    .string "%zu\n"
    .section    .text.startup,"ax",@progbits
    .p2align 4,,15
    .globl  main
    .type   main, @function
main:
.LFB22:
    .cfi_startproc
    movl    $2, %edx
    movl    $.LC0, %esi
    movl    $1, %edi
    xorl    %eax, %eax
    jmp __printf_chk
    .cfi_endproc

这是由gcc与-O3 -S生成的。您可以清楚地看到2被直接移动到一个寄存器中,然后打印功能就会生效。

顺便说一下,你的打印格式错了,gcc应该警告过你。

答案 3 :(得分:2)

sizeof("Z")在编译时优化为2。这可以存储在可执行文件的.text部分中用偏移量80483a0标记的位置,该位置显示(具有错误的字节顺序)为02000000.这之前是c7442404。字节c7 44 24 04 02 00 00 00形成指令movl 0x4(%esp), $0x00000002。这会将2移动到堆栈上,这可能是准备将其作为参数传递给printf