工具:Microsoft visual studio(社区版免费)
c++代码段:
#include<iostream>
using namespace std;
int g;
int main()
{
g=24;
}
现在从更底层的角度来看:
1、打开VS,新建空的c++项目,输入代码
2、光标调整到赋值的那一行,F9设置断点,F5开始调试
3、鼠标右键选择反汇编
4、出现了下面这样的东西
g = 24;
002E16EE C7 05 38 81 2E 00 18 00 00 00 mov dword ptr [g (02E8138h)],18h
5、点击鼠标右键,把“显示代码字节”前面的对号去掉,变成了下面这个样子
g = 24;
002E16EE mov dword ptr [g (02E8138h)],18h
6、002E16EE C7 05 38 81 2E 00 18 00 00 00 mov dword ptr [g (02E8138h)],18h
可以分为三个部分
002E16EE:赋值语句的起始地址
C7 05 38 81 2E 00 18 00 00 00 :mov指令的机器码
mov dword ptr [g (02E8138h)],18h :mov指令的汇编表示,把18h赋给g,g的地址是02E8138h
7、对比机器码和汇编表示,有什么发现??
002E16EE C7 05 38 81 2E 00 18 00 00 00 mov dword ptr [g (02E8138h)],18h
38 81 2E 00 18 00 00 00
(02E8138h) 18h
细心的你肯定发现了,同样有00,2E,81,38!!同样是18
8、和你的猜想没错,真相是这样(后缀h代表16进制数字)
C7 05 (代表mov指令) 38 81 2E 00 (代表变量地址是002E8138)18 00 00 00 (代表要符给定的值是18h)
9、纸上得来终觉浅,绝知此事要躬行。
dword ptr [g (02E8138h)],18h ……变量g的地址真的是02E8138h??g的值真的是18h=24??
验证方法:在反汇编页面用F11逐语句调试至赋值语句的下一行,shift+F9 打开 “快速监视”,输入框内输入g,回车,发现g的值为24;输入&g,发现地址是02E8138h。
10、我们改变变量g的值,比如g=257,同样反汇编发现他的物理地址是038138h,然而038138h处的值真的是257吗??
光标放在赋值语句那一行,F9设置断点,F5开始调试;
鼠标右键选择进入反汇编
依次打开 调试-窗口-内存-内存1,在输入框里输入038138h,发现目前该地址处为0
按F11调试到下一语句,发现038138h处的值变为01 01 00 00……,也就是0101h=257
内存区域按照每两个十六进制数一组的方式显示,可以鼠标右键改为4个一组,更符合习惯。
11、查找内存时,每个地址对应一串数字,,哪些才是存储变量值呢??
有一个sizeof函数,可以给出占用字节数,试一下,发现变量g占了4个字节
已知四个字节,我们就去验证一下,给g赋值0x12345678(16进制数,每两个为一字节)至此,我们知道赋给g的值占用该地址的前四个字节
12、机智的你又发现问题了,为啥0x12345678在地址里面是78 56 34 12 ??
一句话:逻辑上的低字节放在物理上的低字节!
输入代码
选择反汇编
反汇编之后的结果
去掉“显示代码字节”
使用“快速监视”
内存监视内存地址的数值变化
F11调试到下一句
内存监视区域改为4个一组