分享
分享赚钱 收藏 举报 版权申诉 / 13

类型汇编语言入门教程65160.doc

  • 上传人:dzzj200808
  • 文档编号:2609624
  • 上传时间:2018-09-23
  • 格式:DOC
  • 页数:13
  • 大小:84.50KB
  • 配套讲稿:

    如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。

    特殊限制:

    部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。

    关 键  词:
    汇编语言入门教程65160.doc
    资源描述:

    1、汇编语言入门教程 2007-04-29 22:04 对初学者而言,汇编的许多命令太复杂,往往学习很长时间也写不出一个漂漂亮亮的程序,以致妨碍了我们学习汇编的兴趣,不少人就此放弃。所以我个人看法学汇编,不一定要写程序,写程序确实不是汇编的强项,大家不妨玩玩 DEBUG,有时 CRACK 出一个小软件比完成一个程序更有成就感(就像学电脑先玩游戏一样) 。某些高深的指令事实上只对有经验的汇编程序员有用,对我们而言,太过高深了。为了使学习汇编语言有个好的开始,你必须要先排除那些华丽复杂的命令,将注意力集中在最重要的几个指令上(CMP LOOP MOV JNZ) 。但是想在啰里吧嗦的教科书中完成上述目标

    2、,谈何容易,所以本人整理了这篇超浓缩(用 WINZIP、WINRAR依次压迫,嘿嘿!)教程。大言不惭的说,看通本文,你完全可以“不经意”间在前辈或是后生卖弄一下 DEBUG,很有成就感的,试试看!那么这个接下来呢? Here we go!(阅读时看不懂不要紧,下文必有分解) 因为汇编是通过 CPU 和内存跟硬件对话的,所以我们不得不先了解一下 CPU 和内存:(关于数的进制问题在此不提) 是可以执行电脑所有算术逻辑运算与基本 I/O 控制功能的一块芯片。一种汇编语言只能用于特定的 CPU。也就是说,不同的 CPU 其汇编语言的指令语法亦不相同。个人电脑由 1981 年推出至今,其 CPU 发展

    3、过程为:8086802868038680486PENTIUM ,还有 AMD、CYRIX 等旁支。后面兼容前面 CPU 的功能,只不过多了些指令(如多能奔腾的 MMX 指令集) 、增大了寄存器(如 386 的 32 位 EAX) 、增多了寄存器(如486 的 FS) 。为确保汇编程序可以适用于各种机型,所以推荐使用 8086 汇编语言,其兼容性最佳。本文所提均为 8086 汇编语言。寄存器(Register)是 CPU 内部的元件,所以在寄存器之间的数据传送非常快。用途:1.可将寄存器内的数据执行算术及逻辑运算。2.存于寄存器内的地址可用来指向内存的某个位置,即寻址。3.可以用来读写数据到电脑

    4、的周边设备。8086 有 8 个 8 位数据寄存器,这些 8 位寄存器可分别组成 16 位寄存器:定义段 assume cs:prognam ;把上面定义段的段基址放入 CS mov cx,100h ; 装入循环次数 mov dl,0 ; 装入第一个 ASCII 码,随后每次循环装入新码 next: mov ah,2 int 21h inc dl ;INC:递增指令,每次将数据寄存器 DL 内的数值加 1 loop next ; 循环指令,执行一次,CX 减 1,直到 CX 为 0,循环停止 int 20h prognam ends ;段终止 end ;汇编终止 在汇编语言的源程序中,每一个程

    5、序行都包含三项元素: start: mov dl,1 ;装入第一个 ASCII 码,随后每次循环装入新码 标识符 表达式 注解 在原始文件中加上注解可使程序更易理解,便于以后参考。每行注解以“;”与程序行分离。编译器对注解不予理会,注解的数据不会出现在 OBJ、EXE 或 COM 文件中。由于我们在写源程序时,并不知道每一程序行的地址,所以必须以符号名称来代表相对地址,称为“标识符” 。我们通常在适当行的适当位置上,键入标识符。标识符(label)最长可达31 个字节,因此我们在程序中,尽量以简洁的文字做为标识符。现在,你可以将此ASCII.ASM 文件编译成 ASCII.COM 了。1.MA

    6、SM ASCII,2.LINK ASCII,3.EXE2BIN ASCII ASCII.COM。 注意:当你以编译器汇编你设计的程序时,常会发生打字错误、标识符名称拼错、十六进制数少了、逻辑错误等。汇编老手常给新人的忠告是:最好料到自己所写的程序一定会有些错误(别人告诉我的) ;如果第一次执行程序后,就得到期望的结果,你最好还是在检查一遍,因为它可能是错的。原则上,只要大体的逻辑架构正确,查找程序中错误的过程,与写程序本身相比甚至更有意思。写大程序时,最好能分成许多模块,如此可使程序本身的目的较单纯,易于撰写与查错,另外也可让程序中不同部份之间的界限较清楚,节省编译的时间。如果读程序有读不懂的

    7、地方最好用纸笔记下有关寄存器、内存等内容,在纸上慢慢比划,就豁然开朗了。 下面我们将写一个能从键盘取得一个十进制的数值,并将其转换成十六进制数值而显示于屏幕上的“大程序” 。前言:要让 8086 执行这样的功能,我们必须先将此问题分解成一连串的步骤,称为程序规划。首先,以流程图的方式,来确保整个程序在逻辑上没有问题(不用说了吧!什么语言都要有此步骤) 。这种模块化的规划方式,称之为“由上而下的程序规划” 。而在真正写程序时,却是从最小的单位模块(子程序)开始,当每个模块都完成之后,再合并成大程序;这种大处著眼,小处著手的方式称为“由下而上的程序设计” 。 我们的第一个模块是 BINIHEX,其

    8、主要用途是从 8086 的 BX 寄存器中取出二进制数,并以十六进制方式显示在屏幕上。注意:子程序如不能独立运行,实属正常。 binihex segment assume cs:binihex mov ch,4 ;记录转换后的十六进制位数(四位) rotate: mov cl,4 ;利用 CL 当计数器,记录寄存器数位移动次数 rol bx,cl ;循环寄存器 BX 的内容,以便依序处理 4 个十六进制数 mov al,bl ;把 bx 低八位 bl 内数据转移至 al and al,0fh ;把无用位清零 add al,30h ;把 AL 内数据加 30H,并存入 al cmp al,3ah

    9、 ;与 3ah 比较 jl printit ;小于 3ah 则转移 add al,7h ;把 AL 内数据加 30H,并存入 al printit:mov dl,al ;把 ASCII 码装入 DL mov ah,2 int 21h dec ch ;ch 减一,减到零时,零标志置 1 jnz rotate ;JNZ:当零标志未置 1,则跳到指定地址。即:不等,则转移 int 20h ;从子程序退回主程序 binihex ends end 利用循环左移指令 ROL 循环寄存器 BX(BX 内容将由第二个子程序提供) 的内容,以便依序处理 4 个十六进制数:1. 利用 CL 当计数器,记录寄存器移

    10、位的次数。2.将 BX 的第一个十六进制值移到最右边。利用 AND (逻辑“与”运算:对应位都为时,其结果为,其余情况为零)把不要的部份清零,得到结果:先将 BL 值存入 AL 中,再利用 AND 以0Fh(00001111)将 AL 的左边四位清零。由于到的 ASCII 码为 30h 到 39h,而到之 ASCII 码为 41h 到 46h,间断了 7h,所以得到结果:若 AL 之内容小于 3Ah,则 AL 值只加 30h,否则 AL 再加 7h。 ADD 指令会将两个表达式相加,其结果存于左边表达式内。标志寄存器(Flag Register)是一个单独的十六位寄存器,有 9 个标志位,某些

    11、汇编指令(大部份是涉及比较、算术或逻辑运算的指令)执行时,会将相关标志位置 1 或清 0, 常碰到的标志位有零标志(ZF) 、符号标志(SF) 、溢出标志(OF)和进位标志(CF) 。 标志位保存了某个指令执行后对它的影响,可用其他相关指令,查出标志的状态,根据状态产生动作。CMP 指令很像减法,是将两个表达式的值相减,但寄存器或内存的内容并未改变,只是相对的标志位发生改变而已:若 AL 值小于 3Ah,则正负号标志位会置 0,反之则置 1。 JL 指令可解释为:小于就转移到指定位置,大于、等于则向下执行。CMP 和 JG 、JL 等条件转移指令一起使用,可以形成程序的分支结构,是写汇编程序常

    12、用技巧。 第二个模块 DECIBIN 用来接收键盘打入的十进制数,并将它转换成二进制数放于 BX 寄存器中,供模块 1 BINIHEX 使用。 decibin segment assume cs:decibin mov bx,0 ;BX 清零 newchar:mov ah,1 ; int 21h ;读一个键盘输入符号入 al,并显示 sub al,30h ;al 减去 30H,结果存于 al 中,完成 ASCII 码转二进制码 jl exit ;小于零则转移 cmp al,9d jg exit ;左右则转移 cbw ;8 位 al 转换成 16 位 ax xchg ax,bx ;互换 ax 和

    13、 bx 内数据 mov cx,10d ;十进制数 10 入 cx mul cx ;表达式的值与 ax 内容相乘,并将结果存于 ax xchg ax,bx add bx,ax jmp newchar ;无条件转移 exit: int 20 ;回主程序 decibin ends end CBW 实际结果是:若 AL 中的值为正,则 AH 填入 00h;反之,则 AH 填入 FFh。XCHG 常用于需要暂时保留某个寄存器中的内容时。 当然,还得一个子程序(CRLF)使后显示的十六进制数不会盖掉先输入的十进制数。 crlf segment assume cs:crlf mov dl,0dh ;回车的

    14、ASCII 码 0DH 入 DL mov ah,2 int 21h mov dl,0ah ;换行的 ASSII 码 0AH 入 AH mov ah,2 int 21h int 20 ;回主程序 crlf ends end 现在我们就可以将 BINIHEX、DECIBIN 及 CRLF 等模块合并成一个大程序了。首先,我们要将这三个模块子程序略加改动。然后,再写一段程序来调用每一个子程序。 crlf proc near; mov dl,0dh mov ah,2 int 21h mov dl,0ah mov ah,2 int 21h ret crlf endp 类似 SEGMENT 与 ENDS

    15、的伪指令,PROC 与 ENDP 也是成对出现,用来识别并定义一个程序。其实,PROC 真正的作用只是告诉编译器:所调用的程序是属于近程(NEAR )或远程(FAR ) 。 一般的程序是由 DEBUG 直接调用的,所以用 INT 20 返回,用 CALL 指令所调用的程序则改用返回指令 RET,RET 会把控制权转移到栈顶所指的地址,而该地址是由调用此程序的 CALL 指令所放入的。 各模块都搞定了,然后我们把子程序组合起来就大功告成 decihex segment ;主程序 assume cs:decihex org 100h mov cx,4 ;循环次数入 cx;由于子程序要用到 cx,故

    16、子程序要将 cx 入栈 repeat: call decibin;调用十进制转二进制子程序 call crlf ;调用添加回、换行符子程序 call binihex ;调用二进制转十六进制并显示子程序 call crlf loop repeat ;循环 4 次,可连续运算 4 次 mov ah,4ch ; 调用 DOS21 号中断 4c 号功能,退出程序,作用跟 INT 20H int 21H ; 一样,但适用面更广,INT20H 退不出时,试一下它 decibin proc near push cx ;将 cx 压入堆栈,; exit: pop cx ;将 cx 还原; retdecibin

    17、 endp binihex proc near push cx pop cx retbinihex endp crlf proc near push cx pop cx retcrlf endpdecihex ends end CALL 指令用来调用子程序,并将控制权转移到子程序地址,同时将 CALL 的下行一指令地址定为返回地址,并压入堆栈中。CALL 可分为近程( NEAR)及远程(FAR)两种:1.NEAR:IP 的内容被压入堆栈中,用于程序与程序在同一段中。2.FAR:CS 、IP 寄存器的内容依次压入堆栈中,用于程序与程序在不同段中。PUSH、POP 又是一对指令用于将寄存器内容压入、弹出,用来保护寄存器数据,子程序调用中运用较多。堆栈指针有个“后进先出”原则,像 PUSH AX,PUSH BXPOP BX,POP AX 这样才能作到保护数据丝毫不差。

    展开阅读全文
    提示  道客多多所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。
    关于本文
    本文标题:汇编语言入门教程65160.doc
    链接地址:https://www.docduoduo.com/p-2609624.html
    关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

    道客多多用户QQ群:832276834  微博官方号:道客多多官方   知乎号:道客多多

    Copyright© 2025 道客多多 docduoduo.com 网站版权所有世界地图

    经营许可证编号:粤ICP备2021046453号    营业执照商标

    1.png 2.png 3.png 4.png 5.png 6.png 7.png 8.png 9.png 10.png



    收起
    展开