举例
这里我们采用 hello world 的程序举例。
首先复制到记事本,修改文件名为hello.asm。
;完整段的Hello World程序
DATAS SEGMENT
STRING DB 'Hello World!',13,10,'$' ;13为回车,10为换行,$为字符串默认结束符
DATAS ENDS
CODES SEGMENT
ASSUME CS: CODES, DS: DATAS
START:
MOV AX, DATAS
MOV DS, AX
LEA DX, STRING
MOV AH, 9
INT 21H
MOV AH, 4CH
INT 21H
CODES ENDS
END START
这里我是保存在masm文件夹中,因为我的debug.exe文件都在这里。
如果是不会使用dosbox或者是不知道这些文件到哪去弄的,这里有博客。
文件生成&运行,都是套路,上面的博客链接都有
debug
直接在生成exe文件之后 debug hello.exe 就行了。
先给出指令表,然后我们介绍常用的。
反汇编
指令为u,是按照生成的机器码来反推我们的汇编指令:
(其实也是一些外挂和破解软件强力工具,在得到汇编程序之后理论上就可以推出源码和程序的目的,不过实际上这东西应该是比看奥利给识人还难)
单步调试
指令为t,每一步都可以执行一个指令。
我们可以看到寄存器的内容变化(执行指令之后),以及当前的指令内容:
其实还有下一条指令的地址和指令码(汇编指令的左边,最后一行)
第二行最后我们会看到8个奇怪的字符,分别为:
修改/访问寄存器内容
除了上面的t指令在每一步执行的过程中我们会看到这个界面,如果是使用r指令,也可以看到。
截图分别显示了直接r和执行了一步t之后r的结果:
可以看到和t的内容相同。
但是r还可以修改寄存器的内容。
首先使用rcx,回车后会显示cx当前的值和一个冒号,我们可以在后面写上需要修改为的值。
(这里经过尝试,输入十六进制是不行的)
访问内存内容
上面访问和修改了寄存器,现在就要对内存动手了。
这里我们使用到的指令为d,但是直接d会成这样的。
这啥啊。
还记得我们之前t中会显示一个指令地址吗?(图中t的最后一行的076B)
我们要知道,我们的hello代码分为两部分,数据段和代码段,076B就是我们代码段所在的位置。
那数据段呢?最开始的mov ds,ax还记得吗,这个绑定的同时可以看到,AX变成了076A。
那我们输入 d 076A:0000看看,出现了!
简单介绍了各段在内存中的位置,我们接下来看看d指令吧。
一次显示的个数为128字节,如果不给起始地址就会像这样从起始位置开始。
修改内存内容
这里我们使用e指令。
e的格式和d指令相同,我们只需要在下一行进行修改就行。
如果是连续修改多个:在修改了一个之后按下空格,继续进行修改。
执行指令
真要是一行行t过的人都知道,一个循环t到天荒地老,所以我们有没有更快的方式:g指令,从当前位置直接到结束。
如果是不想结束,还可以这样: g +代码段的一个位置。
但这要我们记住指令的位置,这好吗,这不好。
所以我们采用新的方式:
为了方便演示,我添加了一个打印0的功能。(换行是打印字符串自带的)
注意我选中的一行,要考的 。
然后我们使用debug程序,直接g过去:
他停了,停了。
但这样要是直接运行,会变成这样:
直接卡死。
说白了是我们自己添加的一个断点。
结束
结束还好,直接按q。
(莫名想起wim的一个笑话,随机数了解一下)
结束
这里面还是有一些东西没有讲到,主要是我也没怎么用过,基本上的t、u(主要还不是给自己看的),然后g,再看看内存和寄存器。如果特殊需求改一下寄存器和内存,就没什么了,当然还需要有q。
a什么的,我上网查阅了一下,也没看出来个所以然,这里也就没给出。
最后给出几条忠告:
- dosbox中小键盘是不能用的。
- 在输入指令的过程中,比如要输入link hello,如果在之前输入过,我们可以直接使用上行键进行复制。
比如,我们上一条是debug,在退出之后我们按下上行键:
上上条指令也可以出现。 - debug其实主要还是看t的结果,虽然比较麻烦,但是也比设置断点什么的强,如果是简单的汇编程序,逻辑对了其实也还好,最开始学debug会比较辛苦。
- debug界面说实话让人脑淤血,还是看自己vscode代码靠谱。一般来说逻辑应该问题不大,主要t的时候看看指令有没有用错了的,毕竟太多了。