c - 我在哪里可以找到在我的 C 程序的 .data 部分中创建静态变量的程序集?

标签 c static gdb virtual execve

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

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

C程序是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 文件显示变量位于虚拟地址空间在进程创建时已经被放置在那里(这个进程是我感兴趣的)。

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

(如果你能告诉我是什么命令生成了这个输出,那就加分了。我无法使用 readelf 复制它。我从网站上获取了命令并保存了输出。我不记得是如何生成的)

[剪断]

    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(基本英特尔)语法知识,但即使凭直觉我也看不出这些指令如何构建数组。看起来他们只是将寄存器值加在一起。

底线:我想尽可能多地了解这个静态数组的生命周期,尤其是构建它的“缺失代码”在哪里以及我如何查看它?或者更好的是我如何调试(单步执行)加载程序进程?我曾尝试在 __start_libc 条目(或类似的东西)的 main 之前设置一个断点,但无法在该区域识别出任何有希望的东西。

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

最佳答案

staticVar 的初始值设定项存储在可执行文件的 .data 部分。使用 objdump(例如 How can I examine contents of a data section of an ELF file on Linux?)应该会为您的文件显示如下内容:

./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 给了我这个:

  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

这个静态数组的生命周期就是你的进程的生命周期,类似于全局变量。无论如何,没有构建它的代码。这只是内存中的一些数据。

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

关于c - 我在哪里可以找到在我的 C 程序的 .data 部分中创建静态变量的程序集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18582582/

相关文章:

java - 从静态方法实例化非静态内部类

c++ - 无法在 Qt Creator 中启动 gdb.exe

assembly - 为什么要将他已经拥有的相同值复制到 rax 中?

Java:调用静态方法但没有任何反应?

c - C 中的多个信号会导致段错误吗?

c++ - malloc 指针函数传递 fread

c - 结构和字符串

c - 违反C中的静态函数

c++ - 嵌入 GDB 断点

c++ - 非 volatile 变量