汇编语言零基础学习-.pdf
《汇编语言零基础学习-.pdf》由会员分享,可在线阅读,更多相关《汇编语言零基础学习-.pdf(36页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、对初学者而言,汇编的许多命令太复杂,往往学习很长时间也写不出一个漂漂亮亮的程序,以致妨碍了我们学习汇编的兴趣,不少人就此放弃。所以我个人看法学汇编,不一定要写程序,写程序确实不是汇编的强项,大家不妨玩玩DEBUG,有时 CRACK 出一个小软件比完成一个程序更有成就感(就像学电脑先玩游戏一样)。某些高深的指令事实上只对有经验的汇编程序员有用,对我们而言,太过高深了。为了使学习汇编语言有个好的开始,你必须要先排除那些华丽复杂的命令,将注意力集中在最重要的几个指令上(CMP LOOP MOV JNZ)。但是想在啰里吧嗦的教科书中完成上述目标,谈何容易,所以本人整理了这篇超浓缩(用 WINZIP、W
2、INRAR依次压迫,嘿嘿!)教程。大言不惭的说,看通本文,你完全可以“不经意”间在前辈或是后生卖弄一下DEBUG,很有成就感的,试试看!那么这个接下来呢?Here we go!(阅读时看不懂不要紧,下文必有分解)因为汇编是通过 CPU 和内存跟硬件对话的,所以我们不得不先了解一下 CPU 和内存:(关于数的进制问题在此不提)是可以执行电脑所有算术逻辑运算与基本I/O 控制功能的一块芯片。一种汇编语言只能用于特定的CPU。也就是说,不同的CPU 其汇编语言的指令语法亦不相同。个人电脑由 1981年推出至今,其CPU 发展过程为:8086802868038680486PENTIUM ,还有 AMD
3、、CYRIX 等旁支。后面兼容前面 CPU 的功能,只不过多了些指令(如多能奔腾的 MMX 指令集)、增大了寄存器(如386的32位 EAX)、增多了寄存器(如486的 FS)。为确保汇编程序可以适用于各种机型,所以推荐使用 8086汇编语言,其兼容性最佳。本文所提均为 8086汇编语言。寄存器(Register)是 CPU 内部的元件,所以在寄存器之间的数据传送非常快。用途:1.可将寄存器内的数据执行算术及逻辑运算。2.存于寄存器内的地址可用来指向内存的某个位置,即寻址。3.可以用来读写数据到电脑的周边设备。8086 有8个8位数据寄存器,这些 8位寄存器可分别组成 16位寄存器:&:累加寄
4、存器,常用于运算;&:基址寄存器,常用于地址索引;&:计数寄存器,常用于计数;&:数据寄存器,常用于数据传递。为了运用所有的内存空间,8086设定了四个段寄存器,专门用来保存段地址:(Code Segment):代码段寄存器;(Data Segment):数据段寄存器;(Stack Segment):堆栈段寄存器;(Extra Segment):附加段寄存器。当一个程序要执行时,就要决定程序代码、数据和堆栈各要用到内存的哪些位置,通过设定段寄存器CS,DS,SS 来指向这些起始位置。通常是将 DS 固定,而根据需要修改CS。所以,程序可以在可寻址空间小于64K 的情况下被写成任意大小。所以,程
5、序和其数据组合起来的大小,限制在DS 所指的 64K 内,这就是COM 文件不得大于 64K 的原因。8086以内存做为战场,用寄存器做为军事基地,以加速工作。除了前面所提的寄存器外,还有一些特殊功能的寄存器:IP(Intruction Pointer):指令指针寄存器,与CS 配合使用,可跟踪程序的执行过程;SP(Stack Pointer):堆栈指针,与SS配合使用,可指向目前的堆栈位置。BP(Base Pointer):基址指针寄存器,可用作 SS的一个相对基址位置;SI(Source Index):源变址寄存器可用来存放相对于 DS 段之源变址指针;DI(Destination Ind
6、ex):目的变址寄存器,可用来存放相对于ES 段之目的变址指针。还有一个标志寄存器FR(Flag Register),有九个有意义的标志,将在下文用到时详细说明。内存是电脑运作中的关键部分,也是电脑在工作中储存信息的地方。内存组织有许多可存放数值的储存位置,叫“地址”。8086地址总线有20位,所以 CPU 拥有达 1M 的寻址空间,这也是DOS 的有效控制范围,而8086能做的运算仅限于处理 16位数据,即只有 0到64K,所以,必须用分段寻址才能控制整个内存地址。完整的20位地址可分成两部份:1.段基址(Segment):16位二进制数后面加上四个二进制,即一个16进制,变成 20位二进制
7、数,可设定 1M 中任何一个 64K 段,通常记做 16位二进制数;2.偏移量(Offset):直接使用 16位二进制数,指向段基址中的任何一个地址。如:2222(段基址):3333(偏移量),其实际的 20位地址值为:25553。除了上述营养要充分吸收外,你还要知道什么是DOS、BIOS 功能调用,简单的说,功能调用类似于WIN95 API,相当于子程序。汇编写程序已经够要命了,如果不用MS、IBM 的子程序,这日子真是没法过了(关于功能调用详见电脑爱好者98年11期)。编写汇编语言有两种主要的方法:1.使用 MASM 或 TASM 等编译器;2.使用除错程序DEBUG.COM。DEBUG
8、其实并不能算是一个编译器,它的主要用途在于除错,即修正汇编程序中的错误。不过,也可以用来写短的汇编程序,尤其对初学者而言,DEBUG 更是最佳的入门工具。因为 DEBUG 操作容易:只要键入DEBUG 回车,A 回车即可进行汇编,过程简单,而使用编译器时,必须用到文本编辑器、编译器本身、LINK 以及 EXE2BIN 等程序,其中每一个程序都必须用到一系列相当复杂的命令才能工作,而且用编译器处理源程序,必须加入许多与指令语句无关的指示性语句,以供编译器识别,使用 DEBUG 可以避免一开始就碰到许多难以理解的程序行。DEBUG 除了能够汇编程序之外,还可用来检查和修改内存位置、载入储存和执行程
9、序、以及检查和修改寄存器,换句话说,DEBUG 是为了让我们接触硬件而设计的。(8086常用指令用法将在每个汇编程序中讲解,限于篇幅,不可能将所有指令列出)。DEBUG 的的 A 命令可以汇编出简单的COM 文件,所以 DEBUG编写的程序一定要由地址100h(COM 文件要求)开始才合法。FOLLOW ME,SETP BY SETP(步步回车):输入 A100;从 DS:100开始汇编2.输入 MOV DL,1;将数值 01h 装入 DL 寄存器3.输入 MOV AH,2;将数值 02h 装入 DL 寄存器4.输入 INT 21;调用 DOS 21号中断 2号功能,用来逐个显示装入 DL 的
10、字符5.输入 INT 20;调用 DOS 20号中断,终止程序,将控制权交回给 DEBUG 6.请按 Enter 键7.现在已将汇编语言程序放入内存中了,输入G(运行)8.出现结果:输出一个符号。输出结果其实不是它,因 WORD97无法显示原结果,故找一赝品将就着。Program terminated normally 我们可以用命令将十六进制的机器码反汇编(Unassemble)成汇编指令。你将发现每一行右边的汇编指令就是被汇编成相应的机器码,而8086实际上就是以机器码来执行程序。1.输入 U100,106 1FED:0100 B201 MOV DL,01 1FED:0102 B402 M
11、OV AH,02 1FED:0104 CD21 INT 21 1FED:0106 CD20 INT 20 DEBUG 可以用命令来查看、改变寄存器内容。CS:IP 寄存器,保存了将执行指令地址。1.输入 R AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=1FED ES=1FED SS=1FED CS=1FED IP=0100 NV UP EI PL NZ NA PO NC 1FED:0100 B201 MOV DL,01 当程序由 DS:100开始执行,那么终止程序时,DEBUG 会自动将IP 内容重新设定
12、为 100。当你要将此程序做成一个独立的可执行文件,则可以用命令对该程序命名。但一定要为COM 文件,否则无法以DEBUG 载入。输入 N SMILE.COM;我们得告诉 DEBUG 程序长度:程序从 100开始到 106,故占用 7;字节。我们利用 BX 存放长度值高位部分,而以CX 存放低位部分。2.输入 RBX;查看 BX 寄存器的内容,本程序只有7个字节,故本步可省略3.输入 RCX;查看 CX 寄存器的内容4.输入 7;程序的字节数5.输入 W;用命令将该程序写入(Write)磁盘中修行至此,我们便可以真正接触8086汇编指令了。当我们写汇编语言程序的时候,通常不会直接将机器码放入内
13、存中,而是打入一串助记符号(Mnemonic Symbols),这些符号比十六进制机器码更容易记住,此之谓汇编指令。助记符号,告诉CPU 应执行何种运算。也就是说,助忆符号所构成的汇编语言是为人设计的,而机器语言是对 PC 设计的。现在,我们再来剖析一个可以将所有ASCII 码显示出来的程序。1.输入 DEBUG 2.输入 A100 3输入 MOV CX,0100;装入循环次数MOV DL,00;装入第一个 ASCII 码,随后每次循环装入新码MOV AH,02 INT 21 INC DL;INC:递增指令,每次将数据寄存器DL 内的数值加1 LOOP 0105;LOOP:循环指令,每执行一次
14、LOOP,CX 值减1,并跳;到循环的起始地址 105,直到 CX 为0,循环停止INT 20 4.输入 G 即可显示所有 ASCII 码当我们想任意显示字符串,如:UNDERSTAND?,则可以使用DOS21H 号中断 9H 号功能。输入下行程序,存盘并执行看看:1.输入 A100 MOV DX,109;DS:DX 字符串的起始地址MOV AH,9;DOS 的09h 功能调用INT 21;字符串输出INT 20 DB UNDERSTAND?$;定义字符串在汇编语言中,有两种不同的指令:1.正规指令:如MOV 等,是属于 CPU 的指令,用来告诉CPU 在程序执行时应做些什么,所以它会以运算码
15、(OP-code)的方式存入内存中;2.伪指令:如 DB 等,是属于DEBUG 等编译器的指令,用来告诉编译器在编译时应做些什么。DB(Define Byte)指令用来告诉 DEBUG 将单引号内的所有ASCII 码放入内存中。使用 9H 功能的字符串必须以$结尾。用命令可用来查看DB伪指令将那些内容放入内存。6.输入 D100 1975:0100 BA 09 01 B4 09 CD 21 CD-20 75 6E 64 65 72 73 74.!.underst 1975:0110 61 6E 64 24 8B 46 F8 89-45 04 8B 46 34 00 64 19 and$.F.E
16、.F4.d.1975:0120 89 45 02 33 C0 5E 5F C9-C3 00 C8 04 00 00 57 56.E.3._.WV 1975:0130 6B F8 0E 81 C7 FE 53 8B-DF 8B C2 E8 32 FE 0B C0 k.S.2.1975:0140 74 05 33 C0 99 EB 17 8B-45 0C E8 D4 97 8B F0 89 t.3.E.1975:0150 56 FE 0B D0 74 EC 8B 45-08 03 C6 8B 56 FE 5E 5F V.t.E.V._ 1975:0160 C9 C3 C8 02 00 00 6B
17、D8-0E 81 C3 FE 53 89 5E FE.k.S.1975:0170 8B C2 E8 FB FD 0B C0 75-09 8B 5E FE 8B 47 0C E8.u.G.现在,我们来剖析另一个程序:由键盘输入任意字符串,然后显示出来。db 20指示 DEBUG 保留20h 个未用的内存空间供缓冲区使用。输入 A100 MOV DX,0116;DS:DX 缓冲区地址,由 DB 伪指令确定缓冲区地址MOV AH,0A;0Ah 号功能调用INT 21;键盘输入缓冲区MOV DL,0A;由于功能 Ah 在每个字符串最后加一个归位码(0Dh由 Enter MOV AH,02;产生),使光
18、标自动回到输入行的最前端,为了使新输出的INT 21;字符串不会盖掉原来输入的字符串,所以利用功能2h加一;个换行码(OAh),使得光标移到下一行的的最前端。MOV DX,0118;装入字符串的起始位置MOV AH,09;9h 功能遇到$符号才会停止输出,故字符串最后必须加上INT 21;$,否则 9h 功能会继续将内存中的无用数据胡乱显示出来INT 20 DB 20;定义缓冲区送你一句话:学汇编切忌心浮气燥。客套话就不讲了。工欲善其事,必先利其器。与其说DEBUG 是编译器,倒不如说它是“直译器”,DEBUG 的 A 命令只可将一行汇编指令转成机器语言,且立刻执行。真正编译器(MASM)的运
19、作是利用文本编辑器(EDIT 等)将汇编指令建成一个独立且附加名为.ASM 的文本文件,称源程序。它是MASM 程序的输入部分。MASM 将输入的 ASM文件,编译成.OBJ 文件,称为目标程序。OBJ 文件仅包含有关程序各部份要载入何处及如何与其他程序合并的信息,无法直接载入内存执行。链结程序 LINK 则可将 OBJ 文件转换成可载入内存执行(EXEcute)的EXE 文件。还可以用EXE2BIN,将符合条件的 EXE 文件转成 COM 文件(COM 文件不但占用的内存最少,而且运行速度最快)。下面我们用 MASM 写一个与用 DEBUG 写的第一个程序功能一样的程序。用 EDIT 编辑一
20、个 SMILE.ASM 的源程序文件。源程序 DEBUG 程序prognam segment assume cs:prognam org 100h A100 mov dl,1 mov dl,1 mov ah,2 mov ah,2 int 21h int 21 int 20h int 20 prognam ends end 比较一下:1.因为 MASM 会将所有的数值假设为十进制,而 DEBUG则只使用十六进制,所以在源程序中,我们必须在有关数字后加上代表进制的字母,如 H 代表十六进制,D 代表十进制。若是以字母开头的十六进制数字,还必须在字母前加个0,以表示它是数,如 0AH。2.源程序增加
21、五行叙述:prognam segment 与 prognam ends 是成对的,用来告诉MASM 及 LINK,此程序将放在一个称为PROGNAM(PROGram NAMe)的程序段内,其中段名(PROGNAM)可以任取,但其位置必须固定。assume cs:prognam 必须在程序的开头,用来告诉编译器此程序所在段的位置放在 CS 寄存器中。end用来告诉 MASM,程序到此结束,ORG 100H作用相当于 DEBUG 的 A100,从偏移量 100开始汇编。COM 文件的所有源程序都必须包含这五行,且必须依相同的次序及位置出现,这点东西记下就行,千篇一律。接着,我们用MASM 编译 S
22、MILE.ASM。输入 MASM SMILE 不用打入附加名.ASM。Microsoft(R)Macro Assembler Version 5.10 Copyright(C)Microsoft Corp 1981,1988.All rights reserved.Object filename SMILE.OBJ:是否改动输出 OBJ 文件名,如不改就 ENTER Source listing NUL.LST:是否需要列表文件(LST),不需要就ENTER Cross-reference NUL.CRF:是否需要对照文件(CRF),不需要则 ENTER 50162+403867 Bytes
23、symbol space free 0 Warning Errors 警告错误,表示编译器对某些语句不理解,通常是输入错误。0 Severe Errors 严重错误,会造成程序无法执行,通常是语法结构错误。如果没有一个错误存在,即可生成 OBJ 文件。OBJ 中包含的是编译后的二进制结果,它还无法被DOS 载入内存中加以执行,必须加以链结(Linking)。以 LINK 将 OBJ 文件(SMILE.OBJ)链结成 EXE 文件(SMILE.EXE)时,。1.输入 LINK SMILE 不用附加名 OBJ Microsoft(R)Overlay Linker Version 3.64 Copy
24、right(C)Microsoft Corp 1981,1988.All rights reserved.Run File SMILE.EXE:是否改动输出 EXE 文件名,如不改就ENTER List File NUL.MAP:是否需要列表文件(MAP),不需要则ENTER Libraries.LIB:是否需要库文件,要就键入文件名,不要则ENTER LINK:warning L4021:no stack segment 由于 COM 文件不使用堆栈段,所以错误信息no stack segment 并不影响程序正常执行至此已经生成EXE 文件,我们还须使用EXE2BIN 将 EXE 文件(S
25、MILE.EXE),转换成COM 文件(SMILE.COM)。输入EXE2BIN SMILE 产生 BIN 文件(SMILE.BIN)。其实 BIN 文件与 COM 文件是完全相同的,但由于DOS 只认 COM、EXE 及 BAT 文件,所以 BIN 文件无法被正确执行,改名或直接输入EXE2BIN SMILE SMILE.COM即可。现在,磁盘上应该有SMILE.COM 文件了,你只要在提示符号C:下,直接输入文件名称SMILE,就可以执行这个程序了。你是否觉得用编译器产生程序的方法,比 DEBUG 麻烦多了!以小程序而言,的确是如此,但对于较大的程序,你就会发现其优点了。我们再将 ASCI
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 汇编语言 基础 学习
限制150内