精华内容
下载资源
问答
  • 最近学习ARM的汇编,但是ARM不像x86,可以很方便的调试。...Google了很久,又结合自己的实践,终于成功的调试了ARM的汇编此向对ARM嵌入式感兴趣的同学分享一下。 首先说明需要的工具 1. QEMU 
    http://blog.sina.com.cn/s/blog_59fd92c40100h4v2.html
    


    最近在学习ARM的汇编,但是ARM不像x86,可以很方便的调试。不过还好有虚拟机,而且还有GDB这样万能的调试器。Google了很久,又结合自己的实践,终于成功的调试了ARM的汇编,在此向对ARM嵌入式感兴趣的 同学 分享一下。

    首先说明需要的工具
    1. QEMU 
     这个模拟器不仅可以模拟x86,还可以模拟ARM和MIPS,可谓强大
    2. GDB(源代码)  不用说了,万能调试器,但是需要从源代码编译
    3. arm-linux交叉工具链  我用的是自己开发板配套的3.4版本,不过去www.uclinux.org随便下载一个就可以(不过貌似uclinux被**了……)

    先编译GDB,设置target为ARM平台:
    $ ./configure --target=arm-linux
    $ make

    OK,开始写汇编程序,sample代码很简单,给3个寄存器赋值,之后死循环。注意一定要死循环,否则的话会遇到非法指令或者未知指令。

    =======test.S========
    .globl _start
    _start:
      mov r0, #0
      mov r1, #1
      mov r2, #2
    loop:
      b loop
    =======EOF=========

    编译:
    $ ./arm-linx-as -o test.o test.S
    链接:
    $ ./arm-linux-ld -o test test.o
    此时可以用objdump查看test的内容:
    $ ./arm-linux-objdump -d test
    接下来就是调试了,用qemu启动gdb端口监听:
    $ qemu-arm -g 11111 test
    之后启动gdb,注意启动的时候要指明test,不能启动之后用file指定test(为什么不能不清楚,不过是试验结果):
    $ ./gdb /PATH_TO_TEST                                       注意这里的gdb不是系统的gdb,而是刚刚编译好的gdb
    (gdb) target remote localhost:11111                   设置目标为本机11111端口
    (gdb) disassemble                          反汇编
    (gdb) display /10i $pc-16                 这个命令是显示当前pc附近的10条指令,代替调试x86程序的list命令
    (gdb) si                                      si,不是s,是单步执行指令,如果是s的话就会执行到下一个标号处。类似的还有ni
    (gdb) info register                      嗯,这个就是查看寄存器的值啦~
    (gdb) x /16 0                             这个是查看0x00000000开始的16个字(32 bits per word)的内存信息

    差不多就知道这些了,有一个问题是不知道如何设置指令的断点,以后再试吧……

    现在可以边看书边动手实践了~  QEMU还支持Thumb指令集和Jazelle指令集,应该都可以这样调试的
    <script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
    阅读(888) | 评论(0) | 转发(1) |
    给主人留下些什么吧!~~
    评论热议
    展开全文
  • 2.熟悉PC机上编辑、汇编、连接、调试和运行汇编语言程序的过程。 二.实验内容 一个汇编语言程序从写出到最终执行的简要过程如下: 1) 编辑 可以用任意的文本编辑器来编辑源程序,只要最终将其存储为纯文本文件...

    一.实验目的
    1.熟练掌握编写汇编语言原程序的基本框架
    2.熟悉在PC机上编辑、汇编、连接、调试和运行汇编语言程序的过程。
    二.实验内容
    一个汇编语言程序从写出到最终执行的简要过程如下:
    1) 编辑
    可以用任意的文本编辑器来编辑源程序,只要最终将其存储为纯文本文件即可。一般保存为*.asm文件。
    2) 编译
    上机过程中,我们采用微软的masm5.0汇编编译器,文件名为masm.exe。我们的编译器在C:\masm5目录下,可以按照下面的过程来进行源程序的编译,以C:\1.asm为例:
    进入DOS方式,进入C:\masm5目录,运行masm.exe,首先显示一些版本信息,然后提示输入将要被编译的源程序文件名。在输入源程序文件名时一定要指明路径,如果文件在当前路径下,只要输入文件名就可以,否则要输入全路径。在此,我们输入C:\1.asm.
    输入源程序文件名后,程序继续提示我们输入要编译出的目标文件名,因为我们已经输入了源程序文件名为1.asm,则编译程序默认要输出的目标文件名为1.obj,所以我们可以不必另行指定文件名,直接按回车,编译程序将在当前目录下,生出1.obj文件。我们也可以指定生成的目标文件所在的目录,如想在“C:\windows\desktop”下生成目标文件1.obj,则可以输入“C:\windows\desktop\1”
    确定了目标文件名称后,编译程序提示输入列表文件名称和交叉引用文件名称,这些时编译器将源程序编译为目标文件过程中产生的中间结果,我们直接按回车键忽略。
    对源程序编译结束,编译器输出的最后两行告诉我们源程序是否有警告错误和必须要改正的错误。
    3) 链接
    对源程序进行编译得到目标文件后,需要对目标文件进行链接得到可执行文件。
    我们使用微软的Overlay Linker3.6连接器,文件名为link.exe,假设连接器在C:\masm5目录下,我们按照下面的过程来进行程序的链接,以C:\masm5\1.obj为例
    进入DOS方式,进入C:\masm5目录,运行link.exe,首先显示一些版本信息,然后提示输入将要被连接的目标文件名。此处我们输入”1”,按回车.程序继续提示我们输入要生成的可执行文件的名称,这是我们对一个程序进行连接要得到的最终结果。这里我们不必另行指定文件名,直接按回车,链接程序将在当前目录下,生成1.exe文件。
    确定了可执行文件的名称后,连接程序提示输入映像文件的名称和库文件的连接,我们直接按回车键忽略即可。
    最后对目标文件的连接结束,连接程序输出的最后一行告诉我们源程序是否有错误。如果尽出现一个警告错误:“没有栈段”,我们可以不理会。
    4) 执行和调试
    将生成的可执行文件执行:C:\masm5>1.exe,看不到任何结果,因为我们的程序没有向显示器输出信息。
    为了观察程序的运行过程,使用Debug的相关命令来单步执行程序,查看每一条指令的运行结果。
    进入C:\masm5后,我们输入“Debug 1.exe”,按Enter键,Debug将程序从1.exe中加载到内存,进行相关的初始化后设置CS:IP指向程序的入口。使用R命令查看各个寄存器的设置情况,使用U命令来查看我们写入的指令,使用T命令单步执行程序中的每一条指令,到达int 21,使用P命令执行,执行后,显示“Program terminated normally”,返回到Debug,表示程序正常结束。
    注意:在DOS中运行程序时,是Command将程序加载到内存,所以程序运行结束后返回到command中,而在这里是debug将程序加载到内存,所以程序运行结束后返回到debug中。
    三.实验任务

    1. 将下面的程序保存为t1.asm文件,生成可执行文件t1.exe;
      assume cs:codesg
      codesg segment
      mov ax,2000h
      mov ss,ax
      mov sp,0
      add sp,4
      pop ax
      pop bx
      push ax
      push bx
      pop ax
      pop bx
      mov ax,4c00h
      int 21h
      codesg ends
      end

    记录第一次出错:没有把t1.asm文件放在MASM611的BIN文件下。放入之后出现“Assembling:t1.asm”.
    在这里插入图片描述
    小结:汇编语言程序的汇编以及建立过程:
    编辑程序生成asm文件(t1.asm)——>汇编程序(masm t1.asm),将asm文件转换成ti.obj文件——>用LINK程序把obj文件转换成exe文件(link t1.obj)——>最后一步执行可以选择直接执行也可以选择使用debug命令单步执行

    1. 用Debug跟踪t1.exe的执行过程,写出每一步执行后相关寄存器中的内容
      在这里插入图片描述

    在这里插入图片描述

    1. PSP的前两个字节是CD 20,用Debug加载t1.exe,查看PSP的内容
      PSP的具体功能以及用法将会在后面的实验中逐渐提到,在这里可以先提前了解一下,这里的PSP是程序段前缀,这里的CD20是INT20h的机器码,可以先了解到这里,我会用一篇专门的博客来解释psp。在这里插入图片描述
      四.实验报告
      调试说明。包括上机调试的情况、上机调试步骤、调试所遇到的问题是如何解决的,并对调试过程中的问题进行分析,对执行结果进行分析。
    展开全文
  • DEBUG命令 调试 汇编语言程序

    千次阅读 2012-09-19 12:57:46
    DE BUG命令 调试 汇编语言程序   转载▼ 一.如何启动debug命令?... 运行栏里键入: ... 调试 汇编语言程序" title="DEBUG命令 调试 汇编语言程序" style="margin:0px; padd

    DE

    BUG命令 调试 汇编语言程序

     

    一.如何启动debug命令?

     在运行栏里键入:

     debug

     如果不出现黑色命令窗口。则键入:

     c:/windows/system32/debug

     DEBUG命令 <wbr>调试 <wbr>汇编语言程序

    即出现debug命令窗口,如下图

    DEBUG命令 <wbr>调试 <wbr>汇编语言程序

    另一种方法启动debug是:

    按 开始->程序->命令指示符

    在里面键入debug后,按回车

    DEBUG命令 <wbr>调试 <wbr>汇编语言程序

    按回车后弹出debug命令窗口,如下

    DEBUG命令 <wbr>调试 <wbr>汇编语言程序

     

    二,debug的主要命令

     

       1,显示修改寄存器命令R    (Register)

          R;★显示所有寄存器和标志位状态;

             ★显示当前CS:IP指向的指令。

              

           标志                   标志=1         标志=0

            OF                      OV                NV

            DF                      DN                UP

            IF                      EI                DI

            SF                      NG                PL

            ZF                      ZR                NZ

            AF                      AC                NA

            PF                      PE                PO

            CF                      CY                NC

     

    DEBUG命令 <wbr>调试 <wbr>汇编语言程序

     

      2,汇编命令A  (Assemble)

           A [地址];从指定的地址开始输入符号指令;如省略地址,则接着上一个A命令的最后一个单元开始;若第一次使用A命令省略地址,则从当前CS:IP开始(通常是CS:100)。

           注释:①在DEBUG下编写简单程序即使用A命令。

           ②每条指令后要按回车。

           ③不输入指令按回车,或按Ctrl+C结束汇编。

           ④支持所有8086符号硬指令,伪指令只支持DB、DW,不支持各类符号名。

     

      3.运行程序命令G   (Go)

           ① G;从CS:IP指向的指令开始执行程序,直到程序结束或遇到INT 3。

           ② G=地址;从指定地址开始执行程序,直到程序结束或遇到INT 3。

           ③ G 断点1[,断点2,…断点10];从CS:IP指向的指令开始执行程序,直到遇到断点。

           ④G=地址 断点1[,断点2,…断点10]

        -G ;从CS:IP指向的指令开始执行程序。

        -G=0100 ;从指定地址开始执行程序。

        -G=0100 0104

    DEBUG命令 <wbr>调试 <wbr>汇编语言程序

     

    4.反汇编命令  U   (Unassemble)

    反汇编字节并显示相应的原语句,其中包括地址和字节值。反汇编代码看起来象已汇编文件的列表。
    u [range]
    参数

    如果在没有参数的情况下使用,则 u 命令分解 20h 字节(默认值),从前面 u 命令所显示地址后的第一个地址开始。
    range
    指定要反汇编代码的起始地址和结束地址,或起始地址和长度。 
    有关显示内存部分内容的信息,请参看Debug D(转储)。
    范例
    要反汇编 16 (10h) 字节,从地址 04BA:0100 开始,请键入以下命令:
    u04ba:10l0

    DEBUG命令 <wbr>调试 <wbr>汇编语言程序

     

    5.内存16进制表示 D     (Dump)

    显示一定范围内存地址的内容。
    d [range]
    参数
    range
    指定要显示其内容的内存区域的起始和结束地址,或起始地址和长度。如果不指定 range,Debug 程序将从以前 d 命令中所指定的地址范围的末尾开始显示 128 个字节的内容。
    有关显示寄存器内容的信息,请参看Debug R(寄存器)。
    说明
    当使用 d 命令时,Debug 以两个部分显示内存内容:十六进制部分(每个字节的值都用十六进制格式表示)和 ASCII 码部分(每个字节的值都用 ASCII 码字符表示)。每个非打印字符在显示的 ASCII 部分由句号 (.) 表示。每个显示行显示 16 字节的内容,第 8 字节和第 9 字节之间有一个连字符。每个显示行从 16 字节的边界上开始。
    范例
    假定键入以下命令:
    dcs:100 10f
    Debug 按以下格式显示范围中的内容:
    04BA:0100 54 4F 4D 00 53 41 57 59-45 52 00 00 00 00 00 00 TOM.SAWYER......
    如果在没有参数的情况下键入 d 命令,Debug 按以前范例中所描述的内容来编排显示格式。显示的每行以比前一行的地址大 16 个字节(如果是显示 40 列的屏幕,则为 8 个字节)的地址开头。
    对于后面键入的每个不带参数的 d 命令,Debug 将紧接在最后显示的命令后立即显示字节内容。
    如果键入以下命令,Debug 将从 CS:100 开始显示 20h 个字节的内容:
    dcs:100 l 20
    如果键入以下命令,Debug 将显示范围从 CS 段的 100h 到 115h 中所有字节的内容:
    dcs:100 115

    DEBUG命令 <wbr>调试 <wbr>汇编语言程序

    DEBUG命令 <wbr>调试 <wbr>汇编语言程序

     

    6.修改内存字节 E      (Enter)

    将数据输入到内存中指定的地址。
    可以按十六进制或 ASCII 格式键入数据。以前存储在指定位置的任何数据全部丢失。
    e address [list]
    参数
    address
    指定输入数据的第一个内存位置。

    DEBUG命令 <wbr>调试 <wbr>汇编语言程序
    list
    指定要输入到内存的连续字节中的数据。
    有关集成记忆码的信息,请参看Debug A(汇编)。
    有关显示内存部分内容的信息,请参看Debug D (转储)。
    说明
    使用 address 参数
    如果在没有指定可选的 list 参数的值情况下指定 address 的值,Debug 将显示地址和内容,在下一行重复地址,并等待您的输入。此时,您可以执行下列操作之一:
    替换字节值。为此,请在当前值后键入新值。如果您键入的值不是有效的十六进制值,或该值包含两个以上的数字,则 Debug 不会回显无效或额外的字符。
    进入下一个字节。为此,请按 SPACEBAR(空格键)。要更改该字节中的值,请在当前值后键入新值。如果按 SPACEBAR(空格键)时,移动超过了 8 位界限,Debug 程序将显示新的一行并在行首显示新地址。
    返回到前一个字节。为此,请按 HYPHEN 键 (-)。可以反复按 HYPHEN 键 (-) 向后移动超过多个字节。在按 HYPHEN 时,Debug 开始新行并显示当前地址和字节值。
    停止执行 e 命令。为此,请按 ENTER 键。在任何字节位置都可以按 ENTER。
    使用 list 参数
    如果指定 list 参数的值,随后的 e 命令将使用列表中的值替换现有的字节值。如果发生错误,将不更改任何字节值。
    List 值可以是十六进制字节或字符串。使用空格、逗号或制表符来分隔值。必须将字符串包括在单或双引号中。
    范例
    假定键入以下命令:
    ecs:100
    Debug 按下面的格式显示第一个字节的内容:
    04BA:0100 EB.
    要将该值更改为 41,请在插入点键入 41,如下所示:
    04BA:0100 EB.41_
    可以用一个 e 命令键入连续的字节值。在键入新值后按 SPACEBAR(空格键),而不是按 ENTER 键。Debug 显示下一个值。在此范例中,如果按三次 SPACEBAR(空格键),Debug 将显示下面的值:
    04BA:0100 EB.41 10. 00. BC._
    要将十六进制值 BC 更改为 42,请在插入点键入 42,如下所示:
    04BA:0100 EB.41 10. 00. BC.42_
    假定决定值 10 应该是 6F。要纠正该值,请按 HYPHEN 键两次以返回到地址 0101(值 10)。Debug 显示以下内容:
    04BA:0100 EB.41 10. 00. BC.42-
    04BA:0102 00.-
    04BA:0101 10._
    在插入点键入 6f 更改值,如下所示:
    04BA:0101 10.6f_
    按 ENTER 停止 e 命令并返回到 Debug 提示符下。
    以下是字符串项的范例:
    eds:100 "This is the text example"
    该字符串将从 DS:100 开始填充 24 个字节

     

     7.  P: 循环或子程序处理(Procedure)
       格式:P[=地址] [命令数]
             地址:  执行的起始地址。
             指令数:执行的指令条数。
       用途:*循环或子程序处理。将循环、串指令、软件中断或子程序调用
             视为单语句。执行中了,显示目标程序寄存器内容、标志位状态
             和下一条要执行的指令。
             *若地址参数中无段址,则使用CS中的值。完全忽略地址时,则从
             程序中的CS:IP指定位置开始执行。

    DEBUG命令 <wbr>调试 <wbr>汇编语言程序


     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    退出debug程序   Q    (Quit)

     停止 Debug 会话,不保存当前测试的文件。
    当您键入 q 以后,控制返回到 DOS 的命令提示符。
    q
    参数
    该命令不带参数。   

     

    展开全文
  • 要好好掌握反汇编调试程序BUG

    千次阅读 2011-04-04 14:46:00
      备忘--通过反汇编定位release版本程序的bug所在 转自:http://blog.csdn.net/swordll80/archive/2007/01/06/1475847.aspx<br />  <br />今天帮忙调试了一个release版本的程序,此程序运行...

    没事的时候 用GOOGLE搜搜 反汇编调试,看看别人用反汇编调试的例子。

     

    备忘--通过反汇编定位release版本程序的bug所在

    转自:http://blog.csdn.net/swordll80/archive/2007/01/06/1475847.aspx

     

    今天帮忙调试了一个release版本的程序,此程序运行较长一段时间后终于(不挂就不好查了)挂了,系统报错是某处的指令访问了非法地址,显然是内存访问越界(不测试也能猜到,呵呵)。

    点击系统报错对话框的cancel,进入vc6的反汇编调试模式,定位到指令所在的汇编代码,将此指令所在函数(函数以0x10对齐,结尾一般都有nop指令)的所有汇编代码拷贝出来分析。搜索cmp指令,运气比较好,汇编代码中的cmp指令中有一些特殊值,搜索特殊值定位到了程序的一个函数(运气又特别好,是定位到了一个函数,而不是多个函数)。

    函数太长(500多行),只好继续分析,根据反汇编后的指令位置可以估计大概在此函数的2/3处有问题。结合c++代码和非法指令附近的asm代码,找到一个esp相关的临时量,可以肯定是函数内的栈上临时变量,这个变量在非法指令中×8,c++代码中有个POINT刚好大小就是8,非法指令中还+10h,于是可以猜测有这样一个POINT[i+2]操作越界。

    分析完毕。

    以前学asm主要是为了辅助理解系统、c/c++语言等,今天基本上是第一次用于查bug(我自己的程序基本上没多少bug,即是有我也能直接猜出来大概在哪,呵呵),感觉asm的知识所记不多,还是应该加强学习。

     

    C/C++程序内存地址出错查找方法简介

    转自:http://blog.csdn.net/wsy9805/archive/2009/05/20/4200043.aspx

     

    很多时候,我们写的程序都会出现程序的非法推出,如果程序很大,此类错误非常难查,下面介绍两种方法,从错误的内存地址反向查找出问题的程序:

    <1>.通过汇编去查找.
    linux 平台:
      1. 在程序信号处理部分, 加入代码捕捉引起错误点的地址,简单来说,方法就是在注册自己的信号处理函数,在这个函数中加入获取内存错误地址的代码,并把结果写到一个日志文件中。
      2. 编译 DEBUG 版本 程序 (compile 时用 -g , 生成可执行文件后不用 strip 去掉symbol 信息)
      3. 在程序出问题时, 查看日志记录, 得到错误点的地址.
      4. 用objdump -S 导出Debug 版本的汇编代码, 查找错误地址, 则得出那条语句出错.
    windows 下c 语言调试
      1. release 版编译/连接选项, 把"generate debug info/" 打钩选择
      2.dumpbin /DISASM /OUT:dump.out.txt.1 prep.exe 可反编译exe文件
      3.得到程序非法地址(可从管理工具-》事件查看器里得到),与汇编比较。

    <2>.我个人比较常用的.主要是WINDOWS下的.以VC2003为例.

        1.打开工程的属性,在配置属性里面,选择链接器/调试.在右边的生成映射文件选择:是(/MAP)
    映射文件名:$(IntDir)/XXX.map.最后映射行选择:是(/MAPINFO:LINES).这样RELEASE编译的
    时候就会产生程序的MAP文件,在这个文件里面记录了程序各接口,函数的调用地址等.而最后
    选择的映射行则是对每个CPP文件都产生.cod文件,这里面记录了此CPP文件在内存中的地址
    映射.我们就是通过MAP文件和这些COD文件查找具体的出错位置.
    2.设置完了以上设置后,最好在程序里面写一个地址出错的LOG文件,方便程序出错的时候,可以
    查找出正确的位置.下面来说说具体的查找过程:
    如 你在执行一个程序的时候,报了内存错误,错误地址为:001B:00474A66.后面的00474A66就是
    它的出错地址.然后我们先打开该程序的MAP文件(一个程序一般只有一个MAP文件),接着在MAP
    文件中查找与00474A66最接近的地址是哪个,一定要找比它小一点的地址.因为MAP文件中记录的
    都是程序各函数的入口地址,所以这个00474A66一定是在某个地址与另一个地址之间.找到那个比
    出错地址小一点的入口地址后.在那个入口地址的那一行,你可以看到如:
    ?CheckCharName@CUnitSvrModule@@IAEHPBD@Z 004748e0 f i XXXX.obj.
    ?CheckCharName这是函数名.CUnitSvrModule这是类名.004758e0 这是入口地址.
    这个XXXX.obj就是出错的CPP文件,你再打开XXXX.COD这个文件,通过函数名去找到此函数的入口位置.
    如:
    ;COMDAT ?CheckCharName@CUnitSvrModule@@IAEHPBD@Z
    _TEXT SEGMENT
    __$EHRec$ = -12      ; size = 12
    _szNick$ = 8      ; size = 4
    _szNickName$ = 8     ; size = 4
    ?CheckCharName@CUnitSvrModule@@IAEHPBD@Z PROC NEAR ; CUnitSvrModule::CheckCharName, COMDAT
    ; _this$ = ecx
    如果看到这种形式.说明已经找到函数的代码执行处了,下面的内容就是此函数的汇编代码.你再根据
    上面的地址差找到具体在哪一行就行了. 地址差:= 00474A66(出错地址)-004748e0(入口地址).
    3.大致的查找过程就是这样.上面也已经说过了,在程序里面写一个内存出错的LOG文件很重要,这样方便
    程序员在事后维护的时候有据可查.而且编译之前一定要先设置映射文件及映射行.

     

     

    C语言反汇编入门实例

    转自:http://www.programlife.net/c-reverse-to-asm-demo.html

     

    看《天书夜读》第一章,感觉很亲切,于是自己动手操起VS,建立一个默认的Win32 Console Application,在一个空空的main函数里面F9下一个断点之后,按下F5进入调试,然后Alt+8进入反汇编查看窗口,代码如下,自己给他加了点注释,还是很浅显的东西。这里的是Debug模式的反汇编代码:(博客对ASM代码注释的显示颜色不好看,大家将就一下)陌生的指令可能是stos,大家可以自己去Google查一下加深了解;通过仔细阅读这个例子,相信读者们当初学习汇编的场景已经跃然眼前了。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    
    --- d:/my documents/visual studio 2008/projects/first/first/first.cpp ----------
    // First.cpp : 定义控制台应用程序的入口点。
    //
     
    #include "stdafx.h"
     
     
    int _tmain(int argc, _TCHAR* argv[])
    {
    ;将ebp入栈,保存ebp
    00411370  push        ebp  
    ;将esp传送给ebp
    00411371  mov         ebp,esp 
    ;esp减去0C0h,开辟栈空间存放局部变量
    ;注意汇编语言中数字常量如果是字母开头必须加上0
    00411373  sub         esp,0C0h 
    ;保存常用的寄存器ebx,esi,edi
    00411379  push        ebx  
    0041137A  push        esi  
    0041137B  push        edi  
    ;将edi赋值为ebp-0C0h(lea取得偏移地址)
    0041137C  lea         edi,[ebp-0C0h] 
    ;30h放入ecx,为rep执行次数
    ;注意到30h * 4 = 0C0h
    00411382  mov         ecx,30h
    ;0CCCCCCCCh为系统中断int 3h
    00411387  mov         eax,0CCCCCCCCh 
    ;用int 3h填充开辟的栈空间
    0041138C  rep stos    dword ptr es:[edi] 
     
    	return 1;
    ;返回1,是通过eax寄存器返回的
    0041138E  mov         eax,1 
    }
    ;恢复寄存器ebx,esi,edi
    00411393  pop         edi  
    00411394  pop         esi  
    00411395  pop         ebx 
    ;用ebp恢复函数调用前的栈指针esp 
    00411396  mov         esp,ebp 
    ;恢复ebp
    00411398  pop         ebp 
    ;返回 
    00411399  ret

     

    C++代码和调试

    转自:http://bbs.loveunix.net/viewthread.php?tid=3686


    本部分教程主要介绍了良好的C++代码风格、如何书写安全的代码以及在Visual C++环境下的程序调试技术,这些内容对于新员工从学生成长为真正的程序员,逐步参与实际项目的开发工作,以及阅读第三方代码非常重要。

    1 规范易懂的代码

    现阶段软件开发,都要依靠团队的合作。程序员不再是个人英雄主义的代名词,程序员一方面要依赖大量其他程序员完成的代码,一方面又提供大量代码给其他人使用,代码实际上具备了两个要素:首先是可靠的提供某种功能,其次是清楚地表达作者的思想。任何交流都必须有一定的规范才能进行,体现在代码中就是规范易懂。另外,规范易懂的代码才是可重复使用的,规范的代码具有更长的寿命,具有更好的可维护性,也更方便后期的扩展。

    1.1 好代码的几个特征

    怎么样的代码才算规范易懂,体现在细节上会有无数的争论,实际上无论风格和习惯如何,好的代码具有几个共同的特征:
    1. 良好的命名:好的变量名和函数名,让阅读代码的人马上就知道该变量或者函数的作用,很容易就能理解程序的大概结构和功能。程序员有必要理解匈牙利命名法。
    2. 一致性:一致性带来更好的程序,一致的代码缩进风格能够显示出代码的结构,采用何种缩进风格并不重要,实际上,特定的代码风格远没有一致的使用它们重要。
    3. 注释:注释是帮助程序读者的一种手段,程序作者也是未来的程序读者之一。最好的注释是简洁地点明程序的突出特征,或是提供一种概观,帮助别人理解程序;但如果注释只是说明代码已经讲明的事情,或者与代码矛盾,或者以精心编排的形式迷惑干扰读者,那就是帮了倒忙。

    1.2 养成好习惯

    前面已经提过,特定的代码风格远没有一致的使用他们重要,所以,把过多的精力放到A or B的选择上是浪费时间,你要做的是坚持。如何书写规范易懂的代码,如何养成良好的习惯,下面是一些提示。

    1. 按照匈牙利命名法给变量和函数命名。
    2. 遵循国际流行的代码风格。
    3. 写代码的同时就遵循你的命名规范和书写风格,千万不能事后补救。
    4. 利用工具(Parasoft C++ Test)检查你的代码,评估一下自己形成良好的习惯没有。
    5. 坚持不懈直到养成习惯。

    2 编写安全可靠的代码

    在大型应用软件系统中,各个代码片段共同构成完整的系统,代码间的交互非常频繁,程序崩溃往往并不在错误发生的时候就发生,而是延迟了一段时间,经过数个函数之间的中转后才发生,此时定位和查找错误非常费时费力,如何才能及时反映程序中的错误,如何在代码中避免一些幼稚的语义错误呢?一个函数往往会被其他程序员拿来使用,但是他怎么能够正确的使用其他人编写的函数呢?这部分内容能够(部分)帮助解决这些问题。

    2.1 契约编程
    契约编程(Design by Contract)的思想在C++圣经级的著作,C++之父Bjarne Stroustrup的《C++程序设计语言》中略微提到过,OO领域的圣经级著作《面向对象软件构造》以大篇幅阐释了契约编程,现在越来越多的软件开发人员认识到契约编程的重要性,并逐步地在实际工作中采用契约编程。
    对契约编程简单的解释是:对实现的代码块(函数、类)通过规定调用条件(约束)和输出结果,在功能的实现者和调用者之间定义契约。
    具体到我们的工作,开发人员应该对完成的每个函数和类,定义契约。契约编程看似平淡无奇,对程序开发没有什么具体的帮助,实际上,契约编程在开发阶段就能够最大程度的保证软件的可靠性和安全性。
    在实际工作中,每当你需要使用其他程序员提供的模块,你并不知道如何调用,也不知道你传入的参数是否合法,有时候对于功能模块的处理结果也不敢相信。这些本来应该很明显的信息因为模块提供者没有显式的提供,造成了调用者只能忐忑不安的摸着石头过河,浪费了大量时间,而且为了让自己的代码更安全可靠,在代码中做了大量的判断和假设,造成代码结构的破坏和执行效率的损失,最后,调用者依旧不能确保自己的调用是正确的。
    而契约编程通过严格规定函数(或类)的行为,在功能提供者和调用者之间明确了相互的权利和义务,避免了上述情况的发生,保证了代码质量和软件质量。

    2.2 主动调试
    主动调试指在写代码的时候,通过加入适量的调试代码,帮助我们在软件错误发生的时候迅速弹出消息框,告知开发人员错误发生地点,并中止程序。这些调试代码只在Debug版中有效,当经过充分测试,发布Release版程序的时候,这些调试代码自动失效。
    主动调试和契约编程相辅相成,共同保证软件开发的质量。契约编程相当于经济生活中签订的各种合同,而主动调试相当于某方不遵守合同时采取的法律惩罚措施。
    各种开发语言和开发工具都提供这些调试语句,标准C++提供了assert函数,MFC提供了ASSERT调试宏帮助我们进行主动调试,在实际工作中,建议统一使用MFC的ASSERT调试宏。

    2.2.1 参数检查
    对于编写的函数,除了明确的指定契约外,在函数开始处应该对传入的参数进行检查,确保非法参数传入时立即报告错误信息。例如:
    BOOL GetPathItem ( int i , LPTSTR szItem , int iLen )
    {
    ASSERT ( i > 0 ) ;
    ASSERT ( NULL != szItem ) ;
    ASSERT ( ( iLen > 0 ) && ( iLen < MAX_PATH ) ) ;
    ASSERT ( FALSE == IsBadWriteStringPtr ( szItem , iLen ) ) ;
    }
    对指针的检查尤其要注意,通常程序员会这样进行检查:
    // An example of checking only a part of the error condition
    BOOL EnumerateListItems ( PFNELCALLBACK pfnCallback )
    {
    ASSERT ( NULL != pfnCallback ) ;

    }
    这样的检查只能够排除指针为空的情况,但是如果指针指向的是非法地址,或者指针指向的对象并不是我们需要的类型,上面的例子就没有办法检查出来,而是统统认为是正确的。完整的检查应该如下:
    // An example of completely checking the error condition
    BOOL EnumerateListItems ( PFNELCALLBACK pfnCallback )
    {
    ASSERT ( FALSE == IsBadCodePtr ( pfnCallback ) ) ;
    }

    2.2.2 内部检查
    恰当地在代码中使用ASSERT,对bug检测和提高调试效率有极大的帮助,下面举个简单的例子加以说明。
    switch( nType )
    {
    case GK_ENTITY_POINT:
    // do something
    break;
    case GK_ENTITY_PLINE:
    // do something
    break;
    default:
    ASSERT( 0 );
    }

    在上面的例子中,switch语句仅仅处理了GK_ENTITY_POINT和GK_ENTITY_PLINE两种情况,应该是系统中当时只需要处理这两种情况,但是如果后期系统需要处理更多的情况,而此时上面这部分代码又没有及时更新,或者是因为开发人员一时疏忽遗漏了。一个可能导致系统错误或者崩溃的bug就出现了,而使用ASSERT可以及时地提醒开发人员他的疏忽,尽可能快的消灭这个bug。

    还有一些情况,在开发人员编写代码时,如果能够确信在某一点出现情况A就是错误的,那么就可以在该处加上ASSERT,排除情况A。

    综上所述,恰当、灵活的使用ASSERT进行主动调试,能够极大提高程序的稳定性和安全性,减少调试时间,提高工作效率。

    2.3 有用的代码风格
    一些好的代码风格也能够帮助你避免一些幼稚的、低级的错误,而这种错误又是很难检测到的。由于C++语言简洁灵活的特性,有时候敲错一个字符,或者漏敲一个字符,都有可能造成极大的灾难,而这种错误并不是随着你的编程水平和经验的提高就能逐步避免的,谁都会敲错字符,对吧。
    比如程序员经常将等于逻辑判断符==误敲成赋值运算符=,对于我来说就不太可能程序运行出错后才发现,因为我的习惯是,对于逻辑判断,将常量置于==的左边,如果我误输入了=,那么编译的时候编译器就会报错。
    if( INT_MAX == i )

    3 Visual C++调试技术
    检查代码直到头晕眼花也没有发现错误,一运行程序就死机,只好祭出最后的法宝:调试器。Visual C++调试器可以称得上Windows平台下最好的C/C++调试器了,而且Visual C++调试器还可以调试用其他语言如Delphi、Java编写的程序,可谓功能强大。
    尽管Visual C++调试器具有如此大的威力,它也只能帮助你发现一些隐藏的逻辑错误,对于程序设计和结构的缺陷无能为力。
    程序员最常用到的Visual C++调试技术有设置断点、跟踪调用堆栈和反汇编调试,其他编译器功能均为调试中的辅助工具,因为反汇编调试需要程序员具备汇编语言知识和语言底层结构,这里不再介绍。

    3.1 调试的先决条件
    专业调试者有一个共同的特点,即他们同时也是优秀的开发者。显然,如果你不是一个优秀的开发者,那么你也不可能成为调试专家,反之亦然。以下是要成为一名高水平的,至少是合格的调试者或者开发者所需要精通的领域。

    1. 了解项目:对项目的了解是防范用户界面、逻辑及性能方面的错误的第一要素。了解各种功能如何在各种源文件里实现,以及在哪儿实现,你就能够缩小查找范围,很快找出问题所在。
    2. 掌握语言:掌握项目所使用的语言,调试者(开发者)既要知道如何使用这些语言进行编程,还要知道这些语言在后台作些什么。
    3. 掌握技术:要解决棘手的问题,第一个重要步骤就是抓住所用技术的要领,这并不意味着你必须对所用技术的一切细节都一清二楚,而是说你应该对所使用的技术有一个大概的了解,而且更重要的是,当需要更详细的信息时,你应该确切的知道在哪儿查找。
    4. 操作系统和CPU:任何项目都实际运行在特定的操作系统和特定的CPU,对操作系统了解越多,对查找错误帮助越大;从理论上来说,掌握汇编语言,你就可以调试解决任何bug。

    无论从事什么工作,只要是经常从事技术工作的人,都必须不断地学习以跟上技术的发展,更不用说想干得更好或是想走在技术发展的前沿。经常阅读优秀的技术书籍和杂志,多动手编写一些实用程序,阅读其他优秀开发者的代码,作一些反汇编工作,都会有效帮助你提高开发和调试水平(尤其当你将这四者有机结合起来)。

    3.2 调试过程

    确定一个适用于解决所有错误的调试过程有一定的难度,但John Robbins提出的调试过程应该说是最实用的:
    1. 复制错误
    2. 描述错误
    3. 始终假定错误是自己的问题
    4. 分解并解决错误
    5. 进行有创见的思考
    6. 使用调试辅助工具
    7. 开始调试工作
    8. 校验错误已被更正
    9. 学习和交流

    对错误进行描述有助于改正错误,同时也能够得到同事们的帮助。逐步缩小问题范围、排除不存在错误的代码段,直到找到问题所在,是解决所有问题的普遍适用方法。有些奇怪的错误需要你把视线从代码堆转移到诸如操作系统、硬件环境等其他方面去。善用各种调试辅助工具能够节省你大量的时间,而且某些工具本身就不会给你犯有些错误的机会。当你解决了一个bug,停下来思考一下,什么导致你(或他)犯了这样的错误,以后如何避免?

    要记住调试器仅仅是个工具,就好比一只螺丝起子,你让它做什么它就只做什么,真正的调试器是你自己脑子中的调试思想。

    3.3 断点及其用法

    在Microsoft Visual C++调试器中在源代码行中设置一个断点很简单。只需要打开源文件,将光标放在想要设置断点的代码行上,按下F9快捷键就可以了,再次按下F9快捷键就会取消断点。当运行该代码行的代码时,调试器将在所设置的位置处停止。这种简单的位置断点的功能极其强大,经过统计,只需要单独的使用这种断点,就可以解决99.46%的调试问题。

    如果程序并不是每次运行到断点处都会发生错误,那么不停地在调试器和应用程序之间穿梭很快就会让人厌倦,这时高级断点就派上了用场。从本质上来讲,高级断点允许你将某些智慧写入到断点中,让调试器在执行到断点处时,只当程序内部状态符合你指定的条件时才在断点处中断程序运行,并切换到调试器中。

    按下Alt+F9快捷键弹出Breakpoints对话框,浏览一下对话框发现该对话框分为Location、Data和Messages三页,分别对应三种断点:
    1. 位置断点:我们通常使用的简单断点均为位置断点,我们还可以设置断点在某个二进制地址或任何函数上,并通过指定各种限定条件来增强位置断点的功能。
    2. 表达式和变量断点:调试器会让程序一直运行,直到满足所设的条件或者指定数据更改为止。在Intel CPU上,这两种断点都尽可能通过CPU的特定调试寄存器使用一个硬件断点,如果能够使用调试寄存器,那么程序将能够全速运行,否则调试器将单步执行每个汇编指令,并每步都检查条件,程序的运行速度将极其缓慢甚至无法运行。
    3. Windows消息断点:使用消息断点,可以让调试器在窗口过程接收到一个特定的Windows消息时中断。消息断点适用于C SDK类型的程序,对于使用MFC等C++类库的程序(应该是绝大多数)来说,消息断点并不实用,可以变通地使用位置断点来达到同样效果。
    各种高级断点的设置在MSDN中有详细的介绍,请在Visual C++子集下搜索主题Using Breakpoints: Additional Information并阅读相关内容。

    3.4 调用堆栈

    有时候我们并不清楚应该在哪里设置断点,只知道程序正在运行就突然崩溃了,这时候如何定位到出错地点呢?这时的选择就是查看调用堆栈,调用堆栈可以帮助我们确定某一特定时刻,程序中各个函数之间的相互调用关系。
    方法是当程序执行到某断点处或者程序崩溃,控制权转到调试器后,按下Alt+7快捷键,弹出Call Stack窗口,你可以看到当前函数调用情况,当前函数在最上面,下面的函数依次调用其上面的函数。在Call Stack窗口的弹出菜单上选择Parameter Values和Parameter Types可以显示各个函数的参数类型和传入值。

    3.5 使用跟踪工具

    有些时候,我们希望了解程序中不同函数之间的协作关系,或者由于文档的缺失,希望能够确认函数在不同情况下被调用时的传入参数值。这时使用断点功能就过分麻烦,而调用堆栈只能查看当前函数的被调用情况,一种较好的方法就是使用TRACE宏以及相对应的工具。
    程序(Debug版)运行中,一旦运行到TRACE宏,就会向当前Windows系统的调试器输出TRACE宏内指定的字符串并显示出来,当在Visual C++环境中调试运行(按F5键)程序时,可以在Output窗口的Debug页看到TRACE宏的输出内容。实际上,TRACE宏是封装了Windows API函数OutputDebugString的功能,有些辅助工具可以在不惊动Visual C++调试器的前提下,拦截程序中TRACE宏的输出内容,比如《深入浅出MFC》的附录中提到的Microsoft System Journal(MSJ)1996年1月的C/C++专栏介绍的TraceWin工具(在较老版本的MSDN中可以找到源代码和文档)以及功能强大的免费工具DebugView。

    使用TRACE宏,我们可以轻松了解程序中各个函数之间的相互协作关系和被调用的先后顺序和时间,进一步说,你能够完全掌握程序的执行流程。

    最后请注意,TRACE宏会对程序效率有所影响,所以,当前不用的TRACE宏最好删除或者注释掉。

    4 阅读程序的技巧

    对于程序员来说,无论是学习还是工作,经常要阅读其他程序员的源代码,如何快速领悟程序的思想,洞悉程序的结构和各个组成部分的功能,进而全面掌握程序所涉及的方方面面,是程序员很重要的一项基本技能。下面介绍一些常用的技巧。

    4.1 从功能、界面入手

    一个完整的应用程序或者系统是由若干相对独立的功能构成,这些功能反应在与用户交互的图形界面上,就是各种菜单命令、工具栏按钮命令等等。所以如果当前只对程序的某几个功能感兴趣,可以在程序中找到这些菜单命令、按钮命令等的ID响应函数,以此为起点,逐步深入到程序内部,直到完全理解该功能的实现为止。此过程所花费的时间,很大程度上取决于程序员对调试技术的掌握程度。

    需要强调的是,在不熟悉程序核心结构和实现技术的情况下,直接采用该方法探究程序,当逐步深入到程序核心时,涉及的程序模块数量会急剧增长,理解难度也会骤然增大;一旦你对程序核心结构和实现技术了然于胸,采用该方法探究程序,会有势如破竹之感觉。

    4.2 砍去枝叶,只留主干

    前面已经提到,无论如何,最终你都要掌握程序核心结构和实现技术。如何掌握呢?方法是首先将拿到的程序进行完整的备份,然后将次要功能都从程序中去掉,只留下的必须的部分。去除次要功能是一个反复多次的过程,花费的时间取决于程序员对行业知识的理解程度、编程技术的高低和经验的多少。

    经常遇到无法在短时间内判断某个模块是否次要的情况(随着对程序的理解逐渐加深,以及经验和技术的积累,这种情况会越来越少),这时候建议直接将该模块去除,然后重新编译连接程序,运行程序,看程序运行是否正常。

    以上介绍的两种方法是使用比较频繁的,两种方法可以相互结合,交替使用。但无论采用什么方法探究阅读程序,都不要指望能够不费任何气力,花费一两个钟头就能够将上万行的程序探究个明白。

    5 参考资料
    《程序设计实践》,机械工业出版社
    《高质量C++编程指南》,林锐
    《应用程序调试技术》,John Robbins,清华大学出版社
    《面向对象软件构造》,Bertrand Meyer,清华大学出版社

     


     

     

    展开全文
  • debug在程序调试过程有很大的作用,可以帮助程序员更加快速地解决问题,因此一定要熟练掌握各种命令。
  • ARM汇编调试

    2016-02-01 00:00:00
    最近学习ARM的汇编,但是ARM不像x86,可以很方便的调试。...Google了很久,又结合自己的实践,终于成功的调试了ARM的汇编此向对ARM嵌入式感兴趣的同学分享一下。 首先说明需要的工具 1. QEMU 
  • 赵炯的《Linux内核完全剖析》有一个C程序中调用汇编函数的介绍 执行as -o callee.o callee.s的时候遇到错误 “callee.s:7: Error: invalid instruction suffix for `push'”, 参考文章 :...
  • 32汇编调试工具的使用

    千次阅读 2013-01-25 22:35:48
    本文的主要目的是介绍在汇编调试的时候遇到LINK : fatal error LNK1104: cannot open file "\masm32\lib\kernel32.lib" 错误的情况. VKDebug调试工具是Masm32开发包附带的一个调试工具,Masm32程序中做输出...
  • 第6章Windows中调试  也许你以前还没有遇到过下面所述的事情,但迟早有一天它会发生你身上。你把你的程序给某个重要的人物使用,比如你最重要的客户或者是你公司的老板,不幸的是,程序在他们那里运行时崩溃了...
  • VC程序调试

    千次阅读 2009-11-11 12:40:00
    一、VC程序调试方法VC的调试功能:首先,再次强调要用Go命令运行一个将要调试的程序;如果要中止调试状态下的运行程序可以点击Stop Debugging命令,还可以通过Break选项以可恢复方式中断调试程序的运行流程(用...
  • 编写51汇编中断程序遇到的问题

    千次阅读 2013-09-17 22:30:07
    虽然程序很简单,但是始终只有一个INT1产生了中断,调试了一天无果,感觉是不是碰到了脑子有问题了,今天早上解决了,对单片机不是很了解,对汇编语言编写还不够了解,没有懂得底层的东西,没有注意他的一些限制...
  • keil程序在外部RAM中调试的问题总结

    千次阅读 2018-07-14 22:48:41
    但是有些时候内部RAM并不够用,这就需要将程序装入外部RAM中调试,而这个过程可能会出现各种各样的问题,这里我将会把我遇到过的一些问题和需要注意的地方总结一下,希望能够对大家有所帮助。有错误的地方也...
  • GDB调试命令以及GDB调试错误

    万次阅读 2014-10-07 15:00:56
    linux c++调试程序命令:gdb file 启动,罗列代码行数ist 1,break (行数),info break,run(r)调试运行,step(s)单步调试,查看变量 print(p) 变量名,查看堆栈式bt,继续调试continue(c) ,退出程序
  • 使用gdb调试程序完全教程

    万次阅读 多人点赞 2016-06-14 14:21:48
    程序调试过程主要有:单步执行,跳入函数,跳出函数,设置断点,...分析现象 -> 假设错误原因 -> 产生新的现象去验证假设调试器(如GDB)的目的是允许你在程序运行时进入到某个程序内部去看看该程序在做什么,或者
  • Masm for Windows集成开发环境编写汇编程序

    万次阅读 多人点赞 2013-03-27 20:49:38
    Masmfor Windows集成开发环境编写汇编程序 由于最近学习汇编,用的软件是一款叫“Masm for Windows集成开发环境”,但是发现该软件的资料比较少,对于我们这样刚刚学习汇编的同学,我查找了很多资料,下面主要是介绍...
  • 程序调试利器Ollydbg使用教程

    千次阅读 2016-07-30 14:31:10
    一、基础知识 1.1、OllydbgOllydbg(简称OD)是Windows平台下Ring3级的程序调试...动态调试则是可执行程序的运行过程,来查找和修正程序的语法错误和逻辑错误。随着系统安全与逆向工程的不断发展,程序调试已...
  • VS写汇编程序01:VS2015配置汇编语言开发环境

    千次阅读 多人点赞 2018-10-28 17:55:23
    一般情况下,大都数人都不会想用汇编这种古老的语言,但有时候想操控硬件或者想优化程序,又不得不用到汇编语言。汇编语言的编写,调试是一件...下面就讲一讲如何VS2015配置汇编语言开发环境(纯汇编语言开发...
  • vs 2019编写汇编并运行调试

    万次阅读 2019-09-08 15:00:07
    我是上学期学的汇编,因为有vs又不想用课上教的麻烦的dosbox以及masm32,但是一直没找到高亮插件和能调试的(难运行不了而找不到答案上,出现的错误在最后放出,还请先达们不吝指点)汇编代码所以放弃了。...
  • 用GDB调试程序 - Ubuntu中文

    千次阅读 2014-05-04 08:34:48
    终于找到了一个是u 导读: 用GDB调试程序 ...2 一个调试示例  ...6 GDB运行程序  7 调试已运行的程序  8 暂停/恢复程序运行  8.1 设置断点(Break Points)  8.2 设置观察点(Wa
  • 汇编程序:MASM.EXE,用于汇编源程序,得到目标程序。 连接程序:LINK.EXE,用于连接目标程序,得到可执行程序。 调试程序:DEBUG.EXE,用于调试可执行程序。 二、上机过程 汇编语言程序上机操作包括:编辑、汇编、...
  • AT&T汇编程序代码控制(英文对照)

    千次阅读 2010-12-24 15:20:00
    汇编好的每个字符串(字符串末不自动追加零字节)存入连续的地址。 7.5 .asciz "string". . . .asciz is just like .ascii, but each string is followed by a zero byte. The “ z” in ‘.asciz’ ...
  • Linux gcc和gdb程序调试用法

    千次阅读 2013-03-09 15:38:17
    gcc和gdb程序调试用法 gcc一般调试格式: gcc -Wall -o test test.c // -wall 显示程序错误详细信息  gcc -v // 显示gcc的版本 gcc -o{1,2,3} test test.c // 1,2,3三个级别的优化,优化级别越高编译的时间越长 ...
  • 用masm32编写一个很简单的汇编程序来入门一下masm32,打算使用斐波拉切数列这个简单的小程序来作为例子讲述。
  • Linux环境下做C语言项目,项目工程庞大复杂,出现了不少问题,其中遇到最多、花费时间最长的问题就是著名的“段错误”(Segmentation Fault)。借此机会系统学习了一下。 1. 段错误是什么 一句话来说,段错误是指...
  • 深入地分析了开发不包含逻辑和语法错误的代码技巧以及调试程序的基本原理,介绍了开发和调试命令行代码的过程和方法,说明了关于定位、分析及修复编程错误的方法,介绍了开发 Visual C++程序时所遇到的特殊...
  •  vc6.0程序调试技术总结 学c语言,一直编写的都是小程序。...图书馆借了一本书《c语言程序设计实验教程》(西工大出版社),再结合网上一些网友的博文,这里对vc6.0的程序调试技术简单梳理一下。
  • GDB程序调试工具参考知识

    千次阅读 2016-04-01 18:38:08
    GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具。或许,各位比较喜欢那种图形界面方式的,像VC、BCB等IDE的调试,但如果你是UNIX平台下做软件,你会发现GDB这个调试工具有比VC、BCB的图形化调试器更强大的...
  • VC调试遇到的问题

    千次阅读 2007-10-04 11:42:00
    在调试音视频图像传输时遇到了这样奇怪的问题,现在回想起来大致过程是这样的: 1. 原先的项目文件 D:/AVIO 文件夹 2. 由于要对这个项目文件作一个大的变动,结果很难预料, 把文件拷到 D:/AVIO_backup 做备份 3. ...
  • keil将程序装入外部RAM中调试的方法,以及实际项目中遇到的实际问题和相应的解决方案,希望对大家有所帮助。
  • 从int 3探索Windows应用程序调试原理

    千次阅读 2015-05-14 09:45:55
    【系统篇】从int 3探索Windows应用程序调试原理 探索调试器下断点的原理  Windows上做开发的程序猿们都知道,x86架构处理器有一条特殊的指令——int 3,也就是机器码0xCC,用于调试所用,当程序执行到int 3的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 19,703
精华内容 7,881
关键字:

在汇编程序调试中遇到的错误