全局变量

实验品

小白鼠(global.c):

#include <stdio.h>
int i = 1;
int main()
{
    ++i;

    printf("%d\n",i);
    return 0;
}

i 的定义被放在了函数体的外边,i 就成为了全局变量,程序运行的结果我不关心,我关心的是 i 最后变成了什么。

反汇编

这次悟空的火眼金睛也不给力了(后面我们会看到),我们得反汇编可执行文件才能看到最终结果:

[lqy@localhost temp]$ gcc -o global global.c
[lqy@localhost temp]$ objdump -s -d global > global.txt
[lqy@localhost temp]$ 
  • gcc -o global global.c 是编译 global.c 生成可执行文件 global
  • objdump -s -d global > global.txt 是反汇编 global
    • -s 参数可以将所有段的内容以十六进制的方式打印出来
    • -d 参数可以将所有包含指令的段反汇编
    • global.txt 是将标准输出输出到 global.txt 文件(专业点的话,叫"输出重定向")

objdump 是 linux 下一款反汇编工具,能够反汇编目标文件、可执行文件。

这样操作后,global 文件的反汇编结果输出到了 global.txt 文件中,打开 global.txt(文件比较长,我的有 357 行),定位到 main 函数:

 80483c4 <main>:

 80483c4:   55                      push   %ebp
 80483c5:   89 e5                   mov    %esp,%ebp
 80483c7:   83 e4 f0                and    $0xfffffff0,%esp
 80483ca:   83 ec 10                sub    $0x10,%esp
 80483cd:   a1 64 96 04 08          mov    0x8049664,%eax
 80483d2:   83 c0 01                add    $0x1,%eax
 80483d5:   a3 64 96 04 08          mov    %eax,0x8049664
 80483da:   8b 15 64 96 04 08       mov    0x8049664,%edx
 80483e0:   b8 c4 84 04 08          mov    $0x80484c4,%eax
 80483e5:   89 54 24 04             mov    %edx,0x4(%esp)
 80483e9:   89 04 24                mov    %eax,(%esp)
 80483ec:   e8 03 ff ff ff          call   80482f4 printf@plt
 80483f1:   b8 00 00 00 00          mov    $0x0,%eax
 80483f6:   c9                      leave
 80483f7:   c3                      ret

粗体部分标出了 ++i 的反汇编结果:

全局变量 i 最后变成了绝对地址为 0x8049664 的内存块(大小为4字节)。注意这里的 0x8049664 不是指立即数 0x8049664,如果要表示值为 0x8049664 的立即数,应该写为 $0x8049664。

悟空的弱点

通过火眼金睛:

gcc -S -o global.s global.c

我们看到 ++i 的汇编形式是:

movl    i, %eax
addl    $1, %eax
movl    %eax, i

悟空,你太让我们失望了!

目标文件中的全局变量

目标文件也可以用 objdump 来反汇编:

[lqy@localhost temp]$ gcc -c -o global.o global.c
[lqy@localhost temp]$ objdump -s -d global.o > global.txt 
[lqy@localhost temp]$ 

global.o 反汇编出来的 global.txt 就没那么长了,只有 35 行,其中 ++i 部分的结果是:

   9:   a1 00 00 00 00          mov    0x0,%eax
   e:   83 c0 01                add    $0x1,%eax
  11:   a3 00 00 00 00          mov    %eax,0x0

怎么会这样?怎么不是 0x8049664 呢?这就是目标文件 和 可执行文件的区别了:

全局变量在目标文件中只有一个冒牌地址,在链接后(各目标文件协商(为自己的全局变量争一块地盘)完毕)才填入最终的绝对地址。

目标文件和可执行文件

目标文件是编译后的产物,已经完成了 C语言 到 机器码 的转变,但是部分机器码的操作数还需要在链接过程中修正。可执行文件是由多个目标文件和 C 运行库链接而成的,C 运行库提供了诸如 printf 等函数的实现。

linux 下目标文件(默认扩展名是.o)和可执行文件都是ELF 格式(文件内容按照一定格式进行组织)的二进制文件;类似的,Windows 下 VISUAL C++ 编译出来的目标文件(扩展名是.obj)采用 COFF 格式,而可执行文件(扩展名是.exe)采用 PE 格式,ELF 和 PE 都是从 COFF 发展而来的。

因为 linux 下目标文件和可执行文件的内容格式是一样的,所以 objdump 既可以反汇编可执行文件也可以反汇编目标文件。

小结

全局变量也变成无名无姓的内存地址了,而且还是常量!

这次又介绍了一个工具:objdump。所有后面要用到的工具和使用方法都介绍完了:gcc、objdump,……嗯……(好像还不够)……至少主要的都介绍完了O(∩_∩)O~……

出差必备

买火车票、高铁票、机票,订酒店都打9折的出行工具TRIP,点击注册

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,402评论 6 499
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,377评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,483评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,165评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,176评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,146评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,032评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,896评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,311评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,536评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,696评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,413评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,008评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,815评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,698评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,592评论 2 353