[原创]汇编程序的编写及调试
文章标题:[原创]汇编程序的编写及调试顶部 kvew 发布于:2006-05-0301:40 [楼主][原创]汇编程序的编写及调试
文章作者:kvew
信息来源:邪恶八进制信息安全团队(www.eviloctal)
注意:本文首发安全矩阵(/bbs)后由原创作者友情提交到邪恶八进制信息安全团队
最近刚刚接触汇编,写的程序也很简单,诸如经典的入门程序helloworld,简单的两数相加等。今天试着写了个排序的程序,对于各位大虾肯定是不值一提了,在这里也只是记录一下个人编写和使用debug调试汇编程序的过程。文中出现的错误对于汇编初学者也算是常见的错误了。
对于初学汇编的朋友来说,如果稍有其他程序设计背景,对汇编指令的用法应该是很容易入门的。本文题目为《汇编程序的编写与调试》,其实主要还是介绍一下如何使用debug这个工具进行调试,在调试的过程中提及一下编写汇编程序应该注意的地方。好了,闲话少说,看看最初的程序:
首先介绍一下程序的思路:比较相邻两个数的大小,前一个比后一个大,则交换位置,这样把最大的放
到最后,然后把第二大的放到倒数第二的位置,这样一直下来,就把整个数组按从小到大的顺序排列好了。
程序本身不值得一提,仅仅借此描述下如何使用debug进行调试
--------------------------------------------------------------------
DATASEGMENT
X DB5,1,3
DATA ENDS
---------------------
STACK SEGMENT STACK
DB100DUP(?)
STACK ENDS
---------------------
CODE SEGMENT
ASSUMECS:CODE,DS:DATA,SS:STACK
START:
MOVAX,DATA
MOVDS,AX
MOVCX,2 ;X中只有3个数,外部循环2次
LEADI,X
MOVSI,DI ;DI为X第一个元素地址
ADDSI,1 ;SI+1为第二个元素地址
PUSHSI ;保存这两个地址,外部第二轮循环同样是从开始比较
PUSHDI
LP: MOVBX,CX ;BX控制内部循环次数
LP1: MOVAX,DI
CMPAX,SI ;比较DI和SI指向的元素的大小
JL LP2 ;DI指的数比SI小,跳到L4
XCHGAX,SI ;比SI大,交换它们中的内容
XCHGAX,DI
DECBX ;比过一次后,BX减1
CMPBX,0
JZ LP3 ;如果BX为0了,说明内部的循环结束
MOVDI,SI ;如果BX不为0,SI和DI都移向下一个元素
ADDSI,1
JMPLP1 ;跳到前面继续比较
LP2: DEC BX
CMP BX,0
JZ LP3
ADD SI,1
ADD DI,1
JMP LP1
LP3: POP DI ;取出先前保存的首地址,进行下一次外部循环
POP SI
LOOPLP
MOV AH,2 ;准备打印结果
MOV CX,3
LEA BX,X ;把X的地址取出来,放到BX寄存器中
LP4: MOV DL,BX ;这个循环用来打印出结果
INT 21H
INC BX
LOOPLP4
MOVAH,4CH
INT21H
CODE ENDS
END START
------------------------------------------------------------------
-
-----
好,保存为px.asm,然后masmpx.asm,看看出现什么情况:
有一个warningerrors
px.asm(65):warningA4031:Operandtypesmustmatch
在程序的第65行,操作数的类型不匹配,也就是这句
LP4: MOV DL,BX
很显然,BX是个16位的寄存器,而DL是个8位寄存器,显然这个操作是非法的,汇编中要求源操作数和目的操作数的类型一定要匹配,当然在后面的学习中会有不匹配的使用场合,这里就不涉及了。那么怎么改呢,把BX改成BL吗?显然不是,这里的意思是将BX保存的地址(X的地址)中的数送到DL中,这是个间接寻址方式,应该写为
LP4: MOVDL,[BX]
好了,我们再masmpx.asm,提示没有错误没有警告,顺利生成了盼望已久的.exe文件,运行看看结果对不对,怎么打印的是梅花笑脸和心型图案呢?有问题,那就拿出我们的工具debug吧。
输入E:\masm&,出现提示符-,用R命令查看一下各个积存器的状态:
-R
AX=0000BX=0000CX=00D0DX=0000SP=0064BP=0000SI=0000DI=0000
DS=0CE8ES=0CE8SS=0CF9CS=0D00IP=0000NVUPEIPLNZNAPONC
0D00:0000B8F80C MOVAX,OCF8
-
最后一行显示的是即将要执行的代码
用U命令反汇编可以看到我们的汇编代码
-u
0D00:0000B8F80C MOV AX,0CF8
0D00:00038ED8 MOV DS,AX
0D00:0005B90200 MOV CX,0002
0D00:00088D3E0000 LEA DI,[0000]
0D00:000C8BF7 MOV SI,DI
0D00:000E83C601 ADD SI,+01
0D00:001156 PUSH SI
0D00:001257 PUSH DI
0D00:00138BD9 MOV BX,CX
0D00:00158BC7 MOV AX,DI
0D00:00173BC6 CMP AX,SI
0D00:00197C0F JL 002A
0D00:001B96 XCHG SI,AX
0D00:001C97 XCHG DI,AX
0D00:001D4B DEC BX
0D00:001E83FB00 CMP BX,+00
-
然后我们用T命令单步运行看看
-T
AX=0CF8BX=0000CX=00D0DX=0000SP=0064BP=0000SI=0000DI=0000
DS=0CE8ES=0CE8SS=0CF9CS=0D00IP=0003 NVUPEIPLNZNAPONC
0D00:00038ED8 MOV DS,AX
-
我们可以看到在上一条指令执行后,AX积存器的内容已经变为0CF8,也就是我们的数据段首地址,
接下来我们一直单步,可以看到各个代码和积存器中的内容都在我们的控制之中。由于在前面的反汇编中有
0D00:00088D3E0000 LEA DI,[0000]
也就是说X变量的段内偏移地址为0000,那么我们来查看一下数据是否正确,用到D命令查看,后面跟偏移地址0000
-D0000
0CF8:00000501030000000000-0000000000000000 ................
0CF8:00100000000000000000-0000000000000000 ................
0CF8:00200000000000000000-0000000000000000 ................
-
可以看到数据确实是我们定义的5,1,3,那么我们继续T单步
-T
AX=0CF8BX=0002CX=0002DX=0000SP=0060BP=0000SI=0001DI=0000
DS=0CF8ES=0CE8SS=0CF9CS=0D00IP=0015 NVUPEIPLNZNAPONC
0D00:00158BC7 MOV AX,DI
-d0000
-
到了比较两个数的大小的地方了,按照上面程序的思路,应该是先把DI里的数,也就是5放到AX寄存器中,继续单步执行,看看什么结果
-T
AX=0000BX=0002CX=0002DX=0000SP=0060BP=0000SI=0
001DI=0000
DS=0CF8ES=0CE8SS=0CF9CS=0D00IP=0017 NVUPEIPLNZNAPONC
0D00:00173BC6 CMP AX,SI
-
不对啊,执行后AX里应该是5才对啊,怎么是0000呢?对了,又是先前发现的错误,间接寻址,回去把相关的地方都修改一下:
MOVAX,[DI]
CMPAX,[SI]
XCHGAX,[SI]
XCHGAX,[DI]
保存,然后再masmpx.asm,没错误,然后linkpx.obj,生成.exe,运行看看:怎么又是两个心呢?翻一下ASCII表,发现心号是03H,而我们的数据中出现了3的,对了,我们送进DL的是待显示字符的ASCII码,所以我们要把03H转换成十进制的3还要加个30H变成3的ASCII码。到后面的输入循环语句,在
MOVDL,[BX]后面加上ADDDL,30H,保存再汇编,连接,运行,显示:303怎么还是不行呢?进入debug下,T单步,到MOVAX,[DI]处仔细观察AX中的值,并配合D命令查看数据段中的数据
-t
AX=0105BX=0002CX=0002DX=0000SP=0060BP=0000SI=0001DI=0000
DS=0CF8ES=0CE8SS=0CF9CS=0D00IP=0019 NVUPEINGNZNAPOCY
0D00:00197C11 JL 002C
-
运行完MOVAX,[DI]后,确实数据进行了交换,AX中出现了5,继续单步
-t
AX=0105BX=0002CX=0002DX=0000SP=0060BP=0000SI=0001DI=0000
DS=0CF8ES=0CE8SS=0CF9CS=0D00IP=0017 NVUPEIPLNZNAPONC
0D00:00173B04 CMP AX,[SI] DS:0001=0301
-t
AX=0105BX=0002CX=0002DX=0000SP=0060BP=0000SI=0001DI=0000
DS=0CF8ES=0CE8SS=0CF9CS=0D00IP=0019 NVUPEINGNZNAPOCY
0D00:00197C11 JL 002C
-t
AX=0105BX=0002CX=0002DX=0000SP=0060BP=0000SI=0001DI=0000
DS=0CF8ES=0CE8SS=0CF9CS=0D00IP=002C NVUPEINGNZNAPOCY
0D00:002C4B DEC BX
不对啊,按照我们的思路,AX中为5,[SI]中为1,AX比[SI]大,应该继续执行啊,这么变成比它小进行跳转了啊?哦,知道了,这里是比较AX和[SI]的内容,[SI]也确实是1,但和它比较的不是我们先前送进去的5,AX为0105,也就是说应该是AX的低8位进行比较,好了,改AX为AL,保存再汇编,连接,运行,终于打印出了我们期待的正确结果:135
到此,我们的编译调试就结束了,这里还要提醒一点的是,在用CMP和XCHG比较的时候,一定要注
意,他们的操作数中必须至少一个是寄存器,对于汇编的初学者来说,很容易想当然的把上述程序中的比较和交换指令写成:
CMP[DI],[SI]
XCHG[DI],[SI]
这个就是对指令用法的理解还不够,多多看看指令手册吧!:)正确的做法应该先用一个寄存器存放其中一个值,然后这个寄存器相当于一个中间变量,实现数据的交换。
好了,整篇文章也就到此为止了,没有什么创新之谈,全当记录下个人的学习过程,不知道是否对您有所帮助。如前所述,我只是个汇编初学者,文中所举的排序程序本身质量也不高,若有说的不恰当的地方,还望各位多多包涵,多多指教!
[此贴被EvilOctal在2006-05-0321:29重新编辑]顶部 东方 发布于:2006-05-0421:33 [1楼]
调试还是
用OD,debug在win32平台没什么用了。顶部 kvew 发布于:2006-05-0701:34 [2楼]
安全矩阵(/bbs)电子资源里有个32位的debug程序
不过没用过,呵呵~有兴趣的朋友可以去下个试一试顶部 skyfloorone 发布于:2006-05-0715:24 [3楼]
windbg
softice
ida
如果有时间的话,可以拿他们分析一下程序。顶部 大内低手 发布于:2006-05-0718:20 [4楼]
1楼的,楼主明显的写的是16位程序,可能是某本8086书中的习题.用debug也是正常的.那本书上也会教到,用OD?暂且不说OD是收费软件的问题,就是恐怕学会OD要盧i馄恼乱闹渡畹亩嗔.
3楼的,windbg和softice一起排列出来,不知道你是不是两个都很精通了,调试器这玩意用的顺手不是很容易,通常一个就够了,而且这两个又是同类的内核调试器,当然windbg再调试内核的时候和softice不太一样.再者ida和这两个摆在一起就不合适了,不知道3楼的同意这个观点吗?顶部 skyfloorone 发布于:2006-05-0723:25 [5楼]
算不上精通!
我个人认为调试windows用户态的程序,最好用windbg.
调试windows核心态的程序,用softice较好(毕竟windbg也是M的调试器)。
idapro反汇编工具,可以帮助学习cpu指令。
一点点见解而已顶部 ZV 发布于:2006-05-0820:48 [6楼]
windbg和softice都是内核调试器,windbg调试内核的时候需要双机环境,调试进程或者dump的时候可以单机.softice不要,所以喜欢softice的人多.
windbg比softice通用且稳定,因为windbg仅仅是一个shell,调试功能完全取决于系统内部的实现,微软把调试器的功能集成到内核里面了.系统本身的东西自然不会出错.softice则是接管了一系列windows中断,大部分的功能都是自己实现.所以会因为不同系统的诧异产生错误.(单独发行的softice几乎都不能在winxp下使用,ds也只有3.2版本的softice能工作在winxp+sp2).
另外调试用户态程序,用od是最方便的了.
ida则是静态反编译的,他提供了强大的功能对软件进行逆向分析工程,我比较喜欢IDC脚本功能,这在脱壳和解密数据中极为好用,ida的重点是方便分析,和学习cpu指令没关系,如果指令没学好,不可能来分析的,学习指令,看intel的手册最好.(c)Copyleft2003-2007,EvilOctalSecurityTeam.
ThisfileisdecompiledbyanunregisteredversionofChmDecompiler.
Regsiteredversiondoesnotshowthismessage.
YoucandownloadChmDecompilerat:www.zipghost/指示汇编程序如何汇编的指令
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论