| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2807 人关注过本帖
标题:全局变量怎么不在数据段(.data)中呢?
只看楼主 加入收藏
风居住的街道
Rank: 1
等 级:新手上路
帖 子:374
专家分:0
注 册:2008-10-24
收藏
得分:0 
LS,我没有完全运行,只是通过反汇编找到的地址……
2008-11-01 02:50
vfdff
Rank: 6Rank: 6
等 级:侠之大者
威 望:8
帖 子:2172
专家分:425
注 册:2005-7-15
收藏
得分:0 
回复 11# 的帖子
那你怎么确定这个地址 0x00404010 就是分配给这个全局变量的呢 ?

~~~~~~~~~~~~~~~好好学习~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2008-11-01 13:01
风居住的街道
Rank: 1
等 级:新手上路
帖 子:374
专家分:0
注 册:2008-10-24
收藏
得分:0 
LS:
那我有时间认真测试一下吧~~
2008-11-01 20:17
风居住的街道
Rank: 1
等 级:新手上路
帖 子:374
专家分:0
注 册:2008-10-24
收藏
得分:0 
首先贴出试验程序:
程序代码:
#include <stdio.h>
#include <stdlib.h>

int g = 10;

int main(void)
{
    int l = 20;

    printf("%d, %p\n", g, &g);
    printf("%d, %p\n", l, &l);

    return 0;
}


猜测,对于一个特定的程序(编译过了的程序),多次运行下其地址应该是不变的,因为分配的栈空间和静态空间都是相对于基地址的常数,而每次程序被载入的地址也是不变的,在我的电脑上,以上程序多次编译运行结果如下:
程序代码:
10, 00402000
20, 0022FF44
Hit any key to close this window...


现在开始调试了。第一步通过gcc生成静态反编译代码,命令如下:
gcc -S -ott.asm tt.c -O2
使用O2一方面是为了代码最短化,另一方面是因为上面的程序就是用O2编译的,这样是为了保证编译的结果和程序一致,编译结果如下:
程序代码:
    .file    "tt.c"
.globl _g
    .data
    .align 4
_g:
    .long    10
    .def    ___main;    .scl    2;    .type    32;    .endef
    .section .rdata,"dr"
LC0:
    .ascii "%d, %p\12\0"
    .text
    .p2align 4,,15
.globl _main
    .def    _main;    .scl    2;    .type    32;    .endef
_main:
    pushl    %ebp
    movl    $16, %eax
    movl    %esp, %ebp
    subl    $24, %esp
    andl    $-16, %esp
    call    __alloca
    call    ___main
    movl    $20, -4(%ebp)
    movl    $_g, %eax
    movl    %eax, 8(%esp)
    movl    _g, %eax
    movl    $LC0, (%esp)
    movl    %eax, 4(%esp)
    call    _printf
    movl    $LC0, (%esp)
    leal    -4(%ebp), %eax
    movl    %eax, 8(%esp)
    movl    -4(%ebp), %eax
    movl    %eax, 4(%esp)
    call    _printf
    leave
    xorl    %eax, %eax
    ret
    .def    _printf;    .scl    2;    .type    32;    .endef


很明显,字符串在rdata段,g在data段,而代码在text段,没有问题。

我们接着调试exe程序,启动OllyDbg。根据经验,我先找到了printf的调用,这里就是main函数的地址:
图片附件: 游客没有浏览图片的权限,请 登录注册

这里比较乱,这是编译器进行了乱序优化,不妨碍我们观看,很明显找到了入栈的g的地址:402000(l的地址明显是通过ebp提供的,是动态的,这里就不分析了)
然后,我们可以看看这个地址在哪儿:
图片附件: 游客没有浏览图片的权限,请 登录注册

印证了我们的想法。

以上是GCC的测试,VC的测试,马上进行~~~
2008-11-01 20:46
风居住的街道
Rank: 1
等 级:新手上路
帖 子:374
专家分:0
注 册:2008-10-24
收藏
得分:0 
程序代码:
; Listing generated by Microsoft (R) Optimizing Compiler Version 14.00.50727.762 

    TITLE    C:\Users\StarWing\Desktop\dev\tt.c
    .686P
    .XMM
    include listing.inc
    .model    flat

INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES

PUBLIC    _g
_DATA    SEGMENT
_g    DD    0aH
$SG3495    DB    '%d, %p', 0aH, 00H
$SG3496    DB    '%d, %p', 0aH, 00H
_DATA    ENDS
PUBLIC    _main
EXTRN    _printf:PROC
; Function compile flags: /Odtp
; File c:\users\starwing\desktop\dev\tt.c
_TEXT    SEGMENT
_l$ = -4                        ; size = 4
_main    PROC

; 7    : {

    push    ebp
    mov    ebp, esp
    push    ecx

; 8    :     int l = 20;

    mov    DWORD PTR _l$[ebp], 20            ; 00000014H

; 9    : 
; 10   :     printf("%d, %p\n", g, &g);

    push    OFFSET _g
    mov    eax, DWORD PTR _g
    push    eax
    push    OFFSET $SG3495
    call    _printf
    add    esp, 12                    ; 0000000cH

; 11   :     printf("%d, %p\n", l, &l);

    lea    ecx, DWORD PTR _l$[ebp]
    push    ecx
    mov    edx, DWORD PTR _l$[ebp]
    push    edx
    push    OFFSET $SG3496
    call    _printf
    add    esp, 12                    ; 0000000cH

; 12   : 
; 13   :     return 0;

    xor    eax, eax

; 14   : }

    mov    esp, ebp
    pop    ebp
    ret    0
_main    ENDP
_TEXT    ENDS
END



这是VC的静态编译结果,显然g也在.data区。动态调试就不做了……
2008-11-01 21:21
快速回复:全局变量怎么不在数据段(.data)中呢?
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.020325 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved