在哪里可以找到在 C 程序的 .data 部分中创建静态变量的程序集? [英] Where do I find the assembly that creates a static variable in the .data section of my C program?

查看:34
本文介绍了在哪里可以找到在 C 程序的 .data 部分中创建静态变量的程序集?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

第一次海报.计算机科学二年级学生.

First time poster. 2nd year CS student.

我正在探索在 C 源代码->GCC 编译->Linux 执行环境的上下文中在虚拟地址空间的 .data 部分中创建静态变量.

I am exploring the creation of static variables in the .data section of the Virtual Address Space in the context of a C source->GCC compilation->Linux execution environment.

C 程序是 test.c

C program is test.c

int main()
{
   register int i = 0;
   register int sum = 0;
   static int staticVar[10] = {1,2,3,4,5,6,7,8,9,-1};
   Loop: 
        sum = sum + staticVar[i]; //optimized away
    i = i+1;
    if(i != 10)
    goto Loop; 
   return 0;
 }

要求 GDB 'disass/m' 表明没有用于创建 staticVar[] 的代码,因为检查 .s 文件显示该变量位于在创建进程时已将虚拟地址空间放置在那里(这个进程是我感兴趣的).

Asking GDB to 'disass /m' reveals that there is no code for the staticVar[] creation because inspecting the .s file reveals the variable resides in the read/write .data segment of the virtual address space having been placed there at the time of process creation(this process is what I'm interested in).

检查(我虽然是'readelf -A test.o')的输出,目标文件包含我假设是在数据段中创建数组的程序集.这是 ELF 输出.

Examining the output of (I though it was 'readelf -A test.o') the object file contains assembly for what I assume is the creation of the array in the data segment. Here is the ELF output.

(如果你能告诉我这个输出是由什么命令生成的,我会很高兴.我无法使用 readelf 复制它.我从网站上获取了该命令并保存了输出.我不记得是如何生成的)

(Bonus if you can tell me what command generates this output. I can not duplicate it using readelf. I picked up the command off a website and saved output. I cant remember how generated)

[剪辑]

    00000000 <staticVar.1359>:
   0:01 00                  add    %eax,(%eax)
   2:00 00                  add    %al,(%eax) 
   4:02 00                  add    (%eax),%al
   6:00 00                  add    %al,(%eax)
   8:03 00                  add    (%eax),%eax
   a:00 00                  add    %al,(%eax)
   c:04 00                  add    $0x0,%al
   e:00 00                  add    %al,(%eax)
  10:05 00 00 00 06         add    $0x6000000,%eax
  15:00 00                  add    %al,(%eax)
  17:00 07                  add    %al,(%edi)
  19:00 00                  add    %al,(%eax)
  1b:00 08                  add    %cl,(%eax)
  1d:00 00                  add    %al,(%eax)
  1f:00 09                  add    %cl,(%ecx)
  21:00 00                  add    %al,(%eax)
  23:00 ff                  add    %bh,%bh
  25:ff                     (bad)  
  26:ff                     (bad)  
  27:ff                     .byte 0xff

[剪辑]

假设(请更正):该程序集存在于可执行文件中,由 load_elf_binary() 或 execve() 启动的一系列函数的某些部分运行.我没有 at&t(基本英特尔)语法知识,但即使直观地我也看不到这些指令如何构建数组.看起来他们只是将寄存器值加在一起.

Assumptions(please correct): This assembly exists in the executable and is run by load_elf_binary(), or some part of the execve() initiated series of functions. I have no at&t (basic intel) syntax knowledge but even intuitively I dont see how these instructions can build an array. Looks like they are just adding register values together.

底线:我想尽可能多地了解这个静态数组的生命周期,尤其是构建它的缺失代码"在哪里以及如何查看它?或者更好的是如何调试(逐步执行)加载程序过程?我曾尝试在 __start_libc 条目(或类似条目)的 main 之前设置断点,但无法确定该区域有什么前景.

Bottom Line: I would like to know as much as possible about the life cycle of this static array especially where is the "missing code" that builds it and how can I look at it? Or better yet how can I debug (step through) the loader process? I have tried setting a breakpoint before main at the __start_libc entry (or something like that) but could not identify anything promising in this area.

附加信息的链接很棒!谢谢你的时间!

Links to additional info are great! Thanks for your time!

推荐答案

staticVar 的初始化程序存储在可执行文件的 .data 部分中.使用 objdump(例如 如何在 Linux 上检查 ELF 文件数据段的内容?)应该为您的文件显示类似的内容:

The initializers for staticVar is stored in the .data section of the executable. Using objdump (e.g. How can I examine contents of a data section of an ELF file on Linux?) should reveal something like this for your file:

./test:     file format elf64-x86-64

Contents of section .data:
 00d2c0 00000000 00000000 00000000 00000000  ................
 00d2d0 00000000 00000000 00000000 00000000  ................
 00d2e0 01000000 02000000 03000000 04000000  ................
 00d2f0 05000000 06000000 07000000 08000000  ................
 00d300 09000000 ffffffff 00000000 00000000  ................
 00d310 00000000 00000000 00000000 00000000  ................

可执行文件中的内容直接映射到进程的地址空间,因此不需要任何代码来创建数据.对 staticVar 进行操作的代码会直接使用内存指针来引用内容;例如对于您发布的循环, gcc -S 给了我这个:

That content from the executable is directly mapped into the address space of your process, so there is no need for any code to create the data. Codes that operate on staticVar will refer to the content directly using memory pointers; e.g. for the loop you posted, gcc -S gave me this:

  18                .L5:
  19 0013 90            nop
  20                .L2:
  21 0014 4863C3        movslq  %ebx, %rax
  22 0017 8B148500      movl    staticVar.1707(,%rax,4), %edx
  22      000000
  23 001e 8B45F4        movl    -12(%rbp), %eax
  24 0021 01D0          addl    %edx, %eax
  25 0023 8945F4        movl    %eax, -12(%rbp)
  26 0026 83C301        addl    $1, %ebx
  27 0029 83FB0A        cmpl    $10, %ebx
  28 002c 75E5          jne .L5

这个静态数组的生命周期就是你的进程的生命周期,类似于一个全局变量.在任何情况下,都没有构建它的代码.这只是内存中的一些数据.

Lifetime of this static array would be the lifetime of your process, similar to a global variable. In any case, there is no code that builds it. It's just some data in memory.

P/S:您可能需要像这样将 volatile 添加到 sum 中:volatile int sum = 0; 否则 gcc 可能会将其优化掉,因为 sum 的结果值从未使用过.

P/S: You may need to add volatile to sum like such: volatile int sum = 0; Otherwise gcc would probably optimize it away since the resulting value of sum is never used.

这篇关于在哪里可以找到在 C 程序的 .data 部分中创建静态变量的程序集?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆