怎樣才能debug出 eax, ebp等東東?


在我的代碼中,使用了 .386模式,在代碼中 我使用了 mov eax,12345678H, 等代碼;程序經過 編譯,聯結后也成為了 exe文件。然后我在命令行下,采用debug進去調試,之后,用T,P,等命令調試。最后看到的還是 AX,BX,CX,.....等東東。如何才能看到 EAX,EBP...等寄存器中的值呢? 
請高手指點。謝謝了。

12 个解决方案

#1


下載個OllyDBG
用OllyDBG就能看到了

#2


看樓主是什么類型的程序了. 是 dos16 的話, 可以使用支持 386 級指令的調試程序, 比如 cv, tdebug, debug32 等等; 如果是 win32 類的話, 就使用樓上推薦的 OlyDbg, w32dsm, SoftICE 等等

#3


樓主要查看eax等寄存器中的值,應該是win32應用程序吧?

#4


樓上的兄弟,16位dos程序一樣可以用32位寄存器的

#5


try to use debug32 ,you can downloal at www.aogosoft.com

#6


download :(

#7


使用調試器啊,EAX這種都是32位機器的寄存器,首先機器要對!

#8


SoftICE
OllyDBG
還有TRW
都不錯的調試器,可以在WWW.PEDIY.COM上找到,上面還有很多調試的技術呢!

#9


推薦使用:
OlyDbg
w32dsm

#10


我學保護模式程序設計的時候,用的是Bochs虛擬機。Bochs的調試模式可以看到所有的寄存器。

在實模式下是可以使用eax等32位寄存器的,只要指定.386偽指令就可以了。

如:在從實模式跳轉到保護模式時,一般用:mov cr0,eax來修改控制寄存器。這時,程序還處在實模式下,但是可以使用32位的eax寄存器。

但是用dos下的debug的反匯編模式是看不到的。

#11


如果是調試windows程序,我建議你使用國產調試器CCASM,實在是太方便了。
下載地址:http://www.chencan.com/ccasm/downloadtest.htm

#12


別爭了

用微軟提供的windbg吧

可以參考:

http://blogs.msdn.com/lixiong

里面有專門講匯編調試的一個section,節錄在這里:






[案例2]
不要迷信compiler沒有bug。 如果你在VS2003中測試下面的代碼,會發現在release mode下面,程序會崩潰或者異常,但是debug環境下工作正常。

// The following code crashes/abnormal in release build when "whole program optimizations /GL"
// is set. The bug is fixed in VS2005

#include <string>
#pragma warning( push )
#pragma warning( disable : 4702 ) // unreachable code in <vector>
#include <vector>
#pragma warning( pop )
#include <algorithm>
#include <iostream>

//vcsig
// T = float, U = std::cstring
template <typename T, typename U> T func_template( const U & u )
{
std::cout<<u<<std::endl;
const char* str=u.c_str();
printf(str);
return static_cast<T>(0);
}

void crash_in_release()
{
std::vector<std::string> vStr;

vStr.push_back("1.0");
vStr.push_back("0.0");
vStr.push_back("4.4");

std::vector<float> vDest( vStr.size(), 0.0 );

std::vector<std::string>::iterator _First=vStr.begin();
std::vector<std::string>::iterator _Last=vStr.end();
std::vector<float>::iterator _Dest=vDest.begin();

std::transform( _First,_Last,_Dest, func_template<float,std::string> );

 _First=vStr.begin();
 _Last=vStr.end();
 _Dest=vDest.begin();


for (; _First != _Last; ++_First, ++_Dest)
*_Dest =  func_template<float,std::string>(*_First);
}


int main(int, char*)
{
getchar();
crash_in_release();
return 0;
}

編譯設定如下:

1. 取消precompiled header
2. 編譯選項是: /O2 /GL /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /EHsc /ML /GS /Fo"Release/" /Fd"Release/vc70.pdb" /W4 /nologo /c /Wp64 /Zi /TP

拿到這個問題后,首先在本地重現。根據下面的一些測試和分析,很有可能是compiler的bug:

1. 程序中除了cout和printf外,沒有牽涉到系統相關的API. (關於cout, printf跟系統API的關系,后面有介紹), 所有的操作都是寄存器和內存上的操作。所以不會是環境或者系統因素導致的,唯一的可能性就是語法有問題或者編譯器有問題。
2. 檢查語法后沒有發現異常。同時,如果調整一下std::transform 的位置,在for loop后面調用的話,問題也不會發生。語法問題不會導致這么奇怪的結果。
3. 問題發生的情況跟編譯模式相關。

代碼中的std::transform和for loop的作用都是對整個vector調用func_template做轉換。可以比較transform和for loop的執行情況進行比較分析,看看func_template的執行過程有什么區別。在VS2003里面在main函數設定斷點,停下來后用ctrl_alt_D進入匯編模式單步跟蹤。通過下面的分析,證明了這是compiler的bug:

在STL源代碼中,發現std::transform的實現中用這樣的代碼來調用傳入的轉換函數:

*_Dest = _Func(*_First);

編譯器對於該代碼的處理是:
 
EAX = 0012FEA8 EBX = 0037138C ECX = 003712BC EDX = 00371338 ESI = 00371338 EDI = 003712B0 EIP = 00402228 ESP = 0012FE70 EBP = 0012FEA8 EFL = 00000297 
   388:            *_Dest = _Func(*_First);
00402228 push        esi  
00402229 call        dword ptr [esp+28h] 
0040222D fstp        dword ptr [edi]

ESI中保存的是需要傳入func_template的參數。可以看到,使用transform的時候,這個參數是通過push指令傳入stack給func_template調用的。

對於for loop中的*_Dest =  func_template<float,std::string>(*_First);編譯器是這樣處理的:

EAX = 003712B0 EBX = 00371338 ECX = 003712BC EDX = 00000000 ESI = 00371338 EDI = 0037138C EIP = 00401242 ESP = 0012FE98 EBP = 003712B0 EFL = 00000297
    37:              *_Dest =  func_template<float,std::string>(*_First);
00401240 mov         ebx,esi 
00401242 call        func_template <float,std::basic_string<char,std::char_traits<char>,std::allocator<char> > > (4021A0h) 
00401247 fstp        dword ptr [ebp] 

可以看到,使用for loop的時候,參數通過mov指令保存到ebx寄存器中傳入給func_template調用。

最后,看一下func_template函數是如何來獲取傳入的參數:

004021A0 push        esi  
004021A1 push        edi  
    16:      std::cout<<u<<std::endl;
004021A2 push        ebx  
004021A3 push        offset std::cout (414170h) 
004021A8 call        std::operator<<<char,std::char_traits<char>,std::allocator<char> > (402280h)

這里直接把ebx推入stack, 然后調用std::cout,沒有訪問stack,func_template (callee)認為參數應該是從寄存器中傳入的。然而transform函數(caller)卻把參數通過stack傳遞。於是使用transform調用func_template的時候,func_template無法拿到正確的參數,繼而導致崩潰。通過for loop調用的時候,func_template就可以工作正常。編譯器對參數的傳入,讀取處理不統一,導致了這個問題。

至於為何問題在debug模式下不發生,或者調換函數次序后也不發生,留為練習吧 :-P


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com