当前位置:  开发笔记 > 运维 > 正文

为什么.rodata节中的静态字符串在GCC中有一个四点前缀?

如何解决《为什么.rodata节中的静态字符串在GCC中有一个四点前缀?》经验,为你挑选了1个好方法。

对于以下代码:

#include 

int main() {
    printf("Hello World");
    printf("Hello World1");
    return 0;
}

生成的用于调用printf的程序集如下(64位):

  400474:   be 24 06 40 00          mov    esi,0x400624
  400479:   bf 01 00 00 00          mov    edi,0x1
  40047e:   31 c0                   xor    eax,eax
  400480:   e8 db ff ff ff          call   400460 <__printf_chk@plt>
  400485:   be 30 06 40 00          mov    esi,0x400630
  40048a:   bf 01 00 00 00          mov    edi,0x1
  40048f:   31 c0                   xor    eax,eax
  400491:   e8 ca ff ff ff          call   400460 <__printf_chk@plt>

而.rodata部分如下:

Contents of section .rodata:
 400620 01000200 48656c6c 6f20576f 726c6400  ....Hello World.
 400630 48656c6c 6f20576f 726c6431 00        Hello World1.

基于汇编代码,对printf的第一次调用具有地址400624的参数,该参数与.rodata的开头有4个字节的偏移量.我知道它会跳过这4个点前缀的前4个字节.但我的问题是为什么GCC /链接器在.rodata中为字符串生成这个前缀?我在Ubuntu 14.04上使用4.8.4 GCC.编译cmd只是:gcc -Ofast my-source.c -o my-program.



1> Jester..:

对于初学者来说,那些不是四个点,点只是意味着不可打印的角色.您可以在十六进制转储中看到这些字节01 00 02 00.

最终程序包含链接器添加的其他目标文件,它们是C运行时库的一部分.这些数据由代码使用.

你可以看到地址是0x400620.然后,您可以尝试查找匹配的符号,例如,您可以将其加载到gdb并使用info symbol命令:

(gdb) info symbol 0x4005f8
_IO_stdin_used in section .rodata of /tmp/a.out

(注意我有一个不同的地址.)

更进一步,你可以在glibc中找到它的来源:

/* This records which stdio is linked against in the application. */
const int _IO_stdin_used = _G_IO_IO_FILE_VERSION;

#define _G_IO_IO_FILE_VERSION 0x20001

如果您考虑小端存储,则与您看到的值相对应.

推荐阅读
女女的家_747
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有