今天读了下main函数初始化的汇编码
1: void main()
2: {
00401010 push ebp 
00401011 mov ebp,esp
00401013 sub esp,40h 
00401016 push ebx
00401017 push esi
00401018 push edi
00401019 lea edi,[ebp-40h] 
0040101C mov ecx,10h
00401021 mov eax,0CCCCCCCCh
00401026 rep stos dword ptr [edi]此时 ESP = 0x0012FE8C, SS = 0x0023
读到这我突然想看看分配的局部变量缓冲区是不是都被置为0xCCCCCCH,于是在VC调试下打开memory想输入[esp]所指的地址,即堆栈的地址
可这时突然不知道该输什么好了,大家知道取地址[esp]其实代表地址的是ss:esp, 也就是说真正的堆栈栈顶地址难道不应该是 SS:ESP = 0x 0022 0012FE8C 么?,
但memory对话框只允许输入一个双字长度的地址,我只得输入逻辑地址 ESP = 0x0012FE8C, 结果也确实找到了堆栈栈顶,但问题也来了
这个memory对话框是怎么知道我想输入的段地址的?? 是自动把我段地址指定为SS么?? 要知道,我的代码段地址CS = 0x001B , 和SS可不一样, 如果我想找的是以CS为段地址的内存空间呢? 他这么自动帮我把段地址定为SS那不是乱了套了?恳请帮我这个初学者解下惑 感激不尽

解决方案 »

  1.   

    cs是代码段吧,代码段是用eip表示,堆栈段是才是用的esp
      

  2.   

    这个我知道 但是memory对话框里我输入的是地址的值,而不是寄存器的名字
    我这个 0x0012FE8C 既可以代表 ESP 的值, 同样也可能代表 EIP 啊, 问题在于, VC是怎么知道我这个 0x0012FE8C 的段地址是什么? 是SS? 还是CS?
      

  3.   

    直接输入esp就可以,不用输入esp的值。
    Windows程序是平坦模式,cs、ds、es、ss的段基地址都是0,段大小都是4GB。
      

  4.   


    1.这里不是输入什么的问题...而是我既然已经输入值了为什么会出现这个结果的问题
    2.我的ds,es,ss都是0023H,cs是001BH, 没有是0的, 这都是从我的程序的汇编码里抄下来的, 可不是我瞎编的!
      

  5.   

    “Windows程序是平坦模式,cs、ds、es、ss的段基地址都是0,段大小都是4GB。”
    这句话的意思是,在Windows系统中,cs、ds、es、ss这些段都是完全重叠的,只用偏移量就可以表示地址,不需要管段寄存器。
    这点理解后,前一问自然就不用问了。
      

  6.   


    你的意思是, 虽然VC显示的CS,DS,ES,SS寄存器的值不同,但其实WINDOWS根本没用到这些寄存器么? 并且默认把段地址指定为0么?
    那段寄存器是用来干什么的?
      

  7.   

    我建议如果你想真明白,改用WINDEBUG的调试器,那里面是可以该面CS,DS,...的,你在用户模式下调试总会有些局限性,要说明的是cs,DS,ES中的应经不是段地址了,在保护模式下那是选择子,它们表示4GB内存中的莫一段,
    也就是个标号,会对应LDT GDT表中的一个项,所以这要看表的具体情况我记得以前我追代码的时候注意过,WINDOWS操作系统的选择子很多并不都是4GB范围的;
    只是我们在用户模式下编程的时候编译器为我们做了很多工作,让我们不用和最底层的东西打交道!
      

  8.   

    不是没用到这些寄存器,而是这些寄存器描述的段是完全重叠的,只要偏移量相同,用CS,DS,ES,SS中任意一个寄存器来访问,都是相同的地址。
      

  9.   

    这个百度百科很详细的回答了我的问题
    http://baike.baidu.com/view/404433.html?tp=0_01依旧感谢上面的达人, 不然我也搜不到