课件:汇编语言程序设计_第1页
课件:汇编语言程序设计_第2页
课件:汇编语言程序设计_第3页
课件:汇编语言程序设计_第4页
课件:汇编语言程序设计_第5页
已阅读5页,还剩141页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1 第3章汇编语言程序设计 主要内容 汇编语言源程序的结构汇编语言语句格式伪指令功能调用汇编语言程序设计 2 3 1汇编语言概述1 机器语言 二进制数形式的指令和数据 B064是什么意思 这就是机器语言 既不直观 又不易理解和记忆 2 汇编语言 MOVAL 64H 很容易记忆理解 这就是助记符 助记符 用便于记忆的英语单词表示的指令操作码 它反映了指令的功能和主要特征 便于人们理解和记忆 指令除了操作码以外 还有一个操作数问题 操作数可能放在存储器中 这就涉及操作数的地址 程序中遇到转移指令或调用指令 也需要知道转移地址 若采用具体地址就很不方便 一旦有错 改动也很麻烦 于是人们采用标号或符号来代替地址 3 LP1 movax VAR loopLP1汇编语言 指令助记符 符号地址 标号 伪指令等语言元素的集合以及这些元素使用的规则 用汇编语言编写的程序叫汇编语言源程序 汇编源程序需翻译成机器语言 变成可执行文件 机器才能执行 这个翻译过程叫汇编 高级语言中称该过程为 解释 或 编译 执行翻译的程序称为 汇编程序 4 汇编语言程序设计与执行过程 输入汇编语言源程序源文件 ASM汇编 编译 目标文件 OBJ链接可执行文件 EXE调试最终程序小汇编 ASM宏汇编 MASM3 高级语言 通用性强 例 MATLAB C Pascal 5 3 2汇编语言源程序的格式 汇编语言源程序通常由一个或几个程序模块组成 每个模块一般由三个逻辑段组成 数据段 存放数据 变量DATASEGMENTDATAEDNS堆栈段 堆栈区域STACKSEGMENTSTACKENDS代码段 存放程序指令CODESEGMENTCODEEDNS 3 2 1分段结构 6 一个基本的汇编语言程序框架如下 stackSEGMENTPARA stack DB100DUP stack stackENDSdataSEGMENTdataENDScodeSEGMENTASSUMECS code DS data ES datastart MOVAX dataMOVDS AXMOVES AXMOVAH 4CHINT21HcodeENDSENDstart 堆栈段 数据段 代码段 7 例 将两个五字节的16进制数相加DATASEGMENT 定义数据段DATA1DB0F8H 60H 0ACH 74H 3BH 变量一 字节DATA2DB0C1H 36H 93H 0D5H 20H 变量二 字节DATAENDS 数据段结束CODESEGMENT 定义代码段ASSUMECS CODE DS DATASTART MOVAX DATAMOVDS AX 初始化DSMOVCX 5 置循环次数送CXMOVSI 0 SI 0CLC CF 0 8 LOOPER MOVAL DATA2 SI 取一个字节加数ADCDATA1 SI AL 与被加数相加 带进位加法INCSI SI加1DECCX CX减1JNZLOOPER 若 CX 不等于0 转LOOPERMOVAH 4CHINT21H 返回DOSCODEENDS 代码段结束ENDSTART 源程序结束注 MOVAH 4CHINT21H DOS功能调用 结束正在运行的程序 返回DOS 9 3 2 2汇编语言语句的类型和组成 汇编语言的语句有两种 指令性语句 由8086指令助记符构成的语句指令性语句的格式为 标号 指令助记符目的操作数 源操作数 注释注 各部分之间至少要用一个空格作为分隔符 指令性语句由CPU执行 每一条指令性语句都有一条机器码指令与其对应指令性语句汇编时生成机器码 例 LOOPER MOVAL DATA SI 10 汇编语言的语句有两种 指示性语句 由伪指令构成的语句指示性语句的格式为 名字伪指令操作数1 操作数2 操作数n 注释注 各部分之间至少要用一个空格作为分隔符 指示性语句由汇编程序执行 它指出汇编程序应如何对源程序进行汇编 如何定义变量 分配存储单元以及指示程序开始和结束等 指示性语句无机器码指令与其相对应 指示性语句汇编时不生成机器码 例 DATADB0FBH 60H 11 标号有三个属性 段地址 即标号所在段的段地址 程序中引用一个标号 该标号的段地址应在CS中 偏移量 标号所代表存储单元的段内偏移地址 16位的无符号数类型 NEAR或FAR NEAR 表示标号所在语句与转移指令 调用指令在同一码段内 跳转时只需改变IP即可 FAR 标号所在语句与转移指令 调用指令不在同一代码段内 若没有对类型进行说明 默认为NEAR 标号通常作为转移指令或CALL指令的转移地址 3 2 3名字 12 汇编语言的一个实例 hello asmdataSEGMENTHelloDB Hello world 0DH 0AH dataENDSprogSEGMENTASSUMECS prog DS datastart MOVAX dataMOVDS AXLEADX hello 取字符串首地址MOVAH 9INT21H 显示字符串MOVAH 4CHINT21H 退回DOSprogENDSENDstart 名字 标号 13 3 2 4助记符和伪操作 助记符 8086 8088CPU指令的助记符 例如 MOV ADD MUL等伪操作指令 如DB SEGMENT ENDS ASSUME ENDS3 2 5操作数操作数包括常量 寄存器 标号 变量及表达式 1 常量二进制数 以B结尾 如01001101B 十进制数 如85 八进制数 以Q结尾 如174Q 14 十六进制数 以H结尾 第1个数字为A F时 前面应加0 如0F160H 字符串 用引号括起来的1个或多个字符 如 ERROR a 汇编时被翻译成对应的ASCII码45H 52H 52H 4FH 52H 21H和61H 十进制科学计数法 如 8 75E 4十六进制实数 如 10A4E87R2 寄存器8位寄存器 AH AL BH BL CH CL DH DL16位寄存器 AX BX CX DX SI DI BP SP DS CS SS DS3 标号 代表一条指令的符号地址 15 变量名 是存储单元 数据区 的符号地址或名字 变量也有三个属性 段地址 变量所在段的段地址偏移量 变量单元地址与段首地址之间的位移量 类型 有BYTE WORD和DWORD三种 变量在程序中作为存储器操作数被引用 标号和变量名的使用规则组成 A Z 不分大小写 0 9 不能以数字开头长度小于31个字符不能与保留字 指令助记符 伪指令 预定义符号等 重名不能重复定义例如 正确的 LP1 AGAIN NEXT GO OK 1错误的 4M LOOP AAA HELP ONE 4 变量 即内存中的存储单元或数据区 16 5 表达式 表达式是常数 寄存器 标号 变量与运算符的组合 有数字表达式和地址表达式两种 汇编时按优先规则对表达式进行计算 计算出具体的数值或地址 运行时不能改变 表达式中的运算符有6类 算术 逻辑 关系 取地址 属性 杂类 1 算术运算符 MOD用于数字表达式 例 MOVAX 4 1024汇编后的形式为 MOVAX 4096用于地址表达式 例 LEASI TAB 3若TAB的偏移地址为1000H 则汇编后的形式为 LEASI 1003H 17 逻辑运算符只能用于数字表达式中 例 MOVCL 36HAND0FH经汇编后 MOVCL 06H注意 不要把逻辑运算符与逻辑运算指令混淆 例 ANDAX 3FC0HAND0FF00H汇编后源操作数被翻译为 3F00H 所以上述指令与ANDAX 3F00H等价 2 逻辑运算符 AND OR XOR NOT 关系运算的结果是一个逻辑值 真或假关系为真 结果为全1 关系为假 结果为全0例 MOVBX PORTGT300H若PORT的值大于300H 则汇编后为 MOVBX 0FFFFH否则汇编后为 MOVBX 0 3 关系运算符 EQ NE LT GT LE GE 18 OFFSET 取变量 标号的偏移地址注意 以下指令的异同 MOVBX OFFSETVARLEABX VAROFFSET只能取静态的偏移地址 LEA指令即可取静态的偏移地址 也可取动态的偏移地址 SEG 取变量 标号的段地址 例 MOVAX SEGDATAMOVDS AX 取变量DATA的段地址 4 分析运算符和合成运算符 19 TYPE取变量的类型 1 2 4 VARDW 字ARRAYDD10DUP 双字STRDB Thisisatest 字节 MOVAX TYPEVAR AX 2MOVBX TYPEARRAY BX 4MOVCX TYPESTR CX 1LENGTH取所定义变量的长度 即变量中元素的个数 未使用重复操作符DUP 变量个数为1 否则如上例中的变量ARRAY的个数为10 20 SIZE取所定义存储区的字节数 TYPE LENGTH 例 VARDW1 2 3 4 5则TYPEVAR 2 LENGTHVAR 5 SIZEVAR 10合成运算符PTR 用来指定地址操作数的类型格式 PTR类型 BYTE WORD DWORD NEAR FAR BYTE WORD DWORD用于描述数据存储单元 变量 地址NEAR FAR用于描述转移 调用的目的地址例 MOVBYTEPTR DI 0 字节类型MOVWORDPTR DI 0 字类型MOV DI 0B5H 类型不定 21 PTR也可用来进行强制类型转换例 STR1DW STR1定义为字类型MOVAX STR1 合法MOVAL STR1 非法MOVAL BYTEPTRSTR1 合法合成运算符THIS 用来指定存储器操作数的类型合成运算符SHORT 地址操作数 22 5 其他运算符方括号 存储器地址MOVCL BX 间址寻址MOVAL SI 5 变址寻址段超越运算符 MOVAX ES DI HIGH LOW 获取数值或地址表达式的高位和低位字节VAREQU0ABCDHMOVAH HIGHVAR AH 0ABHMOVAL LOWVAR AL 0CDH 23 3 2 6注释注释 以分号开头 可放在指令后 也可单独一行 注意注解的写法 要写指令 段 在程序中的作用 而不要写指令的操作 例如 以下为同一条指令写的注释1 MOVCX 100 传送100到CX2 MOVCX 100 循环计数器置初值显然 第二种写法要比第一种写法要好 24 3 3伪操作命令 数据定义伪指令符号定义伪指令段定义和段寄存器指定伪指令过程定义伪指令结束伪指令 由汇编程序执行的指令 它本身不被汇编成机器指令 常用的伪指令有 25 3 3 2数据定义伪指令 用于定义变量 即内存单元或数据区 数据定义伪指令的格式为 变量名数据定义伪指令操作数 操作数 常用的数据定义伪指令有如下几种 DB定义字节 DW定义字 DD定义双字 DQ定义八字节DT定义十字节操作数可以是常数 变量或表达式例1 DATA BDB10 5 10HDATA WDW100H 4DATA DDD0FFFBH汇编后的内存分配情况如右图所示 26 例2 DATADB100 0FFH 存入64H 0FFHEXPRDB2 3 7 存入0DH 13DSTRDB WELCOME 存入8个字符ABDB AB 存入41H 42HBADW AB 存入42H 41HABDDDD AB 存入42H 41H 00 00OFFABDWAB 存入变量AB的偏移地址ADRSDWTABLE TABLE 5 TABLE 10 存入3个偏移地址TOTALDDTABLE 先存入TABLE偏移地址 再存段地址NUMDQ0011223344556677H 存入77H 66H 55H 44H 33H 22H 11H 00H DECMLDT1234567890H 存入90H 78H 56H 34H 12H 00 00 00 00 00HEXTABDB01 02 03 04 05 06 07 08 09DB0AH 0BH 0CH 0DH 0EH 0FH 27 例3 操作数可以是字符串 例如STRDB HELLO 汇编后的情况如图 注意下面两个定义的不同之处 DB AB 41H在低字节 42H在高字节DW AB 42H在低字节 41H在高字节 操作数 用来保留存储空间 但不存入数据 例4 ABCDB0 1 2 3 4 OK RSVDW 28 复制操作符DUP 重复的数据可以使用复制操作符DUP 如上面RSV亦可写成 RSVDW8DUP 若操作数中若使用 则表示的是地址计数器的当前值 例 TABLEDB10DUP BUFFERDWTABLE 3设TABLE的偏移地址为0080H 则汇编后如下图所示 29 3 3 3符号定义伪指令 1 EQU格式 名字EQU表达式把一个表达式用一个符号表示 以后凡出现该表达式的地方都可用这个符号表示 类似于C语言中的 define 用EQU定义的符号未清除前不能重新定义 清除EQU定义用PURGE伪指令 不占用存储空间 仅是给符号赋值CREQUODH 常数AEQUASCII TABLE 变量STREQU64 1024 数值表达式ADREQUES BP DI 5 地址表达式CBDEQUAAM 指令助记符 30 2 格式 名字 表达式区别 可对同一名字重复定义不占用存储空间 仅是给符号赋值 例1 FIVEEQU5COUNTEQUCXTENEQU10DIST BYTEPTR SI BP GOTO JMP MOVAX TENMOVCX COUNTADDDIST FIVEDIST WORDPTR SI BP 1 ADDDIST AXGOTOLABEL 定义 引用 31 例2 COUNT 10MOVCX COUNT CX 10COUNT COUNT 1MOVBX COUNT BX 9例3 COLUMNEQU80ROWEQU25SCREENFULEQUCOLUMN ROW3 LABEL格式 名字LABEL类型例 AREAWLABELWORD AREAW类型为WORD 32 3 3 4段定义伪操作 1 SEGMENT ENDS格式 段名SEGMENT 定位类型 组合方式 类别 段名ENDS汇编语言程序是按段来组织程序和数据的 和存储器的物理段相对应 汇编语言程序中的段称为逻辑段 汇编连接后被映射到物理段中 SEGMENT语句后可以带有可选参数 用以规定逻辑段的其他一些属性 33 1 定位类型说明如何确定逻辑段的边界 有四种 PARA Paragraph 逻辑段从一个节 16个字节 的边界开始 即段的起始地址应能被16整除 或这说段起始物理地址应为 0H 默认类型BYTE 逻辑段从字节边界开始 即段可以从任何地址开始 WORD 逻辑段从字边界开始 即段的起始地址必须是偶数 PAGE 逻辑段从页边界开始 256字节称为一页 故段的起始物理地址应为 00H 34 2 组合类型说明不同模块中同名段的组合方式 PUBLIC 所有此类型的同名段组合成一个逻辑段 公用一个段地址 运行时装入同一个物理段中 COMMON 所有此类型的同名段具有相同的起始地址 覆盖 共享相同的存储区域 AT 按绝对地址定位 段地址就是表达式的值 STACK 专用于说明堆栈段 组合方式同PUBLIC 35 STACKSEGMENTSTACKDB100DUP STACKENDSDATA1SEGMENTBYTESTRINGDB Thisisanexample DATA1ENDSDATA2SEGMENTWORDBUFFERDW40DUP 0 DATA2ENDS 36 CODE1SEGMENTPAGE CODE1ENDSCODE2SEGMENTPAGE CODE2ENDS START MOVAX STACK MOVSS AXCODE2ENDSENDSTART 37 长度说明 STACK的长度为100 1 100D 64HDATA1的长度为19 1 19D 13HDATA2的长度为40 2 80D 50HCODE1的长度为13 1 13D 0DHCODE2的长度为52 1 52D 34H所占内存地址 STACK 00000H 00063H 占64H 100个字节 从 00H开始DATA1 00064H 00076H 占13H 19个字节 从任何地址开始DATA2 00078H 000C7H 占50H 80个字节 以偶数地址开始CODE1 00100H 0010CH 占0DH 13个字节 从 00H开始CODE2 00110H 00143H 占34H 52个字节 从 00H开始 38 2 ASSUME伪指令在代码段中 还必须明确段和段寄存器的关系 这由ASSUME语句来指定 如ASSUMECS code DS data ES data语句中的code和data为段名 这个语句说明 CS将指向名字为code的代码段DS和ES将指向名字为data的数据段但要注意 ASSUME伪指令只是告知汇编程序有关段寄存器与段的关系 并没有给段寄存器赋予实际的初值 故下面的语句MOVAX DATAMOVDS AXMOVES AX 将段基址装入段寄存器 如果程序中用到堆栈段 则SS也需装入实际的初值 代码段基地址不需要程序员装入CS寄存器 而由OS负责装入 39 例1 CODESEGMENTASSUMECS CODE DS DATA1 SS STACKMOVAX DATA1MOVDS AXMOVAX STACKMOVSS AX CODEENDS 40 例2 DOSSEG MODELSMALL STACK100H DATAIVARDB5IARRAYDW50DUP 5 STRINGDB Thisisastring CODE 41 3 3 5过程定义伪指令PROC ENDP 过程就是子程序 一个过程可以被其它程序所调用 用CALL指令 过程的最后一条指令一般是返回指令 RET 过程定义伪指令的格式为PROC NEAR FAR RETENDP注意 PROC和ENDP必须成对出现 调用NEAR过程 先将IP内容压入堆栈 再将入口地址传送到IP SP SP 2 SP 1 SP IP 42 调用FAR过程 先将CS内容压入堆栈 再将IP内容压入堆栈 最后将段地址送CS 偏移地址送IP SP SP 2 SP 1 SP CS SP SP 2 SP 1 SP IP CS SEGfar proc IP OFFSETfar proc 例 NAME1PROCFARCALLNAME2RETNAME2PROCNEAR RETNAME2ENDPNAME1ENDP 43 3 3 6模块定义与连接伪操作1 NAME模块名 NAME前面不允许加标号2 END 标号 END后面语句不予处理3 PUBLIC符号 说明某些符号是公共的4 EXTRN名字 类型 若为变量 类型可以是BYTE WORD DWORD例 EXTRNALPHA BYTE BETA WORD若为过程 类型可以是NEAR FAR例 EXTRNSBRT FAR若为数值 类型可以是ABS 44 3 4DOS系统功能调用介绍 系统功能调用 由OS提供的一组实现特殊功能的子程序供程序员在程序中调用 以减轻编程工作量 系统功能调用有两种 一种称为DOS功能调用 另一种称为BIOS功能调用 用户程序在调用这些系统服务程序时 不是用CALL命令 而是采用软中断指令INTn来实现 n 5 1FH 调用BIOS中的服务程序 n 20 3FH 调用DOS中的服务程序 在DOS系统中 功能调用都是用软中断指令INT21H来实现的 45 INT2lH功能大致可以分为四个方面 设备管理 目录管理 文件管理和其它 D0S系统功能调用的使用方法如下 AH 功能号 设置该功能所要求的其他入口参数 执行INT21H指令 分析出口参数 以下介绍INT21H的几个最常用的功能 关于数据输入和输出我们这里只讨论键盘输入和显示输出 调用系统功能需要提供入口参数及所调用的功能号 调用结束返回结果 46 1 DOS键盘功能调用 1 检查键盘状态 功能号 0BH MOVAH 0BHINT21H例1 LOOP MOVAH OBHINT21HINCALJNELOOP 无键入则循环LOOPRET 有键入停止循环返回 47 2 单字符输入一个字符 功能号 1 MOVAH 1INT21H例2 GET KEY MOVAH 1 等待键入字符INT21H 结果在AL中CMPAL Y 是 Y JZYES 是 转YESCMPAL N 是 N JZNO 是 转NOJMPGET KEY 否则继续等待输入YES NO 48 3 输入字符串 功能号 0AH 此功能调用从键盘输入一串字符并把它存入用户指定的缓冲区中 MOVAH 0AHLEADX INT21H用户定义的输入字符串的缓冲区格式 N1 缓冲区长度 最大键入字符数 N2 实际键入的字符数 不包括回车符 49 例 DATASEGMENTBUFSIZEDB25ACTCHARDB CHARTEXTDB25DUP DB CODESEGMENT MOVDX OFFSETBUFSIZEMOVAH 0AHINT21H 50 若用户键入的字符数 包括回车 定义的N1 本功能调用将不再接收新的键入 且光标不再向右移动 例2 设在数据段定义键盘缓冲区如下 STR1DB10 10DUP 调用DOS功能的0AH号功能的程序段为 LEADX STR1MOVAH 0AHINT21H此程序段最多从键盘接收10个按键 包括回车 51 2 DOS显示功能调用 1 在显示器上显示一个字符 功能号 2 MOVAH 2MOVDL INT21H例 在显示器上显示一个字符 A MOVAH 2MOVDL A 或MOVDL 41HINT21H 2 显示字符串 功能号 9 MOVAH 9LEADX INT21H 注意 被显示的字符串必须以 结束 52 附 BIOS功能调用 BIOS 基本输入输出系统 是固化在EPROM中的一组实现基本输入输出功能的子程序 BIOS调用通过多个软中断提供 调用方法为 MOVAH INTBIOS中的几个主要中断类型如下 INT10H 屏幕显示INT13H 磁盘操作INT14H 串行口操作INT16H 键盘操作INT17H 打印机操作每类中断由包含许多子功能 调用时通过功能号指定 BIOS功能调用说明见附录 53 3 5汇编语言程序设计举例 例1 源数据区与目标数据区地址可能重叠的数据块传送 图3 15源数据区与目标数据区地址重叠示意图 54 注1 若源数据区的起始地址低于目标数据区的起始地址 应从高地址开始传送 否则应从低地址开始传送 注2 数据块的长度在CX中 55 CODESEGMENTASSUMECS CODEBLK MOVPROCFARSTART PUSHDS DS压入堆栈MOVAX 0PUSHAX AX压入堆栈MOVAX SI 计算源数据区物理地址的高16位SHRAX 1SHRAX 1SHRAX 1SHRAX 1 AX内容右移4位MOVDX DS 段地址存入DXADDAX DX 物理地址高16位存入AX中MOVDS AX 结果送DSANDSI 0FH 源数据区物理地址低4位送SI 56 MOVBX DI 计算目标数据区物理地址的高16位SHRBX 1SHRBX 1SHRBX 1SHRBX 1 BX内容右移4位MOVDX ES 段地址存入DXADDBX DX 物理地址高16位存入BX中MOVES BX 结果送ESANDDI 0FH 源数据区物理地址低4位送DICMPAX BX 比较DS与ES的高16位JADOWN 若DS高 则转移到DOWNJBUP 若DS高 则转移到UP 57 CMPSI DI 若相等 则比较低4位地址JADOWN 若SI高 则转DOWNJBUP 若DI高 则转UPJMPEXIT 若相等 则无条件退出UP STD DF 1 从高地址开始传送MOVAX CX 将数据段长度送AXDECAX AX减1ADDSI AX SI SI AX ADDDI AX DI DI AX JMPTRANS 58 DOWN CLD DF 0 从低地址开始传送TRANS REPMOVSBEXIT RETBLK MOVEENDPCODEENDSENDSTRAT思考题 1 如何获得的物理地址 2 为什么不用SHRAX CL 59 例2 将36位BCD数转换为ASCII十进制数 注1 前导的0可以不显示 注2 全0时则只显示一个0 60 DATASEGMENTBCDBUFDB56H 34H 12H 90H 78H 56H 34H 12HDB90H 78H 56H 34H 12H 90H 78H 56H 34H 12HDATAENDSSTACKSEGMENTSTACKDB100DUP 定义100个存储空间 但内容未知STACKENDSCODESEGMENTASSUMECS CODE DS DATA SS STACKTRANSPROCFARSTRAT PUSHDS 将DS压入堆栈MOVAX 0PUSHAX 将AX压入堆栈 61 MOVAX DATAMOVDS AX 数据段初始化MOVCX 18 字节数LEASI BCDBUF 取BCDBUF的偏移地址ADDSI 17 SI 17MOVDH 0 DH 0LOAD PUSHCX 将CX压入堆栈MOVAL SI 取最后一个BCD数DECSI SI减1MOVBL AL 将AL内容送BL暂存MOVCL 4ROLAL CL AL内容左移4位 高4位与低4位交换 62 ANDAL 0FH 取高4位BCDORDH AL 判断是否为前导0JZLAST 是的话 转LASTADDAL 30H 转换成ASCII码MOVDL ALMOVAH 02INT21H 输出显示LAST POPCX CX出栈CMPCX 1 判断是否为最后一个字节JNZBCDL 否 则转BCDLMOVDH 0FFH 若是 设置标志 63 BCDL MOVAL BL 取暂存在BL的内容ANDAL 0FH 取低4位BCDORDH AL 判断是否为前导0JZGOON 是的话 转GOONADDAL 30H 转换成ASCII码MOVDL ALMOVAH 02INT21H 输出显示GOON LOOPLOADRETTRANSENDPCODEENDSENDSTRAT 64 例3 要求从键盘输入一个小写英文字母 将其转换成大写英文字母后屏幕上显示出来 源程序设计如下 STACKSEGMENTSTACK 定义堆栈段DB100DUP 开辟100个存储单元STACKENDS 堆栈段结束CODESEGMENT 定义代码段ASSUMECS CODE SS STACKSTART MOVAH 01H 1号调用 从键盘输入一字符存入ALINT21HSUBAL 20H 将AL中字符的ASCII码减去20H变成大写字母MOVDL AL 结果送DL 65 MOVAH 02H 2号调用 在屏幕上显示DL中的内容INT21HMOVAH 4CH 返回DOSINT21HCODEENDS 代码段结束ENDSTART 程序汇编结束 66 例4 试计算 S W X Y Z 340 X DATASEGMENT 定义数据段WDW 245 变量初始化XDW15YDW 32ZDW280RESULTDW2DUP 定义结果保存单元DATAENDS 数据段结束CODESEGMENT 定义代码段ASSUMECS CODE DS DATASTART MOVAX DATA 初始化DSMOVDS AXMOVAX X 取出被乘数X存入AX中IMULY 执行X Y操作 67 MOVCX AX 乘积的低位字转存至CXMOVBX DX 乘积的高位字转存至BXMOVAX Z 取出加数Z存入AX中CWD 将Z扩展成双字ADDCX AX X Y的低位字与Z的低位字相加ADCBX DX X Y的高位字与Z的高位字及进位相加SUBCX 340 X Y Z的低位字减340SBBBX 0 X Y Z的高位字减低位的借位 68 MOVAX W 取出W存入AXCWD 将W扩展成双字SUBAX CX W X Y Z 340 低位运算SBBDX BX W X Y Z 340 高位运算IDIVX W X Y Z 340 XMOVRESULT AX 商存入RESULT单元MOVRESULT 2 DX 余数存入RESULT 2单元MOVAH 4CHINT21H 返回DOSCODEENDS 代码段结束ENDSTART 汇编结束 69 例5 已知在内存中有一个字节单元X 存有带符号数据 要求计算出它的绝对值后 放入RESULT单元中 分析 根据数学中绝对值的概念知道 一个正数的绝对值是它本身 而一个负数的绝对值是它的相反数加1 要计算一个数的相反数 需要完成减法运算 即用0减去这个数 8086指令系统中有专门的取负求其补数的指令NEG 程序流程如图所示 源程序设计如下 70 程序段如下DATASEGMENTXDB 25 定义变量RESULTDB 定义结果保存单元DATAENDSCODESEGMENTASSUMEDS DATA CS CODESTART MOVAX DATAMOVDS AX 初始化DSMOVAL X X取到AL中TESTAL 80H 测试AL正负JZNEXT 为正 转NEXTNEGAL 否则AL求补 DOS下MASM EXE NEXT MOVRESULT AL 送结果MOVAH 4CHINT21H 返回DOSCODEENDSENDSTART 汇编结束 71 例6 设变量X为带符号整数 试编写一个程序 完成下面的分段函数计算 题目分析 为了实现上述分段函数的计算 首先要利用上一个例题求出X的绝对值 然后根据X的绝对值判断Y的取值 程序流程如图所示 程序段如下 DOS下演示 72 DATASEGMENTXDB 36YDB DATAENDSCODESEGMENTASSUMECS CODE DS DATASTART MOVAX DATAMOVDS AXMOVAL XCMPAL 0JGENEXT 为正 转NEXTNEGAL AL中的内容求补NEXT CMPAL 5 X 和5比较JGEP1 5 转P1MOVAL 1 否则1送ALMOVBL X X送BL中SUBAL BL 结果送AL中JMPEXIT 转EXITP1 MOVAL 0 0送AL中EXIT MOVY AL 结果送Y单元MOVAH 4CHINT21H 返回DOSCODEENDSENDSTART 汇编结束 73 例7 编写程序 完成下面的分段函数的计算 X为单字节带符号数据 题目分析 这是1个3路分支的程序设计 X为内存中的一个带符号数 首先判断其正负 若为负 1作为函数值 若为正 再判断是否为0 如果为0 函数返回值为0 否则返回值为1 流程图如图所示 74 DATASEGMENTXDB 25YDB DATAENDSCODESEGMENTASSUMECS CODE DS DATASTART MOVAX DATAMOVDS AX 初始化DSMOVAL X X取到AL中CMPAL 0 AL和0比较JGEBIG 0 转BIGMOVBL 1 否则 1送BLJMPEXIT 转到结束位置 75 BIG JEEE AL 0转EEMOVBL 1 否则1送BLJMPEXIT 转到结束位置EE MOVBL 0 0送BLEXIT MOVY BL BL中内容送Y单元MOVAH 4CHINT21HCODEENDSENDSTART 汇编结束 76 例8 设计一个程序 统计在内存W单元保存的无符号字变量中有多少个二进制 1 统计结果送内存N单元保存 分析 要统计内存W单元保存的无符号字变量中有多少个二进制 1 可以将该数据送寄存器AX中 通过移位指令将AX中的每一位依次移入进位标志CF中 若CF 1则计数器CL的值加1 这样就可以统计出AX中1的个数 设计源程序如下 DATASEGMENTWDW00FFH 定义字数据NDB 定义结果保存单元DATAENDSCODESEGMENTASSUMECS CODE DS DATA 77 START MOVAX DATA 初始化DSMOVDS AXMOVCL 0 计数器清零MOVAX W 取数到AXAA ANDAX AX 逻辑与 判AX 0 JZCC 结果为0转移到CCSHLAX 1 逻辑左移1位JNCBB 无进位转BBINCCL 有 1 则计数BB JMPAA 无条件转AACC MOVN CL 结果送N单元MOVAH 4CH 返回DOSINT21HCODEENDSENDSTART 汇编结束 78 例9 编制程序完成求1 50之间的自然数中的奇数之累加和 结果送到RESULT单元中 该题属于循环次数已知 即将50以内的25个奇数进行累加和计算 可采用递增计数法来实现求累加和 程序设计如下 DATASEGMENTRESULTDW 定义结果保存单元CNEQU25 定义计数次数变量DATAENDSCODESEGMENTASSUMEDS DATA CS CODE 79 START MOVAX DATAMOVDS AX 初始化DSMOVAX 0 循环初始化MOVCX CNMOVBX 1NEXT ADDAX BX 求累加和ADDBX 2 BX BX 2LOOPNEXT CX 1 0转NEXTMOVRESULT AX 计算完毕保存结果MOVAH 4CHINT21H 程序结束CODEENDSENDSTART 汇编结束 80 例10 编制程序完成求1 2 3 N的累加和 直到累加和超过1000为止 统计被累加的自然数的个数送CN单元 累加和送SUM单元 该题的循环次数预先是不确定的 只能按照循环过程中的某个特定条件来决定循环是否继续执行 可通过测试条件是否成立来实现对循环的控制 程序设计如下 81 DATASEGMENTSUMDW CNDW DATAENDSCODESEGMENTASSUMECS CODE DS DATASTART MOVAX DATAMOVDS AX 初始化DSMOVAX 0 0送AXMOVBX 0 0送BXLP INCBX BX加1ADDAX BX 求累加和CMPAX 1000 比较JBELP 结果 1000转LPMOVSUM AXMOVCN BX 送结果MOVAH 4CHINT21H 返回DOSCODEENDSENDSTART 汇编结束 82 例11 已知在内存中从TABLE单元起存放0 10的平方值 在X单元中有一个待查数据 用查表的方法求出X的平方值送到Y单元中 程序如下 DATASEGMENTTABLEDW0 1 4 9 16 25 36 49 64 81 100XDB4YDW DATAENDSCODESEGMENTASSUMEDS DATA CS CODESTART MOVAX DATAMOVDS AX 初始化DS 83 MOVBX OFFSETTABLE BX指向表格首地址MOVAL X X中内容取出送至AL中MOVAH 0 X中的值扩展为字SHLAX 1 计算X乘2ADDBX AX BX指向要查找的位置MOVDL BX 取出要查找的内容的低位字节MOVDH BX 1 取出要查找的内容的高位字节MOVY DX 结果保存到内存中MOVAH 4CHINT21H 返回DOSCODEENDSENDSTART 汇编结束 84 例12 已知在内存NUM单元中放有1个字节的二进制数 将其以十六进制形式在显示器上显示出来 源程序设计如下 STACKSEGMENTSTACKDB200DUP STACKENDSDATASEGMENTNUMDB01100101B 定义变量并赋初值BUF1DB0AH 0DH NUM 调用回车换行 显示字符串BUF2DB4DUP 定义结果的保存单元DATAENDSCODESEGMENTASSUMEDS DATA CS CODE SS STACK 85 BEGIN MOVAX DATA 初始化DSMOVDS AXLEADI BUF2 取结果的保存单元BUF2的有效地址MOVAL NUM 取内存中的二进制数MOVCL 4 移位计数初值SHRAL CL 逻辑右移ORAL 30H 逻辑或运算MOV DI AL 保存结果 高位十六进制数的ASCII码 INCDI 地址加1MOVAL NUM 取内存中的二进制数ANDAL 0FH 逻辑与运算ORAL 30H 逻辑或运算MOV DI AL 保存结果 低位十六进制数的ASCII码 86 INCDI 地址加1MOVBYTEPTR DI H 送字符H 十六进制数标志符 INCDI 地址加1MOVBYTEPTR DI 送字符 字符串结束符 MOVDX OFFSETBUF2 取字符串偏移地址MOVAH 09H 09号调用显示字符串INT21HMOVAH 4CHINT21H 返回DOSCODEENDSENDBEGIN 程序结束 87 例13 将 65535的非压缩BCD数转换成2进制数 BCD数 2进制数算法 Dn 1 10n 1 D0 100 Dn 1 10 Dn 2 10 10 D0 0 10 Dn 1 10 Dn 2 10 10 D0即 新的中间结果 中间结果 10 本位数字 中间结果初值为0 程序如下 数据段定义mydataSEGMENTdecnumDB5 3 0 1 9 BCD数53019binnumDW mydataENDS 88 progSEGMENTASSUMECS prog DS mydatabegin MOVAX mydataMOVDS AXMOVSI OFFSETdecnumMOVCX 5 5位BCD数MOVBX 10XORAX AX 中间结果初始值为0 89 next MULBX 中间结果 10 本位数字ADDAL SI ADCAH 0INCSI 指向下位BCD数LOOPnextMOVbinnum AX 保存结果MOVAH 4CHINT21HprogENDSENDbegin 90 程序2 把 255的非压缩BCD数转换成2进制数decnumDB1 5 9 BCD数159binnumDB MOVAX decnumXCHGAH AL 百位在AH 十位在ALAAD 百位数 10 十位数MOVAH AL 中间结果送AHMOVAL decnum 2AAD 中间结果 10 个位数MOVbinnum AL 91 例14 二进制数 BCD方法1 计算二进制数中所包含的1000的个数 100的个数 10的个数和1的个数 方法2 除10取余 下面举例介绍第一种方法 流程图如下 92 汇编程序如下 DATASEGMENTBNUMDB270FHDNUMDB4DUP 存放BCD码的缓冲区DATAENDSCODESEGMENTASSUMECS CODE DS DATABINBCDPROCFARBEGIN MOVAX DATAMOVDS AXMOVAX BNUM 取二进制数LEABX DNUM BCD码缓冲区首地址送BX 93 MOVDL 0 千位的个数计数器AGAIN1 SUBAX 1000 AX 1000JCNEXT1 若 0 则退出循环INCDL DL 1JMPAGAIN1NEXT1 ADDAX 1000 AX AX 1000MOV BX DL 存千位的个数 计算百位的个数MOVDL 0 百位的个数计数器AGAIN2 SUBAX 100 AX 100JCNEXT2INCDLJMPAGAIN2NEXT2 ADDAX 100MOV BX 1 DL 存百位的个数 94 MOVDL 0 十位的个数计数器AGAIN3 SUBAX 10 AX 10JCNEXT3INCDLJMPAGAIN3NEXT3 ADDAX 10MOV BX 2 DL 存十位的个数MOV BX 3 AL 存个位的个数MOVAH 4CHINT21HBINBCDENDPCODEENDSENDBEGIN 95 例15 二进制串转换为ASCII码一个二进制位串若要送显示或打印 需把串中每一位 0或1 化为ASCII码 思路 先将目标串全部预置为30H 再把每个二进制位逐位左移至CF 然后判CF 0 若是 取下一位 若不是 将31H送此单元 流程图如下 96 97 汇编程序如下 DATASEGMENTNUMDW6F78HSTRINGDB16DUP DATAENDSCODESEGMENTASSUMECS CODE DS DATABINCAPROCFARBEGIN MOVAX DATAMOVDS AXCLD DF 0LEADI STRINGMOVCX 16 串的长度 98 MOVAL 30H 0的ASCII码为30HREPSTOSB 串中全部填充为 0 MOVCX 16LEADI STRINGMOVAL 1 MOVBX NUM BX 6F78HAGAIN RCLBX 1 含进位位循环左移JNCNEXT 若为0 转NEXTMOV DI AL 若为1 对应位送入 1 NEXT INCDILOOPAGAINMOVAH 4CHINT21HBINCAENDPCODEENDSENDBEGIN 99 因键入为整数 故要进行如下转换 ASCII BCD 二进制数ASCII BCD码很简单 高4位清零即可得到非压缩的BCD码 BCD 二进制数在本例中采用用以下方法 0 千位数 10 百位数 10 十位数 10 个位数 例16 从键盘输入两个整数 并求其和 100 101 程序如下 DATASEGMENTSTR1DB10 10DUP 第1个数的输入缓冲区STR2DB10 10DUP 第2个数的输入缓冲区NUMDW 存转换后的二进制数SUMDW0 存和OVERDB Overflow 13 10 DATAENDSCODESEGMENTASSUMECS CODE DS DATAMAINPROCFAR 102 START MOVAX DATAMOVDS AXMOVAH 0AHLEADX STR1INT21H 输入第一个数字串 设为26 MOVAH 0AHLEADX STR2INT21H 输入第二个数字串 设为33 LEABX STR1 串1的首地址送BXLEADI NUM 存二进制首地址送DICALLCHANGE 将串1ASCII码 二进制LEABX STR2 串2的首地址送BX 103 LEADI NUM 2 指向CALLCHANGE 将串2ASCII码 二进制MOVAX NUM AX NUM 001AHADDAX NUM 2 两数相加 AX 003BHMOVSUM AX 存和JNONEXT 无溢出 转NEXTLEADX OVERMOVAH 9INT21H 显示 Overflow NEXT MOVAH 4CHINT21H 返回DOSMAINENDP 104 CHANGEPROCMOVCL BX 1 实际字符数送CLMOVAL BX 2 第一个字符送ALMOVCH AL 暂存在CHCMPAL 第一个字符是负号吗 JNZNEXT1 不是 转NEXT1DECCL 字符数减1INCBXNEXT1 ADDBX 2 指向第一个数字字符MOVAX 0 清零AX 存二进制数LP1 DECCLJZNEXT2 若 CL 0 转NEXT2MOVDL BX 取字符ANDDL 0FH 转换成BCD码ADDAL DL 加到中间结果上ADCAH 0 105 MOVDX 10MULDX 10INCBX 指向下一个字符JMPSHORTLP1NEXT2 MOVDL BX 取个位数ANDDL 0FH 个位

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论