debug怎么用_查看CPU和内存,用机器指令和汇编指令编程

1. Debug的使用

(1) 什么是Debug
Debug是DOS、Windows都提供的实模式(8086 CPU)程序的调试工具。使用它,可以查看CPU各种寄存器中的内容、内存情况和在机器码级跟踪程序的运行。

(2) 我们常用的Debug功能
★ 用Debug的R命令查看、改变CPU寄存器的内容;
★ 用Debug的D命令看内存中的内容;
★ 用Debug的E命令改写内存中的内容;
★ 用Debug的U命令将内存中的机器指令翻译成汇编指令;
★ 用Debug的T命令执行一条机器指令;
★ 用Debug的A命令以汇编指令的格式在内存中写入一条机器指令。

注:命令不分大小写,R也可写成r,依此类推。

(3) 进入Debug
Debug是在DOS方式下使用的程序。我们在进入Debug之前,应先进入到DOS方式,
① 重新启动计算机,进入DOS方式,此时进入的实模式下的DOS。
② 在windows进入DOS :
第一步:打开CMD窗口,如图1所示:(win系统:黑乎乎的CMD窗口,其实是window系统模拟DOS的一种操作环境,快捷键:alt + Enter 可全屏显示)。

7f90363f01e4c8d0121743fbb347e904.png
图1 CMD窗口

第二步:进入到DOS后,输入Debug,然后回车运行Debug程序,你会发现如图2所示的情况。(也是挺无奈的,系统没有debug这个程序,因此我们需要自己下载)。

31b40338bba4f0688137bb3d725303b3.png
图2 就这样吧

第三步:完全舍弃前二步(突然想到了葵花宝典的那个啥,欲练此功...,你懂的),下载链接:

关于在Win7(64位)下使用MASM和DEBUG方法,汇编语言交流,技术交流区,鱼C论坛 - Powered by Discuz!​fishc.com.cn

反正能下载并安装好的方法都是好方法。

2. 执行命令

假设你已经下载并安装好了相关的程序,下面就进行实验了。

先对AX, BX, CX, DX, CS, IP这6个寄存器下手,毕竟都是老熟人(哈哈,知根知底),其它的寄存器那就算了,等以后熟了再说。

① Debug中的R命令

用途1:用R命令查看CPU寄存器的内容。

186b05c4464c66d5fb5365c3fe320500.png
图3 查看寄存器的内容

先输入Debug,再输入r,如图所示:可以看到,AX = 0000,BX = 0000,CX = 0000,DX = 0000,CS = 073F,IP = 0100

寄存器的下面,可以看到CS:IP 所指向的内存单元处所存放的机器码,并将它翻译成汇编指令,此处的机器码为:0000,对应的汇编指令为:ADD [BX+SI], AL(这条指令的含义,暂时不必深究,)。Debug输出信息右下角还有一个信息:“DS:0000=CD“,现在也不必深究。

用途2:用R命令修改寄存器的内容。

64386d8572d401d614a04e2081019501.png
图4 修改AX的内容

输入 r 寄存器名,比如修改寄存器ax的内容。输入 “r ax” 即可,会出现ax当前存放的内容,然后按Enter键,将出现”:”的输入提示,在后面输入要写入的数据后按Enter键,即完成了对ax中内容的修改,若想看修改的结果,可用r指令查看,如图4所示:

刚才修改的是ax寄存器,现在我想修改CS和IP,操作都一样,如图5所示:

e7afe5ef137b7c838ed6a1381cf3add7.png
图5 修改CS:IP的内容

② Debug中的D命令

用法1:查看Debug预设的地址处的内容

如图6所示,在进入Debug之后,用D命令直接查看,将列出Debug预设的内存单元处的内容,显示的信息:左边部分是内存单元(073F:0100 … 073F:0170),总共8行,每一行有16个内存单元,总的显示出128个内存单元;中间部分是每个内存单元对应的内容,比如:(内存单元073F:010E存放的内容为AE),大家仔细观察就会发现,每一行内容的中间是不是有个横杠(“-”),这是为方便你观看内容,横杠前面是8个字节的内容,后面也是8个字节的内容;右边部分是与内存单元里存放数据相对应的ASCII字符。比如:内存单元073F:0112,073F:0113中存放的数据分别为,46H,74H,对应的ASCII字符是F,t,内存单元073F:0111存放的数据是F0H,它没有可显示的ASCII字符,Debug就用”.”来代替。

6706440fa40e6a81d2334843d2813688.png
图6 列出Debug预设的地址处的内容

用法2:查看特定范围内地址处的内容

如图7所示:输入d 1000:0,回车。

5bedfa2d06be530b7b4d33f87fa03bb8.png
图7 查看内存1000:0处的内容

如图8所示:输入d 1000:9,回车,初始地址,从9开始,看行不行? 其实也是行的。

aff04c3e608e2a183f78ee2e815886e1.png
图8 查看1000:9处的内容

细心观察就会发现,输入初始地址(基础地址+ 偏移地址) 或直接输入d命令,系统默认显示出128个内存单元,如果还想看后面的内容,输入d,回车即可,如图9所示:

dfe92d264e674f1a3ac89397beacee3c.png
图9 查看后续内容

那么问题来了,我不想看这么多,我就想看一个内存单元的数据行不行?

dfaf29bf7fa95118fc35d8badc0588d3.png
图10 查看1000:0内存单元的内容

其实也是行的,比如你想看内存单元1000:0存放的数据,直接输入 d 1000:0 0,回车即可。如果我想看3个内存单元的数据呢?

ac4c6a33656379a7049d6495d347728c.png
图11 查看1000:0 至 1000:2内存单元的内容

这几句话可忽略不看。{在这里啰嗦一句:汇编语言的内存单元地址是从0开始的,还有很多的编程语言也是从0开始,为什么不是从1开始?
其实0是代表与序列开头的偏移量,这显得比较自然,拿Python来说,序号 -1 表示是序列的最后一个数据的索引,-1可以这样理解:”-1”中的1表示与序列开头的偏移量,而”-1”中的负号则表示反方向。}

附加:查看同一内存地址其实可用如下三种方法:

2e98102f9ea61baa077b61a03ef5dc1c.png
图12 查看同一内存单元的三种方法

图12中所有“段地址:偏移地址“都表示了10000H这一物理地址。

③ 用Debug的E命令
格式1:e 地址 内容

dec3c029521b04651e2a78042c98ef8c.png
图13 改写内存的内容:数字

第一种情况:向内存中写入数字
如图13所示,将内存1000:0 ~ 1000:9单元中的内容分别写为:0 1 2 3 4 5 6 7 8 9
格式 e 1000:0 0 1 2 3 4 5 6 7 8 9

23da8c8340c5313fa3b61a2067d68f7b.png
图14 改写内存的内容:字符

第二种情况:向内存写入字符串
如图14所示,将内存1000:0~1000:7 单元中的内容分别写为:1 'a' 2 'b' 3 'c' 4 'd'
格式 e 1000:0 1 ‘a’ 2 ‘b’ 3 ‘c’ 4 ‘d’
仔细观看:发现写入进内存1000:1、1000:3、1000:5中的内容分别为与'a'、'b'、'c'对应的ASCCI码值:61H,62H,63H 。

a46491009dd25cb5951b049057aa7e17.png
图15 改写内存的内容:字符串

第三种情况:向内存中写入字符串
如图15所示,将内存1000:0 ~ 1000:B单元中的内容分别写为:1 "a+b" 2 "c++" 3 "IBM"

格式2 :e 地址
逐个对内存单元的内容进行修改,
例子:比如修改1000:0内存单元的内容

第一步:输入e 1000:0
第二步:回车之后,你会看到1000:0目前存放的内容,在其之后有’.’,这是程序在等待你的输入。这时你有4种选择,1. 回车(退出e命令,对内容不作修改);于对1000:0进行了修改);2.输入数据,回车(对1000:0作了修改,并且退出e命令);3.空格(对1000:0的内容不作修改,接着程序会等待你输入1000:1的内容);4.输入数据,接着按空格(与第3种选择的在于修改了1000:0的内容)。

e717f8ed7e12a7345f0e53b1c8406fcf.png
图16 逐个修改内存的内容

上面的步骤可能说的有点复杂,其实只要记住:回车退出,空格保存。其实我们知道机器指令也是数据,那么我们能否向内存中写入机器指令呢?比如我们要向内存单元1000:0写入这样一段机器码:

机器码 对应的汇编指令

b80100 mov ax, 0001

b90200 mov cx, 002

01c8 add ax, cx

可用上面e 命令的格式:e 地址 内容 的方法进行写入,如图所示:

ba651964cdfac44d9cb9e24fadfe77a9.png
图17 向内存写入机器指令

这样就完了吗,我只是看到了我写进去的机器码,汇编指令呢?
如果想看汇编指令,我们就要用到Debug的u命令。

④ Debug的U命令

刚才我们向起始内存单元1000:0输入了相关机器指令,我们怎么看对之对应的汇编指令呢?
在Debug输入 U 1000:0 ,如图18所示:

1bbaaa25fd040e1bb781aa5576736ff0.png
图18 查看汇编指令

用U指令查看汇编指令包含三部分内容:左边部分,显示的是内存单元地址;中间部分显示的是内存单元所存放的机器指令;右部分显示的是与机器指令相对应的汇编指令。

如果你深入想一想,就会发现,内存中的数据与代码没有任务区别,关键在于如何解释。

又有人可能会问了,我写完机器指令,也能看与之相对应的汇编指令,但我的目的可不是看代码,我最终是想要执行代码。
Debug提供了T命令来满足你的要求。

⑤ Debug的T命令

想要执行命令之前,我们应该想几个问题,
问题1 :指令在哪 ?
问题2 :怎么执行 ?

问题1:指令在哪?
还是用我们上面那个例子,我们已经用E命令从内存单元1000:0开始写入三条汇编指令。
指令的起始单元地址在:1000:0,共有3条指令,问题1解决,

问题2:怎么执行?
我们写好指令后,我们当然知道指令在哪,但是计算机不知道,我们得告诉它,指令在哪?
前面我们已经知道,计算机会把CS:IP指向的内存单元当作指令来运行,因此,我们只要让CS:IP指向我们写指令的初始地址(上面的例子,1000:0)就可以了,问题2解决。

实验开始:

e44c1062654a1bbfda3f8e2c55b401a9.png
图19 执行指令

仔细观察:

第一步:我修改CS的指向;
第二步:我修改IP的指向;
第三步:用r指令查看相关寄存器的变化,CS:IP已经指向1000:0(指令的初始位置);
第四步:用t指令执行后,相当于执行了第一条机器指令 B80100(对应的汇编指令:mov ax, 0001),观察发现,AX = 0001 。

想要继续执行的话,继续用t指令即可,如图19所示:

000749deb028bf817456cf5d1d4a4979.png
图19 继续执行指令

运行完之后,又有人可能会想,刚才用E命令写完机器指令,通过U命令能看与之对应的汇编指令,再通过T命令能够执行机器指令。但是话说,我写给内存的是机器指令,这个就很不友好了,我哪能记得这么多的机器指令?

为此,Debug又提供了A命令,这个命令可以帮助你解决这一问题。

⑥ Debug的A命令

格式:a 地址
你不是记不了那么的机器指令嘛,好的,用a命令,你直接在内存单元写汇编指令。

eebdf5ef2ba29a6d153496724e1d08ad.png
图20 编写汇编指令

注:最后直接Eneter,就结束输入。

有人又可能会想,其实我觉得汇编挺难的。(哈哈其实我也觉得),汇编属于比较"低端"的语言,会让我们离计算机低层更近,就像你想了解一个人,靠近Ta,才能了解,通过中间n个人,去了解一个人,我想那个人早就面目全非了,哈哈。

写到这里,可能有人会说,这样没有多大意义,其实看一下书,查一下资料就知道了,说的很对,但谁让我记忆力不好呢,写下来印象会更加深刻,好记性不如烂笔头,古人的科技比我落后不假,但生活与学习经验却并不会比我们少。能把简单的事做好,你就不简单,能把平凡的事做好,你就不平凡,加油吧!!!

......一个人自愉自乐......

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值