Debug和Realise版本

Debug和Realise版本
Debug和Realise版本

Debug与Release版本的区别

Debug 和Release 并没有本质的区别,他们只是VC预定义提供的两组编译选项的集合,编译器只是按照预定的选项行动。如果我们愿意,我们完全可以把Debug和Release 的行为完全颠倒过来。当然也可以提供其他的模式,例如自己定义一组编译选项,然后命名为MY_ABC等。习惯上,我们仍然更愿意使用VC已经定义好的名称。

Debug版本包括调试信息,所以要比Release版本大很多(可能大数百K至数M)。至于是否需要DLL支持,主要看你采用的编译选项。如果是基于ATL的,则Debug和Release 版本对DLL的要求差不多。如果采用的编译选项为使用MFC动态库,则需要MFC42D.DLL 等库支持,而Release版本需要MFC42.DLL支持。Release不对源代码进行调试,不考虑MFC的诊断宏,使用的是MFC Release库,编译时对应用程序的速度进行优化,而Debug则正好相反,它允许对源代码进行调试,可以定义和使用MFC的诊断宏,采用MFC Debug库,对速度没有优化。

既然Debug和Release仅仅是编译选项的不同,那么为什么要区分Debug和Release 版本呢?

Debug和Release,在我看来主要是针对其面向的目标不同的而进行区分的。Debug通常称为调试版本,通过一系列编译选项的配合,编译的结果通常包含调试信息,而且不做任何优化,以为开发人员提供强大的应用程序调试能力。而Release通常称为发布版本,是为用户使用的,一般客户不允许在发布版本上进行调试。所以不保存调试信息,同时,它往往进行了各种优化,以期达到代码最小和速度最优。为用户的使用提供便利。

下面仅就默认的Debug和Release版本的选项进行比较,详细的编译选项可以看MSDN 的说明。

我们将默认的Debug和Release的选项设置进行比较,过滤掉相同设置,主要的不同如下:编译选项:/Od /D "_DEBUG" /Gm /RTC1 /MDd /Fo"Debug““" /ZI

链接选项:/OUT:"D:“MyProject“logging“Debug“OptionTest.dll" /INCREMENTAL Release设置:

编译选项:/O2 /GL /D "NDEBUG" /FD /MD /Fo"Release““" /Zi

链接选项:/OUT:"D:“MyProject“logging“Release“OptionTest.dll" /INCREMENTAL:NO

Debug 版本:

/MDd /MLd 或/MTd 使用Debug runtime library(调试版本的运行时刻函数库)

/Od 关闭优化开关

/D "_DEBUG" 相当于#define _DEBUG,打开编译调试代码开关(主要针对assert函数)

/ZI 创建Edit and continue数据库,在调试过程中如果修改了源代码不需重新编译

/GZ 可以帮助捕获内存错误

/Gm 打开最小化重链接开关,减少链接时间

Release 版本:

/MD /ML 或/MT 使用发布版本的运行时刻函数库

/O1 或/O2 优化开关,使程序最小或最快

/D "NDEBUG" 关闭条件编译调试代码开关(即不编译assert函数)

/GF 合并重复的字符串,并将字符串常量放到只读内存,防止被修改

MDd与MD

首先,Debug版本使用调试版本的运行时库(/MDd选项),Relase版本则使用的是发布版本的运行时库(vcrt.dll)。其区别主要在于运行时的性能影响。调试版本的运行时库包含了调试信息,并采用了一些保护机制以帮助发现错误,也因此,其性能不如发布版本。编译器提供的Runtime Library很稳定,不会造成Release版本错误,倒是由于Debug版本的Runtime Library加强了对错误的检测,如堆内存分配检查等,反而会报告错误,应当指出,如果Debug有错误,而Release版本正常,程序肯定是有Bug的,只是我们还没有发现。

ZI与Zi

其次,/ZI选项与/Zi选项。通过使用/ZI选项,可以在调试过程修改代码而不需要重新编译。这是个调试的好帮手,可如果我们使用Release版本,这将变得不可行。

Od与O2

/O2与/Od 选项:Od是关闭编译器优化,普遍用于Debug版本。而O2选项是创建最快速代码,这当然是Release版本的不二选择。

RTCx选项

/RTCx选项让编译器插入动态检测代码以帮助你检测程序中的错误。比如,它会将局部变量初始化为非零值。包括用0xCC初始化所有自动变量,0xCD初始化堆中分配的内存(即new的内存),使用0xDD填充被释放的内存(即delete的内存),0xFD初始化受保护的内存(debug版在动态分配内存的前后加入保护内存以防止越界访问)。这样做的好处是这些值都很大,一般不可能作为指针,考试,大提示作为数值也很少用到,而且这些值很容易辩认,因此有利于在Debug版本中发现Release版才会遇到的错误。另外,通过函数指针调用函数时,会通过检查栈指针验证函数调用的匹配性(防止原型不匹配)。使用/RTCx 选项会造成Debug版本出错,而Release版本正常的现象,因为Release版中未初始化的变量是随机的,很可能使指针指向了有效但是错误的地址,从而掩盖了错误。这个编译选项只能在/Od选项下使用。

Gm,INCREMENTAL or NO

编译选项中的Gm和链接选项中的INCREMENTAL都只为一个目的,加快编译速度。我们经常遇上这样的问题,只修改了一个头文件,结果却造成所有动态库的重新编译。而这两个选项就是为了解决这样的问题。如果启用了/Gm开关,编译器在项目中的.idb文件中存储了源文件和类定义之间的依赖关系。之后的编译过程中使用.idb 文件中的信息确定是否需要编译某个源文件,哪怕是此源文件已经包含了已修改的.h文件。

INCREMENTAL开关默认是开启的。使用增量链接生成的可执行文件或者动态链接库会大于非增量链接的程序,因为有代码和数据的填充。另外,增量链接的文件还包含跳转trunk 以处理函数重定位到新地址。

MSDN 上明确指出:为确保最终发布版本不包含填充或者trunk,请非增量链接程序。

/GZ 选项:做以下这些事

1.初始化内存和变量。包括用0xCC 初始化所有自动变量,

0xCD ( Cleared Data ) 初始化堆中分配的内存(即动态分配的内存,例如new ),0xDD ( Dead Data ) 填充已被释放的堆内存(例如delete ),

0xFD( deFencde Data ) 初始化受保护的内存(debug 版在动态分配内存的前后加入保护内存以防止越界访问),其中括号中的词是微软建议的助记词。这样做的好处是这些值都很大,作为指针是不可能的(而且32 位系统中指针很少是奇数值,在有些系统中奇数的指针会产生运行时错误),作为数值也很少遇到,而且这些值也很容易辨认,因此这很有利于在Debug 版中发现Release 版才会遇到的错误。要特别注意的是,很多人认为编译器会用0 来初始化变量,这是错误的(而且这样很不利于查找错误)。

2. 通过函数指针调用函数时,会通过检查栈指针验证函数调用的匹配性。(防止原形不匹配)

3. 函数返回前检查栈指针,确认未被修改。(防止越界访问和原形不匹配,与第二项合在一起可大致模拟帧指针省略FPO )

通常/GZ 选项会造成Debug 版出错而Release 版正常的现象,因

为Release 版中未初始化的变量是随机的,这有可能使指针指向一个有效地址而掩盖了非法访问。

_DEBUG与NDEBUG

这是最重要的一个选项。这两个是编译器的预处理器定义,默认情况下_DEBUG用于Debug 版本,而NDEBUG用于Release版本。它们可以说是重要的无以复加。因为,assert系列的断言仅仅在_DEBUG下生效!

下面是assert.h文件中摘出来的:

C++代码

1. #ifdef NDEBUG

2. #define assert(_Expression) ((void)0)

3. #else /* NDEBUG */

4. #ifdef __cplusplus

5. extern "C" {

6. #endif /* __cplusplus */

7. _CRTIMP void __cdecl _wassert(__in_z const wchar_t * _Message, __in_z const

wchar_t *_File, __in unsigned _Line);

8. #ifdef __cplusplus

9. }

10. #endif /* __cplusplus */

11. #define assert(_Expression) (void)( (!!(_Expression)) || (_wassert(_CRT_WIDE(#

_Expression), _CRT_WIDE(__FILE__), __LINE__), 0) )

12. #endif /* NDEBUG */

可以看出在未定义_DEBUG时,assert变成一条空语句不被执行。

也就是说,我们现在所有发布的版本无法使用断言机制进行程序调试。

相关经验:

1. 变量。

大家都知道,debug跟release在初始化变量时所做的操作是不同的,debug是将每个字节位都赋成0xcc,而release的赋值近似于随机。如果你的程序中的某个变量没被初始化就被引用,就很有可能出现异常:用作控制变量将导致流程导向不一致;用作数组下标将会使程序崩溃;更加可能是造成其他变量的不准确而引起其他的错误。所以在声明变量后马上对其初始化一个默认的值是最简单有效的办法,否则项目大了你找都没地方找。代码存在错误在debug方式下可能会忽略而不被察觉到。debug方式下数组越界也大多不会出错,在release中就暴露出来了,这个找起来就比较难了。

2. 自定义消息的消息参数。

MFC为我们提供了很好的消息机制,更增加了自定义消息,好处我就不用多说了。这也存在debug跟release的问题吗?答案是肯定的。在自定义消息的函数体声明时,时常会看到这样的写法:afx_msg LRESULT OnMessageOwn(); Debug 情况下一般不会有任何问题,而当你在Release下且多线程或进程间使用了消息传递时就会导致无效句柄之类的错误。导致这个错误直接原因是消息体的参数没有添加,即应该写成:afx_msg LRESULT OnMessageOwn(WPARAM wparam, LPARAM lparam); 3. release模式下不出错,但debug模式下报错。

这种情况下大多也是因为代码书写不正确引起的,查看MFC 的源码,可以发现好多

ASSERT的语句(断言),这个宏只是在debug模式下才有效,那么就清楚了,release版不报错是忽略了错误而不是没有错误,这可能存在很大的隐患,因为是Debug模式下,比较方便调试,好好的检查自己的代码,再此就不多说了。

3. ASSERT, VERIFY, TRACE.......... 调试宏

这种情况很容易解释。举个例子:请在VC下输入ASSERT然后选中按F12跳到宏定义的地方,这里你就能够发现Debug中ASSERT要执行AfxAssertFailedLine,而Release 下的宏定义却为\"#define ASSERT(f) ((void)0)\"。所以注意在这些调试宏的语句不要用程序相关变量如i++写操作的语句。

VERIFY 是个例外,\"#define VERIFY(f) ((void)(f))\",即执行。

哪些情况下Release版会出错?

1. Runtime Library:链接哪种运行时刻函数库通常只对程序的性能产生影响。调试版本的Runtime Library 包含了调试信息,并采用了一些保护机制以帮助发现错误,因此性能不如发布版本。编译器提供的Runtime Library 通常很稳定,不会造成Release 版错误;倒是由于Debug 的Runtime Library 加强了对错误的检测,如堆内存分配,有时会出现Debug 有错但Release 正常的现象。应当指出的是,如果Debug 有错,即使Release 正常,程序肯定是有Bug 的,只不过可能是Release 版的某次运行没有表现出来而已。

2. 优化:这是造成错误的主要原因,因为关闭优化时源程序基本上是直接翻译的,而打开优化后编译器会作出一系列假设。这类错误主要有以下几种:

(1) 帧指针(Frame Pointer)省略(简称FPO ):在函数调用过程中,所有调用信息(返回地址、参数)以及自动变量都是放在栈中的。若函数的声明与实现不同(参数、返回值、调用方式),就会产生错误,但Debug 方式下,栈的访问通过EBP 寄存器保存的地址实现,如果没有发生数组越界之类的错误(或是越界“不多”),函数通常能正常执行;Release 方式下,优化会省略EBP 栈基址指针,这样通过一个全局指针访问栈就会造成返回地址错误是程序崩溃。C++ 的强类型特性能检查出大多数这样的错误,但如果用了强制类型转换,就不行了。你可以在Release 版本中强制加入/Oy- 编译选项来关掉帧指针省略,以确定是否此类错误。此类错误通常有:

MFC消息响应函数书写错误。正确的应为

afx_msg LRESULT OnMessageOwn(WPARAM wparam, LPARAM lparam);

ON_MESSAGE 宏包含强制类型转换。防止这种错误的方法之一是重定

义ON_MESSAGE 宏,把下列代码加到stdafx.h 中(在#include "afxwin.h"之后),函数原形错误时编译会报错

C++代码

1. #undef ON_MESSAGE

2. #define ON_MESSAGE(message, memberFxn) \

3. { message, 0, 0, 0, AfxSig_lwl, \

4. (AFX_PMSG)(AFX_PMSGW)(static_cast< LRESULT (AFX_MSG_CALL \

5. CWnd::*)(WPARAM, LPARAM) > (&memberFxn) },

(2) volatile 型变量:volatile 告诉编译器该变量可能被程序之外的未知方式修改(如系统、其他进程和线程)。优化程序为了使程序性能提高,常把一些变量放在寄存器中(类似

于register 关键字),而其他进程只能对该变量所在的内存进行修改,而寄存器中的值没变。如果你的程序是多线程的,或者你发现某个变量的值与预期的不符而你确信已正确的设置了,则很可能遇到这样的问题。这种错误有时会表现为程序在最快优化出错而最小优化正常。把你认为可疑的变量加上volatile 试试。

(3) 变量优化:优化程序会根据变量的使用情况优化变量。例如,函数中有一个未被使用的变量,在Debug 版中它有可能掩盖一个数组越界,而在Release 版中,这个变量很可能被优化调,此时数组越界会破坏栈中有用的数据。当然,实际的情况会比这复杂得多。与此有关的错误有:

非法访问,包括数组越界、指针错误等。例如

C++代码

1. void fn(void)

2. {

3. int i;

4. i = 1;

5. int a[4];

6. {

7. int j;

8. j = 1;

9. }

10. a[-1] = 1; //当然错误不会这么明显,例如下标是变量

11. a[4] = 1;

12. }

j 虽然在数组越界时已出了作用域,但其空间并未收回,因而i 和j 就会掩盖越界。

而Release 版由于i、j 并未其很大作用可能会被优化掉,从而使栈被破坏。

3. _DEBUG 与NDEBUG :当定义了_DEBUG 时,assert() 函数会被编译,

而NDEBUG 时不被编译。除此之外,VC++中还有一系列断言宏。这包括:

ANSI C 断言void assert(int expression );

C Runtime Lib 断言_ASSERT( booleanExpression );

_ASSERTE( booleanExpression );

MFC 断言ASSERT( booleanExpression );

VERIFY( booleanExpression );

ASSERT_VALID( pObject );

ASSERT_KINDOF( classname, pobject );

ATL 断言ATLASSERT( booleanExpression );

此外,TRACE() 宏的编译也受_DEBUG 控制。

所有这些断言都只在Debug版中才被编译,而在Release 版中被忽略。唯一的例外

是VERIFY() 。事实上,这些宏都是调用了assert() 函数,只不过附加了一些与库有关的调试代码。如果你在这些宏中加入了任何程序代码,而不只是布尔表达式(例如赋值、能改变变量值的函数调用等),那么Release 版都不会执行这些操作,从而造成错误。初学者很容易犯这类错误,查找的方法也很简单,因为这些宏都已在上面列出,只要利

用VC++ 的Find in Files 功能在工程所有文件中找到用这些宏的地方再一一检查即可。另外,有些高手可能还会加入#ifdef _DEBUG 之类的条件编译,也要注意一下。顺便值得一提的是VERIFY() 宏,这个宏允许你将程序代码放在布尔表达式里。这个宏通常用来检查Windows API 的返回值。有些人可能为这个原因而滥用VERIFY() ,事实上这是危险的,因为VERIFY() 违反了断言的思想,不能使程序代码和调试代码完全分离,最终可能会带来很多麻烦。因此,专家们建议尽量少用这个宏。

一、"Debug是调试版本,包括的程序信息更多"

补充:只有DEBUG版的程序才能设置断点、单步执行、使用TRACE/ASSERT等调试输出语句。REALEASE不包含任何调试信息,所以体积小、运行速度快。

I. 内存分配问题

1. 变量未初始化。下面的程序在debug中运行的很好。

C++代码

1. thing * search(thing * something)

2. BOOL found;

3. for(int i = 0; i < whatever.GetSize(); i++)

4. {

5. if(whatever[i]->field == something->field)

6. { /* found it */

7. found = TRUE;

8. break;

9. } /* found it */

10. }

11. if(found)

12. return whatever[i];

13. else

14. return NULL;

而在release中却不行,因为debug中会自动给变量初始化found=FALSE,而在release 版中则不会。所以尽可能的给变量、类或结构初始化。

2. 数据溢出的问题

如:

C++代码

1. char buffer[10];

2. int counter;

3. lstrcpy(buffer, "abcdefghik");

在debug版中buffer的NULL覆盖了counter的高位,但是除非counter>16M,什么问题也没有。但是在release版中,counter可能被放在寄存器中,这样NULL就覆盖了buffer 下面的空间,可能就是函数的返回地址,这将导致ACCESS ERROR。

3. DEBUG版和RELEASE版的内存分配方式是不同的。如果你在DEBUG版中申请ele 为6*sizeof(DWORD)=24bytes,实际上分配给你的是32bytes(debug版以32bytes为单位分配),而在release版,分配给你的就是24bytes(release版以8bytes 为单位),所以在debug版中如果你写ele[6],可能不会有什么问题,而在release版中,就有ACCESS VIOLATE。

II. ASSERT和VERIFY

1. ASSERT在Release版本中是不会被编译的。

ASSERT宏是这样定义的

C++代码

1.

2. #ifdef _DEBUG

3. #define ASSERT(x) if( (x) == 0) report_assert_failure()

4. #else

5. #define ASSERT(x)

6. #endif

实际上复杂一些,但无关紧要。假如你在这些语句中加了程序中必须要有的代码比如

C++代码

1.

2. ASSERT(pNewObj = new CMyClass);

3.

4. pNewObj->MyFunction();

这种时候Release版本中的pNewObj不会分配到空间

所以执行到下一个语句的时候程序会报该程序执行了非法操作的错误。这时可以用VERIFY :

C++代码

1.

2. #ifdef _DEBUG

3. #define VERIFY(x) if( (x) == 0) report_assert_failure()

4. #else

5. #define VERIFY(x) (x)

6. #endif

这样的话,代码在release版中就可以执行了。

III. 参数问题:

自定义消息的处理函数,必须定义如下:

afx_msg LRESULT OnMyMessage(WPARAM, LPARAM);

返回值必须是HRESULT型,否则Debug会过,而Release出错

IV. 内存分配

保证数据创建和清除的统一性:如果一个DLL提供一个能够创建数据的函数,那么这个DLL同时应该提供一个函数销毁这些数据。数据的创建和清除应该在同一个层次上。

V. DLL的灾难

人们将不同版本DLL混合造成的不一致性形象的称为“动态连接库的地狱“(DLL Hell) ,甚至微软自己也这么说https://www.360docs.net/doc/613043934.html,/library/techart/dlldanger1.htm)。

如果你的程序使用你自己的DLL时请注意:

1. 不能将debug和release版的DLL混合在一起使用。debug都是debug版,release 版都是release版。

解决办法是将debug和release的程序分别放在主程序的debug和release目录下

2. 千万不要以为静态连接库会解决问题,那只会使情况更糟糕。

VI. RELEASE版中的调试:

1. 将ASSERT() 改为VERIFY() 。找出定义在"#ifdef _DEBUG"中的代码,如果在RELEASE版本中需要这些代码请将他们移到定义外。查找TRACE(...)中代码,因为这些代码在RELEASE中也不被编译。请认真检查那些在RELEASE中需要的代码是否并没有被便宜。

2. 变量的初始化所带来的不同,在不同的系统,或是在DEBUG/RELEASE版本间都存在这样的差异,所以请对变量进行初始化。

3. 是否在编译时已经有了警告?请将警告级别设置为3或4,然后保证在编译时没有警告出现.

VII. 将Project Settings" 中"C++/C " 项目下优化选项改为Disbale (Debug)。编译器的优化可能导致许多意想不到的错误,请参https://www.360docs.net/doc/613043934.html, /~newcomer/debug_release.htm

1. 此外对RELEASE版本的软件也可以进行调试,请做如下改动:

在"Project Settings"中"C++/C"项目下设置"category"为"General"并且将"Debug Info"设置为"Program Database"。

在"Link"项目下选中"Generate Debug Info"检查框。

"Rebuild All"

如此做法会产生的一些限制:

无法获得在MFC DLL中的变量的值。

必须对该软件所使用的所有DLL工程都进行改动。

另:

1. MS BUG:MS的一份技术文档中表明,在VC5中对于DLL的"Maximize Speed"优化选项并未被完全支持,因此这将会引起内存错误并导致程序崩溃。

2. https://www.360docs.net/doc/613043934.html,/有一个程序DebugView,用来捕捉OutputDebugString 的输出,运行起来后(估计是自设为system debugger)就可以观看所有程序的OutputDebugString的输出。此后,你可以脱离VC来运行你的程序并观看调试信息。

3. 有一个叫Gimpel Lint的静态代码检查工具,据说比较好用https://www.360docs.net/doc/613043934.html,/ 不过要化$的。

Debug与Release不同的问题在刚开始编写代码时会经常发生,99%是因为你的代码书写错误而导致的,所以不要动不动就说系统问题或编译器问题,努力找找自己的原因才是根本。我从前就常常遇到这情况,经历过一次次的教训后我就开始注意了,现在我所写过的代码我已经好久没遇到这种问题了。下面是几个避免的方面,即使没有这种问题也应注意一下:

1. 注意变量的初始化,尤其是指针变量,数组变量的初始化(很大的情况下另作考虑了)。

2. 自定义消息及其他声明的标准写法

3. 使用调试宏时使用后最好注释掉

4. 尽量使用try - catch(...)

5. 尽量使用模块,不但表达清楚而且方便调试。

Qt 怎样设置应用程序图标以及release版本的主意事项

Qt 怎样设置应用程序图标以及release版本的主意事项 第一步,准备个ICO图标。 例如:myApp.ico 用任何的文本编辑器新建个文件 里面写上一行: IDI_ICON1 ICON DISCARDABLE "myApp.ico" 第二步,保存改名为myApp.rc并把它和你的图标myApp.ico一起放置到你的Qt工程的目录里面。 第三步,用文本编辑器打开你的Qt工程文件(如myApp.pro ),在里面的最后面新添一行: RC_FILE = myApp.rc 第四步,在程序中添加如下代码: //app是程序中唯一的QApplication对象 app.setWindowIcon(QIcon("myApp.ico")); 注意:如果你的myApp.rc和你的图标myApp.ico不是在你的Qt工程目录里面,那么最后一句的代码中请指明图标文件的路径。 2.release版本主意事项 (1)在没有安装Qt的电脑上运行编译的程序,会提示缺少一些库文件,比如mingwm10.dll,libgcc_s_dw2_1.dll,这时需要在自己的开发程序的电脑上收索这些dll文件(全盘收索吧,不知道路径的话) (2)可能不能正确显示背景图片。解决方法如下: 要显示自己加入qrc文件中的信息,需要把qt的一个文件包复制,跟release.exe放在一个文件夹中,这样在没有装qt的电脑就业能运行了。文件包的名字叫imageformats。 给QT程序的EXE添加图标 问:要想让Qt程序的Debug和Release版本的exe都有图标,总共分几步?

答:总共分三步,客官看好,千万别眨眼! 第一步:在项目文件夹目录下创建文件app.rc,把从网上down下来的叫做tubiao.ico的图标也Copy进来在app.rc里面写上这么一段话: IDI_ICON1 ICON DISCARDABLE "tubiao.ico" 第二步:打开Qt Creator,把这两个文件导入到项目里面 第三步:在项目的pro文件里面填上: RC_FILE+=app.rc 给QT程序添加一个漂亮的图标 【问题描述】如图1所示,直接编译的QT程序,没有漂亮的外观,如何给程序添加一个漂亮的图标呢?

【微机原理】DEBUG命令详解

DUBUG命令详解 Debug:A(汇编) 直接将8086/8087/8088 记忆码合并到内存。 该命令从汇编语言语句创建可执行的机器码。所有数值都是十六进制格式,必须按一到四个字符输入这些数值。在引用的操作代码(操作码)前指定前缀记忆码。 a [address] 参数address指定键入汇编语言指令的位置。对address 使用十六进制值,并键入不以“h”字符结尾的每个值。如果不指定地址,a 将在它上次停止处开始汇编。有关将数据输入到指定字节中的信息,请单击“相关主题”列表中的Debug E(键入)。有关反汇编字节的信息,请单击“相关主题”列表中的Debug U(反汇编)。 说明使用记忆码 段的替代记忆码为cs:、ds:、es: 和ss:。远程返回的记忆码是retf。字符串处理的记忆码必须明确声明字符串大小。例如,使用movsw 可以移动16 位的字串,使用movsb 可以移动8 位字节串。 汇编跳转和调用汇编程序根据字节替换自动将短、近和远的跳转及调用汇编到目标地址。通过使用near 或far 前缀可以替代这样的跳转或调用,如下例所示: -a0100:0500 0100:0500 jmp 502 ; a 2-byte short jump 0100:0502 jmp near 505 ; a 3-byte near jump 0100:0505 jmp far 50a ; a 5-byte far jump 1

可以将near 前缀缩写为ne。 区分字和字节内存位置当某个操作数可以引用某个字内存位置或者字节内存位置时,必须用前缀word ptr 或者前缀byte ptr 指定数据类型。可接受的缩写分别是wo 和by。以下范例显示两种格式: dec wo [si] neg byte ptr [128] 指定操作数Debug 使用包括在中括号([ ]) 的操作数引用内存地址的习惯用法。这是因为另一方面Debug 不能区分立即操作数和内存地址的操作数。以下范例显示两种格式: mov ax,21 ; load AX with 21h mov ax,[21] ; load AX with the ; contents of ; memory location 21h 使用伪指令使用a 命令提供两个常用的伪指令:db 操作码,将字节值直接汇编到内存,dw 操作码,将字值直接汇编到内存。以下是两个伪指令的范例: db 1,2,3,4,"THIS IS AN EXAMPLE" db 'THIS IS A QUOTATION MARK:"' db "THIS IS A QUOTATION MARK:'" dw 1000,2000,3000,"BACH" 范例a 命令支持所有形式的间接注册命令,如下例所示: 2

VS中的一些应用Debug和Release区别

Debug和Release区别 VC下Debug和Release区别 最近写代码过程中,发现Debug 下运行正常,Release 下就会出现问题,百思不得其解,而Release 下又无法进行调试,于是只能采用printf方式逐步定位到问题所在处,才发现原来是给定的一个数组未初始化,导致后面处理异常。网上查找了些资料,在这罗列汇总下,做为备忘~ 一、Debug 和Release 的区别 Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。Release 称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。 Debug 和Release 的真正区别,在于一组编译选项。 Debug 版本 参数含义 /MDd /MLd 或/MTd 使用Debug runtime library(调试版本的运行时刻函数库) /Od 关闭优化开关 /D "_DEBUG" 相当于#define _DEBUG,打开编译调试代码开关(主要针对assert函数) /ZI 创建Edit and continue(编辑继续)数据库,这样在调试过程中如果修改了源代码不需重新编译 GZ 可以帮助捕获内存错误 Release 版本参数含义 /MD /ML 或/MT 使用发布版本的运行时刻函数库 /O1 或/O2 优化开关,使程序最小或最快 /D "NDEBUG" 关闭条件编译调试代码开关(即不编译assert函数) /GF 合并重复的字符串,并将字符串常量放到只读内存,防止被修改 Debug 和Release 并没有本质的界限,他们只是一组编译选项的集合,编译器只是按照预定的选项行动。

实验一 DEBUG的使用

实验一 DEBUG的使用 实验目的: 1.学习使用DEBUG程序的各种命令。 2.掌握8088/86指令系统---算数指令。 3.掌握用DEBUG调试自编程序的方法。 4.掌握8088/8086 CPU寄存器的用途和存储器组织及它们之间的关系。 5.掌握内存操作数及寻址方法。 6.掌握汇编语言伪操作:BYTE PTR,WORD PTR。 内容及步骤: 一、DEBUG 命令使用: 1、敲 DEBUG 进入 DEBUG 环境,显示提示符 '_ '。 2、用命令 D100 10F 观察内存中的16进制码及屏幕右边的ASCII字符。 3、用命令 E100 30 31 32 …… 3F 将30H~3FH写入地址为100H开始的内存单元中, 再用D命令观察结果,看键入的16进制数是什么字符的ASCII码? 4、用命令 F100 10F 'A' 将'A'的ASCII码填入内存,用D命令查看结果。 5、用命令 F110 11F 41 将41H 填入内存,用D命令观察结果并比较。 6、用R 命令检查各寄存器内容,特别注意AX,BX,CX,DX,IP及标志位中ZF,CF和AF的内 容。 7、用R命令将AX,BX内容改写为1234H及5678H。 8、用H命令检查下列各组16进制数加减结果并和你的手算结果比较: (1)34H,22H (2)56H,78H (3)A5,79H (4)1284H,5678H (5)A758,347FH 二、8088常用指令练习 1、传送指令 1)用A命令在内存100H处键入下列内容: MOV AX,1234 MOV BX,5678 XCHG AX,BX MOV AH,34 MOV AL,56 MOV CX,75AB XCHG AX,CX 2)用U命令检查键入的程序,特别注意左边的机器码。 3)用T命令逐条运行这些指令,每运行一行检查并记录有关寄存器及IP的变化情况。并注意标志位有无变化。 2、加减法指令: 1)用A命令在内存200H处键入下列内容:

如何把VS2008上编的debug、release程序在没装VS的xp机器上运行

如何把VS2008上编的debug、release程序在没装VS的xp机器上运 行 用VS2008 SP编写的MFC程序,拷贝到其他没装VS2008的机器上直接运行,肯定是不行的。即使选择静态链接MFC,有时候系统还是会提示“应用程序配置不正确”。这是因为程序中可能不止用到了9.0版本MFC,还可能有ATL、CRT、OPENMP等。在自己的机器上运行时,系统会到"C:\WINDOWS\WinSxS\"文件夹查找相应的库,这个文件夹里包含了所有安装过的版本的运行库和清单文件。如果只找9.0版本的库和清单文件,也可以到"C:\Program Files\Microsoft Visual Studio 9.0\VC\redist\x86"这个文件夹。 对于只用到Release库程序: 拷贝需要的库和清单文件到exe所在目录,修改程序的清单文件,再移植就可以运行了。修改的方法是:用Release方式编译链接程序,然后修改xxx.exe.intermediate.manifest,将其中name为Microsoft.VC90.CRT、Microsoft.VC90.MFC等的dependency块删掉,生成(不是重新生成!)项目,VS会把清单文件重新嵌入到程序中。这样,到了目标机器上,系统就不会按照清单文件到WinSxS文件夹去查找库(当它找不到时,就会提示“配置错误”。从“事件查看器”中,会看到加载失败的信息),而是到了该加载时才从工作目录查找。网上很多说法都提到了拷贝dll和manifest,但如果不修改程序中嵌入的manifest的话,拷贝了也是没用的。 另外一个不需要修改清单文件的办法,是下载Microsoft Visual C++ 2008 Redistributable Package,只有几兆,到目标机器上安装就可以了。这是vcredist_x86 for VS2008 的下载地址: https://www.360docs.net/doc/613043934.html,/downloads/details.aspx?FamilyID=9b2da534-3e03-4391-8a4d-074b9f 2bc1bf&displaylang=en 这是vcredist_x86 for VS2008 SP1的下载地址: https://www.360docs.net/doc/613043934.html,/downloads/details.aspx?familyid=A5C84275-3B97-4AB7-A40D-3802B 2AF5FC2&displaylang=en 两个安装程序的版本略有差别。 当然,如果只用到了9.0版的MFC,只要选择“在静态库中使用MFC”,就可以运行了。 对于用到Debug库程序: 如果你的程序用到了Debug版的运行库,那么上述库是不能解决问题的,因为它们都是Release版。可以到"C:\WINDOWS\WinSxS\",把用到的文件夹拷贝到目标机器的WinSxS中。不过我用的仍是修改清单文件的办法:从"C:\Program Files\Microsoft Visual Studio

常用Linux系统Debug命令

常用Linux系统Debug命令 常用Linux系统Debug命令 命令系统,是一种计算机代码控制系统。常用Linux系统Debug 命令有哪些呢?下面是相关的知识,欢迎阅读。 1、查看TCP连接状态 netstat-nat|awk'{print$6}'|sort|uniq-c|sort-rn netstat- n|awk'/^tcp/{++S[$NF]};END{for(ainS)printa,S[a]}' netstat- n|awk'/^tcp/{++state[$NF]};END{for(keyinstate)printkey,"",s tate[key]}' netstat- n|awk'/^tcp/{++arr[$NF]};END{for(kinarr)printk,"",arr[k]}' netstat-n|awk'/^tcp/{print$NF}'|sort|uniq-c|sort-rn netstat-ant|awk'{print$NF}'|grep-v'[a-z]'|sort|uniq-c netstat-nat|awk'{print$6}'|sort|uniq-c|sort-rn netstat- n|awk'/^tcp/{++S[$NF]};END{for(ainS)printa,S[a]}' netstat- n|awk'/^tcp/{++state[$NF]};END{for(keyinstate)printkey,"",s tate[key]}' netstat- n|awk'/^tcp/{++arr[$NF]};END{for(kinarr)printk,"",arr[k]}' netstat-n|awk'/^tcp/{print$NF}'|sort|uniq-c|sort-rn

实验一--掌握DEBUG-的基本命令及其功能

实验一掌握DEBUG 基本命令及其功能【上篇】查看CPU和内存,用机器指令和汇编指令编程 一.实验目的: 掌握DEBUG 的基本命令及其功能 掌握win7 win8 使用DEBUG功能 二.实验内容: 1. 预备知识:Debug的使用 (1) 什么是Debug? Debug是DOS、Windows都提供的实模式(8086方式)程序的调试工具。使用它,可以查看CPU各种寄存器中的内容、内存的情况和在机器码级跟踪程序的运行。 (2) 我们用到的Debug功能 ●用Debug的R命令查看、改变CPU寄存器的内容; ●用Debug的D命令查看内存中的内容; ●用Debug的E命令改写内存中的内容; ●用Debug的U命令将内存中的机器指令翻译成汇编指令; ●用Debug的T命令执行一条机器指令; ●用Debug的A命令以汇编指令的格式在内存中写入一条机器指令。 (3) 进入Debug Debug是在DOS方式下使用的程序。我们在进入Debug前,应先进入到DOS方式。用以下方式可以进入DOS: ①重新启动计算机,进入DOS方式,此时进入的是实模式的DOS。 ②在Windows中进入DOS方式,此时进入的是虚拟8086模式的DOS。 三.实验任务 1. 从网上下载Dosbox和debug.exe(文件夹中有)。 2. debug.exe放在D:根目录,然后安装,安装完成以后,点击快捷方式进入Dos界面:

3.输入mount c d:\ 接着输入c: Dosbox 5.接着,你就可以使用Debug: debug 6.备注:debug.exe放在D:根目录下,你也可以把debug.exe放在任何一个文件夹下面。 其中这个文件夹就是mount c d:所对应的。 一.(1) 使用Debug,将下面的程序段写入内存,逐条执行,观察每条指令执行后,CPU 中相关寄存器中内容的变化。(逐条执行,每条指令执行结果截图) 机器码汇编指令 b8 20 4e mov ax,4E20H 05 16 14 add ax,1416H bb 00 20 mov bx,2000H 01 d8 add ax,bx 89 c3 mov bx,ax

终端软件版本管理规范

文件编码AQ2I-01-S003 版本V01 文件层级□一阶□二阶 ■三阶 文件类别 ■体系文件 □技术文件 编制部门T终端部机密等级■内文□秘密□机密□绝密 编制人熊红旺文件类别■通用□项目 审核何天翼编制日期2017.6.15 审批何天翼生效日期2017.6.20 总页数7 分发编号01 文件发布盖章 终端软件版本管理规范

文件制/修订记录 页码章节制/修订记录 版本 修订人修订日期备注修订前修订后 全部首次制定无V01 熊红旺2017.6.20

目录 1.概述 (4) 2.软件版本的分类 (4) 3.软件版本的使用流程和规则 (4) 3.1测试部测试版本、预封版版本、封版版本使用流程和规则 (5) 3.2生产线软件版本使用规则 (6) 4.软件版本的发布流程和规则 (6) 5.软件版本标识规则 (6) 5.1软件版本号命名规则 (6) 5.1.1关于软件版本唯一标识的说明 (7) 5.1.2测试部测试版本的软件版本号 (7) 5.1.3预封版版本的软件版本号 (7) 5.1.4封版版本的软件版本号 (8) 5.1.5回归验证版本的软件版本号 (8) 5.1.6特殊版本的软件版本号 (8) 5.2版本文件夹命名规则 (8) 5.2.1正式发布版本文件夹命名规则 (8) 5.2.2回归测试版文件夹命名规则 (8) 5.3版本发布邮件通知的内容和格式 (9) 5.3.1正式发布版本邮件通知的内容和格式 (9)

5.3.2回归测试版本邮件通知的内容和格式 (9) 5.4版本说明的内容和格式 (10) 5.4.1正式发布版本说明的内容和格式 (10) 5.4.2回归测试版本说明的内容和格式 (10)

掌握DEBUG基本命令

实验课程名称微型计算机原理实验报告_实验项目名称掌握DEBUG基本命令_专业班级电子信息科学与技术101班_学生姓名____________ 学号_____ 实验成绩 指导教师签字

贵 州 大 学 实 验 报 告 纸 系 别 班 级 姓 名 学号 课 程 名 称 成 绩 评 定 教师签名 实 验 时 间 2011年 11 月 23 日 一、实验目的 (1)熟悉DEBUG 有关命令的使用方法。 (2)利用DEBUG 掌握有关指令的功能。 (3)利用DEBUG 运行简单的程序段。 二、实验内容 Ⅰ.掌握DEBUG 程序的各种命令,重点掌握U ,G ,T ,D ,E ,R 命令。 ⒈ 反汇编命令:-U[地址] 该命令从指定地址开始,反汇编32个字节,若地址省略,则从上一个U 命令的最后一条指令的下一个单元开始显示32个字节。

⒉运行命令G: ⒊追踪命令T,有两种格式: 1)逐条指令追踪:-T[=地址] 该命令从指定地址起执行一条指令后停下来,显示寄存器内容和状态值。 2)多条指令追踪: -T[=地址][值] 该命令从指定地址起执行n条命令后停下来,n由[值]确定。 ⒋显示内存单元内容的命令D,格式为: -D[地址]或-D[范围] 1)D命令后跟寄存器表示的地址 2)D命令后不加地址

3)D命令后加直接地址 ⒌修改内存单元内容的命令E,用给定的内容代替指定范围的单元内容: -E地址内容表 6.检查和修改寄存器内容的命令R,它有三种方式: 1)显示CPU内部所有寄存器内容和标志位状态;格式为:-R 2)显示和修改某个指定寄存器内容,格式为:-R 寄存器名 3)显示和修改标志位状态,命令格式为:-RF

VC如何releas调试

首先必须明确的是,什么是Release版程序,什么是Debug版程序 Debug通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。Release称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。 Debug 和Release 的真正秘密,在于一组编译选项。下面列出了分别针对二者的选项(当然除此之外还有其他一些,如/Fd /Fo,但区别并不重要,通常他们也不会引起Release 版错误,在此不讨论) Debug 版本 参数含义 /MDd /MLd 或/MTd 使用Debug runtime library (调试版本的运行时刻函数库) /Od 关闭优化开关 /D "_DEBUG" 相当于#define _DEBUG,打开编译调试代码开关(主要针对assert函数) /ZI 创建Edit and continue(编辑继续)数据库,这样在调试过程中如果修改了源代码不需重新编译 /GZ 可以帮助捕获内存错误 /Gm 打开最小化重链接开关,减少链接时间 Release 版本 参数含义 /MD /ML 或/MT 使用发布版本的运行时刻函数库 /O1 或/O2 优化开关,使程序最小或最快 /D "NDEBUG" 关闭条件编译调试代码开关(即不编译assert函数) /GF 合并重复的字符串,并将字符串常量放到只读内存,防止被修改

实际上,Debug 和Release 并没有本质的界限,他们只是一组编译选项的集合,编译器只是按照预定的选项行动。事实上,我们甚至可以修改这些选项,从而得到优化过的调试版本或是带跟踪语句的发布版本。 OK,知道了这些,谁还会说RELEASE版本不能调试? 只需要设置相应编译环境,RELEASE同样可以像DEBUG版本设置断点,查看参数。 步骤如下: 1、在Project Settings里选Settings For为All Configurations。 2、在C/C++标签中,Debug info 选Program Database。 3、在Link 标签中,Category选Debug,选中Debug info 复选框和Microsoft format。 现在就可以像在Debug版本中那样设置断点进行测试了,但是记住,Release版本由于代码优化,有些变量是观察不到的,行的运行顺序可能也会不同。 还有一种就是使用debugview.exe进行调试(https://www.360docs.net/doc/613043934.html,),这个是个好东西。 debugview.exe是用来显示debug信息的,而这个debug信息就是由我们自己的application所发出的。我们可以看msdn上的关于debug的那些函数,一个比较有用的函数是OutputDebugString(LPCTSTR msg)。用这个函数,我们就可以把调试信息往外发出,而debugview.exe就可以接收到。 这其实是windows的一个机制,说起来也是很简单的东西,其实他们之间的交互就是一个4K 大小的share memory,

debug常见命令使用说明

五、DEBUG调试程序 DEBUG.EXE程序是专门为分析、研制和开发汇编语言程序而设计的一种调试工具,具有跟踪程序执行、观察中间运行结果、显示和修改寄存器或存储单元内容等多种功能。它能使程序设计人员或用户触及到机器内部,因此可以说它是80X86CPU的心灵窗口,也是我们学习汇编语言必须掌握的调试工具。 1)DEBUG程序使用 在DOS提示符下键入命令: C>DEBUG [盘符:][路径][文件名.EXE][参数1][参数2] 这时屏幕上出现DEBUG的提示符“-”,表示系统在DEBUG管理之下,此时可以用DEBUG 进行程序调试。若所有选项省略,仅把DEBUG装入内存,可对当前内存中的内容进行调试,或者再用N和L命令,从指定盘上装入要调试的程序;若命令行中有文件名,则DOS把DEBUG 程序调入内存后,再由DEBUG将指定的文件名装入内存。 2)DEBUG的常用命令 (1)汇编命令A 格式:A[起始地址] 功能:将输入源程序的指令汇编成目标代码并从指定地址单元开始存放。若缺省起始地址,则从当前CS:100地址开始存放。A命令按行汇编,主要是用于小段程序的汇编或对目标程序的修改。 (2)反汇编命令U 格式1:U[起始地址] 格式2:U[起始地址][结束地址|字节数] 功能:格式1从指定起始地址处开始将32个字节的目标代码转换成汇编指令形式,缺省起始地址,则从当前地址CS:IP开始。 格式2将指定范围的内存单元中的目标代码转换成汇编指令。 (3)显示、修改寄存器命令R 格式:R[寄存器名] 功能:若给出寄存器名,则显示该寄存器的内容并可进行修改。缺省寄存器名,则按以下格式显示所有寄存器的内容及当前值(不能修改)。 AX=0000 BX=0004 CX=0020 DX=0000 SP=0080 BP=0000 SI=0000 DI=0000 DS=3000 ES=23A0 CS=138E IP=0000 NV UP DI PL NZ NA PO NC 138E:0000 MOV AX,1234 -R AX ;输入命令 AX 0014 ;显示AX的内容 :;供修改,不修改按回车。 若对标志寄存器进行修改,输入:-RF 屏幕显示如下信息,分别表示OF、DF、IF、SF、ZF、AF、PF、CF的状态。 NV UP DI PL NZ NA PO NC 不修改按回车键。要修改需个别输入一个或多个此标志的相反值,再按回车键。R命令只能显示、修改16位寄存器。 (4)显示存储单元命令D 格式1:D[起始地址]

Visual Studio中的debug和release版本的区别

Visual Studio中的debug和release版本的区别 Debug通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。Release 称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。 Debug 和Release 的真正秘密,在于一组编译选项。下面列出了分别针对二者的选项(当然除此之外还有其他一些,如/Fd /Fo,但区别并不重要,通常他们也不会引起Release 版错误,在此不讨论) Debug 版本 参数含义 /MDd /MLd或/MTd使用Debug runtime library (调试版本的运行时刻函数库) /Od 关闭优化开关 /D "_DEBUG" 相当于#define _DEBUG,打开编译调试代码开关(主要针对assert函数) /ZI 创建Edit and continue(编辑继续)数据库,这样在调试过程中如果修改了源代码不需重新编译 /GZ 可以帮助捕获内存错误 /Gm打开最小化重链接开关,减少链接时间 Release 版本 参数含义 /MD /ML 或/MT 使用发布版本的运行时刻函数库 /O1 或/O2 优化开关,使程序最小或最快 /D "NDEBUG" 关闭条件编译调试代码开关(即不编译assert函数) /GF 合并重复的字符串,并将字符串常量放到只读内存,防止被修改 实际上,Debug 和Release 并没有本质的界限,他们只是一组编译选项的集合,编译器只是按照预定的选项行动。事实上,我们甚至可以修改这些选项,从而得到优化过的调试版本或是带跟踪语句的发布版本。 哪些情况下Release 版会出错 有了上面的介绍,我们再来逐个对照这些选项看看Release 版错误是怎样产生的 1、Runtime Library:链接哪种运行时刻函数库通常只对程序的性能产生影响。调试版本的Runtime Library 包含了调试信息,并采用了一些保护机制以帮助发现错误,因此性能不如发布版本。编译器提供的Runtime Library 通常很稳定,不会造成Release 版错误;倒是由于Debug 的Runtime Library 加强了对错误的检测,如堆内存分配,有时会出现Debug 有错但Release 正常的现象。应当指出的是,如果Debug 有错,即使Release 正常,程序肯定是有Bug 的,只不过可能是Release 版的某次运行没有表现出来而已。 2、优化:这是造成错误的主要原因,因为关闭优化时源程序基本上是直接翻译的,而打开优化后编译器会作出一系列假设。这类错误主要有以下几种: 1. 帧指针(Frame Pointer)省略(简称FPO):在函数调用过程中,所有调用信息(返回地址、参数)以及自动变量都是放在栈中的。若函数的声明与实现不同(参数、返回值、调用方式),就会产生错误,但Debug 方式下,栈的访问通过EBP 寄存器保存的地址实现,如果没有发生数组越界之类的错误(或是越界“不多”),函数通常能正常执行;Release 方式下,优化会省略EBP 栈基址指针,这样通过一个全局指针访问栈就会造成返回地址错误是程序崩溃。

引用 VC++ Debug和Release区别

引用VC++ Debug和Release区别 2009-12-17 09:53 -------------------------------------- 本文主要包含如下内容: 1. Debug 和 Release 编译方式的本质区别 2. 哪些情况下 Release 版会出错 2. 怎样"调试" Release 版的程序 -------------------------------------- 一、Debug 和 Release 编译方式的本质区别 Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。Release 称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。 Debug 和 Release 的真正秘密,在于一组编译选项。下面列出了分别针对二者的选项(当然除此之外还有其他一些,如/Fd /Fo,但区别并不重要,通常他们也不会引起 Rele ase 版错误,在此不讨论) Debug 版本: /MDd /MLd 或 /MTd 使用 Debug runtime library(调试版本的运行时刻函数库) /Od 关闭优化开关 /D "_DEBUG" 相当于 #define _DEBUG,打开编译调试代码开关(主要针对 assert函数) /ZI 创建 Edit and continue(编辑继续)数据库,这样在调试过 程中如果修改了源代码不需重新编译 /GZ 可以帮助捕获内存错误 /Gm 打开最小化重链接开关,减少链接时间 Release 版本: /MD /ML 或 /MT 使用发布版本的运行时刻函数库 /O1 或 /O2 优化开关,使程序最小或最快 /D "NDEBUG" 关闭条件编译调试代码开关(即不编译assert函数) /GF 合并重复的字符串,并将字符串常量放到只读内存,防止 被修改 实际上,Debug 和 Release 并没有本质的界限,他们只是一组编译选项的集合,编译 器只是按照预定的选项行动。事实上,我们甚至可以修改这些选项,从而得到优化过的调试版本或是带跟踪语句的发布版本。 二、哪些情况下 Release 版会出错

1DEBUG命令的功能及使用

实验一DEBUG命令的功能及使用 一实验目的 掌握汇编语言基本运行环境和熟悉DEBUG调试程序的命令。包括:学习使用指令,掌握常用的指令功能和简单程序设计;掌握DEBUG调试程序的命令,熟悉程序输入、存储器和CPU寄存器及标志位的检查方法,单步、断点、连续等运行程序的调试方法。 二实验内容 DEBUG的主要命令功能与格式 1.汇编命令A 格式:A [[<段寄存器名>/<段地址>:] <段内偏移>] 上式等价于: (1)A <段寄存器名>:<段内偏移> (2)A <段地址>:<段内偏移> (3)A <段内偏移> (4)A 功能:键入该命令后显示段地址和段内偏移并等待用户从键盘逐条键入汇编命令,逐条汇编成代码指令,顺序存放到段地址和段内偏移所指定的内存区域,直到显示下一地址时用户直接键入回车键返回到提示符“-”。 注:其中(1)用指定段寄存器的内容作段地址,(3)用CS的内容作段地址,(4)以CS:100作地址。以后命令中提及的各种‘地址’形式,均指(1)、(2)、(3)中A后的地址形式。 2.显示内存命令D 格式:D [<地址>/<范围>] 上式等价于: (1)D <地址> (2)D <范围> (3)D 功能:以两种形式显示指定范围的内存内容。一种形式为十六进制内容,一种形式为以相应字节的内容作为ASCII码的字符,对不可见字符以‘.’代替。 注:其中(1)以CS为段寄存器。(3)显示CS:100起始的一片内容。 3.修改内存命令E 格式:E <地址> [<单元内容表>] 上式等价于: (1)E <地址> (2)E <地址> <单元内容表>

其中<单元内容表>是以逗号分隔的十六进制数,或用’或”括起来的字符串,或者是二者的组合。 功能:(1)不断显示地址,可连续键入修改内容,直至新地址出现后键入回车Enter 为止。(2)将<单元内容表>逐一写入由<地址>开始的一片单元。 4.填充内存命令F 格式:F <范围> <单元内容表> 功能:将单元内容表中的值逐个填入指定范围,单元内容表中内容用完后重复使用。 例如:-F 5BC:200 L 10 B2,‘XYZ’,3C 5.执行命令G 格式:G [=<地址>[,<断点>]] 上式等价于: (1)G (2)G=<地址> (3)G=<地址>,<断点> 功能: 执行内存中的指令序列 注:(1)从CS:IP所指处开始执行 (2)从指定地址开始执行 (3)从指定地址开始执行,到断点自动停止。 6.内存搬家命令M 格式:M <源地址范围> <目标起始地址> 其中源及目标地址若仅输入偏移量,则隐含相对DS。 功能:把<源地址范围>中的内容顺序搬至<目标起始地址>起的一片连续单元。 例如:-M CS:100 110 600 把从CS:100起至CS:110止17个字节搬至DS:600至DS:610的一片单元。 7.结束DEBUG返回DOS命令Q 格式:Q 功能:返回DOS提示符下 8.显示修改寄存器命令R 格式:R [<寄存器名>] 上式等价于: (1)R (2)R <寄存器名> 功能:(1)显示当前所有寄存器内容,状态标志及将要执行的下一指令的地址,代码及汇编语句形式。其中对状态标志FLAG以每位的形式显示,见下表。

关于DEBUG和RELEASE的一些问题及解决方法

[release][版本][调试]release版本下调试正常运行exe出错 - VC/MFC / 基础类 10月 9th, 2010 by admin Posted in VC/MFC | No Comments ? 我做的一个调用dll的程序,在debug下调试和运行exe都正常 在release下调试也正常,但是直接运行release下的exe就会挂掉,请高人指点一下,到底是什么原因。 程序中有调用外部工具执行解压和压缩,因为没有使用多线程,在解压缩的时候会使主框架无响应,在这样的状态下进入调用dll的模块,然后程序执行一半就挂掉了,是不是和解压缩有关呢 ? 不会是跟路径有关吧?程序中使用的相对路径???跟路径无关,都是相对路径而且release下调试是通过的,能正常运行得出结果 但是,直接执行release下的exe文件就挂掉了,很奇怪运行就挂掉是指,没有响应?程序崩溃?程序直接消失? 没有响应的话,是某个地方阻塞掉了,可以根据程序流程来跟踪,看执行到哪里才没响应的. 程序崩溃的话,看看提示是什么,再跟踪程序流程. 程序直接消失的话,多半是栈溢出了.挂掉的时候attach process一下,再查看堆栈,可以定位出在哪个函数挂掉了。< < 很可能就是路径的问题 release调试的时候,可以设置工作目录,其他相对路径都是基于这个工作目录release运行的时候,工作目录应该是其所在的文件夹用几个messagebox调试的看看一定是路径问题!把dll放到release一份看看。把dll放到release 目录下,再直接运行exe文件试试.- - 路径不正确吧。一些指针变量未初始化?? 字节对齐方式不对??在PostMessage或者在SendMessage处查看,我也碰到这问题,就是这么解决的. 80%是相对路径,改成绝对路径试试 有没有考虑过权限的问题,调试的时候程序是有DEBUG权限的,直接运行是没有这么高的权限+看下库依赖问题 depends< 顶一个!< Tags: , release, 版本, 调试 [release][版本][VC/MFC]急!!~~release版本出现问题 - VC/MFC / 基础类

DEBUG命令使用及寻址方式使用

实验一 DEBUG命令使用及8088指令使用 一、实验目的 1、熟悉使用DEBUG命令 2、用DEBUG命令进行七种寻址方式的验证 二、DEBUG学习指导 DEBUG是专门为汇编语言设计的一种调试工具,它通过步进,设置断点等方式为汇编语言程序员提供了非常有效的调试手段。 1、DEBUG程序的启动在DOS提示符下,可键入命令:C>DEBUG[d:][path][文 件名][ 参数1][参数2] 其中文件名是被调试文件的名称,它须是执行文件(EXE),两个参数是运行被调试文件时所需要的命令参数,在DEBUG程序调入后,出现提示符“-”,此时,可键入所需的DEBUG命令。在启动DEBUG时,如果输入了文件名,则DEBUG程序把指定文件装入内存。用户可以通过DEBUG的命令对指定文件进行修改、显示和执行。如果没有文件名,则是以当前内存的内容工作,或者用命名命令和装入命令把需要的文件装入内存,然后再用DEBUG的命令进行修改、显示和执行。 2、DEBUG的主要命令 (1)汇编命令A,格式为:-A[地址] 该命令从指定地址开始允许输入汇编语句,把它们汇编成机器代码相继存放在从指定地址开始的存储器中。 (2)反汇编命令U,有两种格式: 1)-U[地址] 该命令从指定地址开始,反汇编32个字节,若地址省略,则从上一个U 命令的最后一条指令的下一个单元开始显示32个字节。 2)-U范围该命令对指定范围的内存单元进行反汇编,例如:-U 04BA:0100 0108或–U 04BA:0100 L9 此二命令是等效的。 (3)运行命令G,格式为:-G [=地址1][地址2[地址3。。。]] 其中地址1规定了运行起始地址,后面的若干地址均为断点地址。 (4)追踪命令T,有两种格式: 1)逐条指令追踪:-T[=地址] 该命令从指定地址起执行一条指令后停下来,显示寄存器内容和状态值。 2)多条指令追踪:-T[=地址][值] 该命令从指定地址起执行n条命令后停下来,n由[值]确定。 (5)显示内存单元内容的命令D,格式为:-D[地址]或-D[范围]

VC中release和debug的区别

Debug通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。Release称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。 Debug 和Release 的真正秘密,在于一组编译选项。下面列出了分别针对二者的选项(当然除此之外还有其他一些,如/Fd /Fo,但区别并不重要,通常他们也不会引起Release 版错误,在此不讨论) Debug 版本 参数含义 /MDd /MLd 或/MTd 使用Debug runtime library (调试版本的运行时刻函数库) /Od 关闭优化开关 /D "_DEBUG" 相当于#define _DEBUG,打开编译调试代码开关(主要针对assert函数) /ZI 创建Edit and continue(编辑继续)数据库,这样在调试过程中如果修改了源代码不需重新编译 /GZ 可以帮助捕获内存错误 /Gm 打开最小化重链接开关,减少链接时间 Release 版本 参数含义 /MD /ML 或/MT 使用发布版本的运行时刻函数库 /O1 或/O2 优化开关,使程序最小或最快 /D "NDEBUG" 关闭条件编译调试代码开关(即不编译assert函数) /GF 合并重复的字符串,并将字符串常量放到只读内存,防止被修改 实际上,Debug 和Release 并没有本质的界限,他们只是一组编译选项的集合,编译器只是按照预定的选项行动。事实上,我们甚至可以修改这些选项,从而得到优化过的调试版本或是带跟踪语句的发布版本。 哪些情况下Release 版会出错 有了上面的介绍,我们再来逐个对照这些选项看看Release 版错误是怎样产生的 1、Runtime Library:链接哪种运行时刻函数库通常只对程序的性能产生影响。调试版本的Runtime Library 包含了调试信息,并采用了一些保护机制以帮助发现错误,因此性能不如发布版本。编译器提供的Runtime Library 通常很稳定,不会造成Release 版错误;倒是由于Debug 的Runtime Library 加强了对错误的检测,如堆内存分配,有时会出现Debug 有错但Release 正常的现象。应当指出的是,如果Debug 有错,即使Release 正常,程序肯定是有Bug 的,只不过可能是Release 版的某次运行没有表现出来而已。

DEBUG的基本调试命令

实验一 DEBUG的基本调试命令 一、实验目的 1.熟悉Pentium微处理器指令系统和寻址方式 2.掌握DEBUG调试软件的基本命令、调试方法。 二、DEBUG调试软件介绍 DEBUG.EXE程序是专门为分析、研制和开发汇编语言程序而设计的一种调试工具,具有跟踪程序执行、观察中间运行结果、显示和修改寄存器或存储单元内容等多种功能。它能使程序设计人员或用户触及到机器内部,因此可以说它是80X86CPU的心灵窗口,也是我们学习汇编语言必须掌握的调试工具。WINDOWS操作系统安装时自带有DEBUG.EXE程序,不需另外安装。 1、DEBUG程序的使用 在DOS提示符下键入命令: C:\> DEBUG [盘符:][路径][文件名.EXE][参数1][参数2] 这时屏幕上出现DEBUG的提示符“-”,表示系统在DEBUG管理之下,此时可以用DEBUG 进行程序调试。若所有选项省略,仅把DEBUG装入内存,可对当前内存中的内容进行调试,或者再用N和L命令,从指定盘上装入要调试的程序;若命令行中有文件名,则DOS把DEBUG 程序调入内存后,再由DEBUG将指定的文件名装入内存。 2、DEBUG的常用命令 (1)汇编命令 A 格式:A [起始地址] 或 A ;每输入完一条指令,用回车键来确认。 功能:将输入源程序的指令汇编成目标代码并从指定地址单元开始存放。若缺省起始地址,则从当前CS:100 (段地址:偏移地址)地址开始存放。A命令是按行进行汇编,主要是用于小段程序的汇编或对目标程序的修改,具有检查错误的功能。如有错误,用^Error提示。然后重新输入正确命令即可。 注:DEBUG的A命令中数字部分输入的默认格式是16进制。如输入10,对于计算机而言,就是10H。另外A命令不支持标识符的输入。只能用准确的段地址:偏移地址来设置跳转的位置。 (2)反汇编命令 U 格式1:U [起始地址] 格式2:U [起始地址][结束地址|字节数] 功能:格式1从指定起始地址处开始固定将32个字节的目标代码转换成汇编指令形式,缺省起始地址,则从当前地址CS:IP开始。 格式2将指定范围的内存单元中的目标代码转换成汇编指令。 (3)显示、修改寄存器命令 R 格式:R[寄存器名]或R 功能:若给出寄存器名,则显示该寄存器的内容并可进行修改。缺省寄存器名,则按以下格式显示所有寄存器的内容及当前值(不能修改)。 AX=0000 BX=0004 CX=0020 DX=0000 SP=0080 BP=0000 SI=0000 DI=0000 DS=3000 ES=23A0 CS=138E IP=0000 NV UP DI PL NZ NA PO NC 138E:0000 MOV AX,1234 -R AX ;输入命令 AX 0014 ;显示AX的内容 : ;供修改,不修改按回车。 若对标志寄存器进行修改,输入:-RF 屏幕显示如下信息,分别表示OF、DF、IF、SF、ZF、AF、PF、CF的状态。 NV UP DI PL NZ NA PO NC 不修改按回车键。要修改需个别输入一个或多个此标志的相反值,再按回车键。R命令只能显示、修改16位寄存器。

相关文档
最新文档