static 变量存放在.data还是.bss

2024-03-24 02:08
文章标签 变量 static data 存放 bss

本文主要是介绍static 变量存放在.data还是.bss,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 来自:http://hi.baidu.com/zkheartboy/blog/item/12cc5c904f42e68ba877a472.html

 

#include <stdio.h>


void add()
{
   static   int   var;
   var++;
   printf("var=%d\n",var);

}


int main()
{
    add();
    return 0;
}

/*
//汇编之后
    .file    "seeStatic.c"
    .local    var.0
    .comm    var.0,4,4
    .section    .rodata
.LC0:
    .string    "var=%d\n"
    .text
.globl add
    .type    add,@function
add:
    pushl    %ebp
    movl    %esp, %ebp
    subl    $8, %esp
    incl    var.0
    subl    $8, %esp
    pushl    var.0
    pushl    $.LC0
    call    printf
    addl    $16, %esp
    leave
    ret
.Lfe1:
    .size    add,.Lfe1-add
.globl main
    .type    main,@function
main:
    pushl    %ebp
    movl    %esp, %ebp
    subl    $8, %esp
    andl    $-16, %esp
    movl    $0, %eax
    subl    %eax, %esp
    call    add
    movl    $0, %eax
    leave
    ret
.Lfe2:
    .size    main,.Lfe2-main
    .ident    "GCC: (GNU) 3.2.2 20030222 (Red Hat Linux 3.2.2-5)"
*/
//---------------------------------------------------------------------------------------------------------------------------------------------
/*网上的 资料

ChinaUnix.net

gerysand    2005-4-15 04:24
关于堆,栈,动态分配,静态分配的一个小实验

其中有些不明白,大家帮着解释一下

下边是c源码
char *str_g="abcd";
int a=0;
int b;
int main()
{
        static int c;
        char *str_l=(char *)malloc(16);
        c=b=a;
        printf("address of str_l=%x\n",&str_l);
        printf("address of malloc string=%x\n",str_l);
}

gerysand    2005-4-15 04:51
关于堆,栈,动态分配,静态分配的一个小实验

编译后的汇编    
         .file   "test.c"        //指出这个文件由test.c编译而来
        .section        .rodata //只读段包含字符"abcd"
.LC0:
        .string "abcd"
                                                                                                                                              
.globl str_g            //全局变量str_g
        .data           //表明在数据段中
        .align 4
        .type   str_g, @object
        .size   str_g, 4
str_g:
        .long   .LC0    //初始化为.LC0的地址,即"abcd"字符串的地址
.globl a                //全局变量a
        .bss            //为什么它放在bss数据段中?(还是我理解的有问题)
        .align 4
        .type   a, @object
        .size   a, 4
a:
        .zero   4       //长度为4个字节,初始化为0(是这个意思吗?)
        .local c.0     //用local标记的static变量c,这个是static定义所特有的,表示虽然放在全局区域但是不可导出
        .comm   c.0,4,4 //用comm标记应该是表示未初始化,但是后边0,4,4表示什么无从考证
        .section        .rodata //又是两个字符串常量,用rodata标记为只读数据段
.LC1:
        .string "address of str_l=%x\n" //.LC1长度为21byte
.LC2:
        .string "address of malloc string=%x\n"
        .text
.globl main             //全局函数入口
        .type   main, @function
main:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $8, %esp
        andl    $-16, %esp
        movl    $0, %eax
        subl    %eax, %esp
        subl    $12, %esp
        pushl   $16
        call    malloc
        addl    $16, %esp
        movl    %eax, -4(%ebp)
        movl    a, %eax
        movl    %eax, b
        movl    %eax, c.0
        subl    $8, %esp
        leal    -4(%ebp), %eax
        pushl   %eax
        pushl   $.LC1
       call    printf
        addl    $16, %esp
        subl    $8, %esp
        pushl   -4(%ebp)
        pushl   $.LC2
        call    printf
        addl    $16, %esp
        leave
        ret
        .size   main, .-main    //计算main的大小
        .comm   b,4,4           //为什么b放在这里定义???难道它是放在text段里吗???comm应该是指未初始化
        .section        .note.GNU-stack,"",@progbits
        .ident "GCC: (GNU) 3.3.2 20031022 (Red Hat Linux 3.3.2-1)"


用bojdump -d 查看的.o文件

test.o:     文件格式 elf32-i386
                                                                                                                                              
反汇编 .text 节:
                                                                                                                                              
00000000 <main>;:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   83 ec 08                sub    $0x8,%esp
   6:   83 e4 f0                and    $0xfffffff0,%esp
   9:   b8 00 00 00 00          mov    $0x0,%eax
   e:   29 c4                   sub    %eax,%esp
10:   83 ec 0c                sub    $0xc,%esp
13:   6a 10                   push   $0x10
15:   e8 fc ff ff ff          call   16 <main+0x16>;
1a:   83 c4 10                add    $0x10,%esp
1d:   89 45 fc                mov    %eax,0xfffffffc(%ebp)
20:   a1 00 00 00 00          mov    0x0,%eax
25:   a3 00 00 00 00          mov    %eax,0x0
2a:   a3 04 00 00 00          mov    %eax,0x4
2f:   83 ec 08                sub    $0x8,%esp
32:   8d 45 fc                lea    0xfffffffc(%ebp),%eax
35:   50                      push   %eax
36:   68 05 00 00 00          push   $0x5 //对应.LC1
3b:   e8 fc ff ff ff          call   3c <main+0x3c>;
//为什么一样的二进制代码和下一个printf调用翻译出来的汇编不一样???见4e地址处
//用objdump -r 查看了一下,发现printf是需要重定位的,但是应该重定向到同一位置
//为什么会出现地址不一样的情况,请高手解答
40:   83 c4 10                add    $0x10,%esp
43:   83 ec 08                sub    $0x8,%esp
46:   ff 75 fc                pushl 0xfffffffc(%ebp)
49:   68 1a 00 00 00          push   $0x1a //对应.LC2,和LC1相差21byte
4e:   e8 fc ff ff ff          call   4f <main+0x4f>;
53:   83 c4 10                add    $0x10,%esp
56:   c9                      leave
57:   c3                      ret


*/

从中学习到了 static 声明的变量,不管它是全局变量也好,还是在函数之中的也好,只要是没有赋初值
都存放在.bss段,如果赋了初值,则把它放在.data段。

反汇编的方法, 首先
gcc -o test.o -c test.c
得到test.o文件,然后,objdump -d test.o 即可。

 

这篇关于static 变量存放在.data还是.bss的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/840188

相关文章

变量与命名

引言         在前两个课时中,我们已经了解了 Python 程序的基本结构,学习了如何正确地使用缩进来组织代码,并且知道了注释的重要性。现在我们将进一步深入到 Python 编程的核心——变量与命名。变量是我们存储数据的主要方式,而合理的命名则有助于提高代码的可读性和可维护性。 变量的概念与使用         在 Python 中,变量是一种用来存储数据值的标识符。创建变量很简单,

native和static native区别

本文基于Hello JNI  如有疑惑,请看之前几篇文章。 native 与 static native java中 public native String helloJni();public native static String helloJniStatic();1212 JNI中 JNIEXPORT jstring JNICALL Java_com_test_g

论文翻译:arxiv-2024 Benchmark Data Contamination of Large Language Models: A Survey

Benchmark Data Contamination of Large Language Models: A Survey https://arxiv.org/abs/2406.04244 大规模语言模型的基准数据污染:一项综述 文章目录 大规模语言模型的基准数据污染:一项综述摘要1 引言 摘要 大规模语言模型(LLMs),如GPT-4、Claude-3和Gemini的快

CentOS下mysql数据库data目录迁移

https://my.oschina.net/u/873762/blog/180388        公司新上线一个资讯网站,独立主机,raid5,lamp架构。由于资讯网是面向小行业,初步估计一两年内访问量压力不大,故,在做服务器系统搭建的时候,只是简单分出一个独立的data区作为数据库和网站程序的专区,其他按照linux的默认分区。apache,mysql,php均使用yum安装(也尝试

使用Spring Boot集成Spring Data JPA和单例模式构建库存管理系统

引言 在企业级应用开发中,数据库操作是非常重要的一环。Spring Data JPA提供了一种简化的方式来进行数据库交互,它使得开发者无需编写复杂的JPA代码就可以完成常见的CRUD操作。此外,设计模式如单例模式可以帮助我们更好地管理和控制对象的创建过程,从而提高系统的性能和可维护性。本文将展示如何结合Spring Boot、Spring Data JPA以及单例模式来构建一个基本的库存管理系统

JS_变量

二、JS的变量 JS中的变量具有如下特征 1 弱类型变量,可以统一声明成var 2 var声明的变量可以再次声明 3 变量可以使用不同的数据类型多次赋值 4 JS的语句可以以; 结尾,也可以不用;结尾 5 变量标识符严格区分大小写 6 标识符的命名规则参照JAVA 7 如果使用了 一个没有声明的变量,那么运行时会报uncaught ReferenceError: *** is not de

15 组件的切换和对组件的data的使用

划重点 a 标签的使用事件修饰符组件的定义组件的切换:登录 / 注册 泡椒鱼头 :微辣 <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-

12C 新特性,MOVE DATAFILE 在线移动 包括system, 附带改名 NID ,cdb_data_files视图坏了

ALTER DATABASE MOVE DATAFILE  可以改名 可以move file,全部一个命令。 resue 可以重用,keep好像不生效!!! system照移动不误-------- SQL> select file_name, status, online_status from dba_data_files where tablespace_name='SYSTEM'

使用条件变量实现线程同步:C++实战指南

使用条件变量实现线程同步:C++实战指南 在多线程编程中,线程同步是确保程序正确性和稳定性的关键。条件变量(condition variable)是一种强大的同步原语,用于在线程之间进行协调,避免数据竞争和死锁。本文将详细介绍如何在C++中使用条件变量实现线程同步,并提供完整的代码示例和详细的解释。 什么是条件变量? 条件变量是一种同步机制,允许线程在某个条件满足之前进入等待状态,并在条件满

axure之变量

一、设置我们的第一个变量 1、点击axure上方设置一个全局变量a = 3 2、加入按钮、文本框元件点击按钮文档框展示变量值。 交互选择【单击时】【设置文本】再点击函数。 点击插入变量和函数直接选择刚刚定义的全局变量,也可以直接手动写入函数(注意写入格式。) 这样点击按钮时就直接展示刚刚设置的全局变量3了。 2、更改变量值 在新建交互里点击设置变量值。 将a变量设置成等于10. 将新