0

我写了以下程序:

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

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

    a.out:文件格式elf32-i386

    .interp 部分的内容:
     8048114 2f6c6962 2f6c642d 6c696e75 782e736f /lib/ld-linux.so
     8048124 2e3200 .2。             
    .note.ABI-tag 部分的内容:
     8048128 04000000 10000000 01000000 474e5500 ....GNU。
     8048138 00000000 02000000 06000000 09000000 ......
    .gnu.hash 部分的内容:
     8048148 02000000 04000000 01000000 05000000 ......
     8048158 00200020 00000000 04000000 ad4be3c0。. ..........K..
    .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 ......
    .dynstr 部分的内容:
     80481b8 005f5f67 6d6f6e5f 73746172 745f5f00 .__gmon_start__。
     80481c8 6c696263 2e736f2e 360​​05f49 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。    
    .gnu.version 部分的内容:
     8048204 00000000 02000200 0100 ......      
    .gnu.version_r 部分的内容:
     8048210 01000100 10000000 10000000 00000000 ......
     8048220 1069690d 00000200 42000000 00000000 .ii.....B.......
    .rel.dyn 部分的内容:
     8048230 7c950408 06010000 |.......        
    .rel.plt 部分的内容:
     8048238 8c950408 07010000 90950408 07020000 ......
     8048248 94950408 07030000 ....        
    .init 部分的内容:
     8048250 5589e583 ec08e879 000000e8 00010000 U......y.......
     8048260 e8db0100 00c9c3 .......         
    .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.........
    .text 部分的内容:
     80482b0 31ed5e89 e183e4f0 50545268 c0830408 1.^.....PTRh....
     80482c0 68d08304 08515668 84830408 e8b7ffff h....QVh........
     80482d0 fff49090 5589e553 83ec04e8 00000000 ....美国........
     80482e0 5b81c3a0 1200008b 93fcffff ff85d274 [........吨
     80482f0 05e882ff ffff585b c9c39090 90909090 ......X[........
     8048300 5589e553 83ec0480 3da09504 0800753f 美国....=.....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$.....qU
     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 美国............
     8048450 0883f8ff 740c83eb 04ffd08b 0383f8ff ..........
     8048460 75f483c4 045b5dc3 你....[]。        
    .fini 部分的内容:
     8048468 5589e553 83ec04e8 00000000 5b81c30c 美国........ [...
     8048478 110000e8 80feffff 595bc9c3 ........Y[..    
    .rodata 部分的内容:
     8048484 03000000 01000200 00000000 41626364 ....Abcd
     8048494 65666700 25640a00 efg.%d..        
    .eh_frame 部分的内容:
     804849c 00000000 ....            
    .ctors 部分的内容:
     80494a0 ffffffff 00000000 ........        
    .dtors 部分的内容:
     80494a8 ffffffff 00000000 ........        
    .jcr 部分的内容:
     80494b0 00000000 ....            
    .dynamic 部分的内容:
     80494b4 01000000 10000000 0c000000 50820408 ....P...
     80494c4 0d000000 68840408 f5feff6f 48810408 ....h......oH...
     80494d4 05000000 b8810408 06000000 68810408 ......
     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 ........        
    .got 部分的内容:
     804957c 00000000 ....            
    .got.plt 部分的内容:
     8049580 b4940408 00000000 00000000 7e820408 ..........
     8049590 8e820408 9e820408 ......        
    .data 部分的内容:
     8049598 00000000 ....            
    .comment 部分的内容:
     0000 00474343 3a202847 4e552920 342e312e .GCC:(GNU)4.1。
     0010 32203230 30383037 30342028 52656420 2 20080704(红
     0020 48617420 342e312e 322d3436 29000047 帽子 4.1.2-46)..G
     0030 43433a20 28474e55 2920342e 312e3220 CC:(GNU)4.1.2
     0040 32303038 30373034 20285265 64204861 20080704(红哈
     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(红帽
     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(红帽 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(红帽 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(红帽 4.1.2-
     0110 34362900 46)。

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

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

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

干杯,VSN

PS GCC 版本:4.1.2 20080704

4

4 回答 4

4

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

于 2012-10-15T14:02:58.253 回答
4

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

于 2012-10-15T14:03:05.027 回答
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 应该警告您。

于 2012-10-15T15:19:03.710 回答
2

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

于 2012-10-15T14:34:49.630 回答