微机原理与应用》第4章汇编语言程序设计.ppt_第1页
微机原理与应用》第4章汇编语言程序设计.ppt_第2页
微机原理与应用》第4章汇编语言程序设计.ppt_第3页
微机原理与应用》第4章汇编语言程序设计.ppt_第4页
微机原理与应用》第4章汇编语言程序设计.ppt_第5页
已阅读5页,还剩135页未读 继续免费阅读

下载本文档

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

文档简介

微机原理与接口技术 主讲 易凡 武汉大学物理学院电子科学与技术系,第四章 汇编语言程序设计,4.1 汇编语言的基本概念,机器语言 用机器码(二进制码)表示操作的程序语言,与处理器相关,可直接执行,但难懂,检查难;,4.1.1汇编语言程序的一般概念,高级语言 具有普适性的程序设计语言,功能强大,易编写,易检查,与机器无关。,汇编语言 用多种助记附表示多操作的语言,面向机器,但易懂,易检查,机器不能识别,4.1.1 汇编语言程序的一般概念(续),汇编语言源程序 用汇编语言按一定格式编写的程序,它不能直接执行。源程序的属性为ASM 目标文件 将源程序经汇编后转换成的二进制代码的文件, 属性为OBJ 执行文件 经连接后将目标文件与库文件或其它目标文件连接在一起形成的可执行的文件, 属性为EXE 汇编 将源程序转换成目标文件的翻译过程 汇编程序 完成汇编工作的程序,汇编程序的主要功能,检查源程序; 测出源程序中的语法错误,给出出错信息; 产生目标代码程序, 并给出列表文件(LST文件); 展开宏指令; 常用的汇编程序有小汇编ASM, 宏汇编MASM, 以及TASM, TASMX, TASM32等,4.1.2 上机的步骤,编辑建立ASM源程序; 将ASM文件经汇编(MASM)转换成OBJ文件; 将OBJ文件经连接(LINK)转变成EXE文件上机执行。,4.2 汇编语言程序格式,指令语句 能产生目标代码, CPU可以执行, 完成特定功能的语句, 由CPU指令组成。 指示语句(伪指令语句) 不产生目标代码, 仅是为汇编程序作指示的语句。 宏指令语句 是一个指令序列, 在汇编时, 所有的宏指令语句都被展开为相应的指令序列。,4.2.1 汇编语言语句的类型,4.2.2 语句的格式,语句格式为: 名字 助记符 操作数 ;注释 其中,助记符项为必要项, 方括号项为可选项。,名字 可为作名字的字符有:字母AZ, 数字09, 字符? 、_、$等 数字不能放在名字之首 在指令语句中,名字一般是标号。 伪指令语句中,名字通常是变量(名), 段名,过程名等,标号:是某指令代码存放单元的符号地址,标号后必须有一个冒号“:” 标号的属性:段,偏移量,类型(FAR,NEAR),变量(名)某个存储器中数据单元或数据区的符号地址, 它代表数据单元或数据区。 变量有三种属性:段,偏移量,类型(BYTE,WORD,DWORD,QWORD),4.2.2 语句的格式,助记符 分为指令助记符和伪指令助记符。 操作数 指令操作的对象。可作为操作数的有:常量,寄存器,标号,变量和表达式。 常量: 如立即数,直接寻址的地址,ASC码字符串等 寄存器: AX,AH,DS,SP,DX等,表达式: 是常数、寄存器、标号、变量与一些操作符相组合的序列。分数字表达式和地址表达式两种。数字表达式产生一个数值结果,地址表达式产生一个地址。,; 注释项 它不会被汇编, 其功能为增加源程序的可读性。注释前必须加分号;,4.2.2 语句的格式(续),4.2.3 操作符,算术操作符 (加) 、(减)、(乘)、/ (除)、MOD (模除,即两个整数相除后取余数),例4.1 MOV DX , BLOCK(61)2 该指令语句等价于 MOV DX , BLOCK10,算术操作符应用之例,例4.2 数组ARRAY定义如下,试写出把数组长度(字数)存入CX寄存器的指令。 ARRAY DW 1, 2, 3, 4, 5, 6, 7 END DW ? END是为计算数组长度而建立的符号地址。 所需指令为: MOV CX , (ENDARRAY)/2 汇编后计算表达式而形成了指令 MOV CX , 7,逻辑运算操作符 AND(逻辑与) OR(逻辑或), XOR(逻辑异或) NOT(逻辑非) 。,它们只能用于数字表达式中,4.2.3 操作符(续),例4.4 AND DX , PORT_VAL AND 0FEH 汇编PORT_VAL AND 0FEH 确定了外设端口号,例4.3 IN AL , PORT_VAL OUT PORT_VAL AND 0FEH , AL 当端口号PORT_VAL为偶数时, 输出端口号与之相同; 当PORT_VAL为奇数时, 输出端口号比输入端口号小1,逻辑运算操作符应用之例,关系运算操作符 EQ(等于)、NE(不等)、LT(小于)、GT(大于)、 LE(小于或等于)、GE(大于或等于) 参与关系运算操作的两个操作数必须都同为数字或为同一段内的两个存储器地址。 计算的结果应为逻辑值: 结果为真,表示为FFFFH 结果为假,表示为0,4.2.3 操作符(续),例4.5: MOV AX , 4 EQ 3 ; 结果为假 等价于 MOV AX , 0 MOV AX , 4 NE 3 ; 结果为真 等价于 MOV AX , 0FFFFH 例4.6 MOV BX , (PORT_VAL LT 5)AND 20) OR (PORT_VAL GE 5)AND 30) 当 PORT_VAL5时, 汇编结果为: MOV BX , 30 否则,汇编结果为: MOV BX , 20,关系运算操作符应用之例,分析运算符,SEG 格式:SEG 变量(名) 功能:取变量所在段的段基址,主要有:SEG , OFFESET , TYPE, SIZE , LENGTH,OFFST 格式:OFFSET 变量/标号 功能:取变量或标号的偏移地址,分析运算符应用之例,例4.8 MOV DI , OFFSET DATA1 ; ; (DI)DATA1的偏移地址,例4.7 MOV AX , SEG ARRAY ; (AX)ARRAY的段基址 MOV DS , AX ; (DS)(AX),分析运算符(续),表4.1 TYPE 类型值与类型的关系,TYPE 格式:TYPE 变量/标号 功能:取变量或标号的类型值,例4.10 : VAR DW ? ; VAR为字变量 ARRAY DD 10 DUP(?) ;ARRAY为双字变量 STR DB THIS IS TEST ; STR为字节变量 MOV AX , TYPE VAR ; (AX) 2 MOV BX , TYPE ARRAY ; (BX) 4 MOV CX , TYPE STR ; (CX) 1,例4.9 ARRAY DW 1 , 2 , 3 : ADD SI , TYPE ARRAY 汇编后: ADD SI , 2,分析运算操作符应用之例,LENGTH 格式:LENGTH 变量(名) 功能:取重复定义(DUP)的复制次数, 若不是DUP定 义,则取数值1。,分析运算符(续),SIZE 格式:SIZE 变量(名) 功能:取LENGTH值与TYPE值的乘积,例4.13 若: FEES DW 100 DUP (?) 则 TYPE FEES = 2 LENGTH FEES = 100 SIZE FEES=(LENGTH FEES)(TYPE FEES)=1002=200 所以 MOV CX , SIZE FEES 汇编后: MOV CX , 200,例4.11 若: FEES DW 100 DUP (?) 对于指令: MOV CX , LENGTH FEES 汇编后: MOV CX , 100,例4.12 若: ARRAY DW 1 , 2 , 3 对于指令: MOV CX , LENGTH ARRAY 汇编后为: MOV CX , 1,分析运算操作符应用之例,综合运算符,属性运算符PTR 格式:类型 PTR 表达式 功能:对存储单元赋予确定的类型,THIS运算符 格式:名字 EQU THIS 类型 功能:给名字(变量或标号)指定类型,它的段,偏移地址与下一存储单元相同。,短程运算符SHORT 格式:SHORT 标号 功能:指明标号的类型为短标号, 从标号到引用标号指令之间的距离是在: -128127字节范围内,例4.15 设已有数据定义如下 TWO_BYTE DW ? 可用以下语句对这两个字节赋予另一种类型定义 ONE_BYTE EQU BYTE PTR TWO_BYTE OTHER_BYTE EQU BYTE PTR (TWO_BYTE+1) OTHER_BYTE EQU BYTE PTR ONE_BYTE1 ONE_BYTE与TWO_BYTE 皆为符号地址 它们的段和偏移量属性相同,但类型属性不同,前者是BYTE类型,后者是WORD类型。,例4.14 INC BX ; 操作数的类型不明确 可用PTR操作符对操作数明确定义: INC WORD PTR BX ;明确字操作数,综合操作符应用之例,例4.16 FIRST_TYPE EQU THIS BYTE WORD_TABLE DW 100 DUP (?) FIRST_TYPE与WORD_TABLE的段,偏移地址均相同,但前者是BYTE类型,后者是WORD类型。,综合操作符应用之例,例4.17 L1 EQU THIS FAR L: MOV CX ,100 L标号与L1标号的段、偏移地址一样,但类型不同。 L是NEAR类型,L1是FAR类型,允许其他段的转移指令调用。,例如 : JMP SHORT TAG TAG: ,字节分离运算符LOW、HIGH 功能:分别得一个数值或地址表达式的低位和高位字节,例4.18 STUFF EQU 0ABCDH 语句: MOV AH , HIGH STUFF 汇编后: MOV AH , 0ABH 语句: MOV AL , LOW STUFF 汇编后: MOV AL , 0CDH,综合运算符,4.3 伪指令语句,数据定义伪指令语句 功能:定义变量的类型,分配空间并赋初值 格式:变量名 DB/DW/DD 操作数,操作数,变量名 是任选项,是数据单元的符号地址,助记符 DB、DW、DD DB(Define byte):定义变量的类型为BYTE, 每个操作数占一个字节,数据定义伪指令语句,助记符 DB、DW、DD DB(Define byte):定义变量的类型为BYTE, 每个操作数占一个字节 DW(Define word):定义变量的类型为WORD,每个操作数占2个字节, 采用小端对准方式存放 DD(Define double word): 定义变量的类型为DWORD, 每个操作数占4个字节,操作数的几种形式 操作数为常数,常数表达式或为字符(串) 操作数是“?”只定义存储空间,但不预存储数据 操作数是已定义的变量或标号,操作数字段的几种形式举例,操作数是常数或是常数表达式,例4.19 DATA_BYTE DB 10,4,10H DATA_WORD DW 100,100H,-5 DATA_DWD DD 320,0FFFDH DATA_BYTE 是字节类型, 每个操作数占一个字节单元 DATA_WORD 是字类型, 每个操作数占两个字节单元 DATA_DWD 是双字类型, 每个操作数占四个字节单元,图4.1 例4.19 的汇编结果,操作数是字符串,例4.20 MESSAGE DB HELLO AB DB AB BA DW AB 字符串必须用单引号 包封 超过两个字符的字符串只能用DB定义。,操作数字段的几种形式举例,操作数是?只定义存储空间,但不预存储数据,例4.21 ABC DB 0 , ? , ? , ? , 0 DEF DW ? , 52 , ?,MWSSAGE DB HELLO,DB AB,DW AB,图4.2 例4.20 的汇编存储结果,图4.3 例4.21与例4.22 的汇编结果,关于复制操作符DUP (duplication operator),格式: 重复次数 DUP (复制内容),图4.4 例4.23的汇编结果,操作数是已定义的变量或标号,例4.24 PAR1 DB 1, 2, 3, 4 PAR2 DB ABCD PAR3 DW 0, 1, ? DATA1 DB 100 DUP(?) DATA2 DW 200 DUP(0) PARM_TABLE DW PAR1 DW PAR2 DW PAR3 INTSEG_DATA DD DATA1 DD DATA2,符号定义的伪指令,表达式赋值伪指令EQU 格式: 名字 EQU 表达式 表达式可以是常数、符号、地址表达式、寄存器, 指令等; 表达式不允许重复定义,例4.25: CR EQU 256 ; 数赋于符号名 DATA EQU HIGHT+12 ; 地址表达式赋予符号名 LF EQU ASC_TABLE ; 变量赋新符号名 B EQU BP+8 ; 变址方式引用赋于符号B CBD EQU AAM ; CBD等价于指令AAM,等号 = 伪操作 “=”与“EQU”的功能一样, 但“=”操作允许表达式重复定义,例4.26 COUNT=10 MOV CX , COUNT ; (CX) 10 COUNT=COUNT1 MOV BX , COUNT ; (BX) 9 ,符号定义的伪指令(续),类型定义伪指令LABLE 格式:标号/变量 LABLE 类型 功能:对标号/变量的类型定义, 它的段地址和偏 移地址与下一个存储器单元的相同。 变量类型: BYTE、 WORD、 DWORD 标号类型: NEAR、FAR,符号定义的伪指令(续),LABLE伪指令应用举例,例4.27 AGAINF LABLE FAR AGAIN: PUSH AX AGAIN的类型为NEAR,允许在本段内调用; AGAINF的类型为FAR,允许被其他段调用; AGAIN与AGAINF的段、偏移属性均相同。,例4.28 AREAW LABLE WORD AREAB DB 100 DUP(?) MOV AREAW , AX MOV AREABBX , AL AREAW的类型为WORD,AREAB的类型为BYTE 它们的段地址与偏移地址一样,段定义伪指令SEGMENT/ENDS,格式: 段名 SEGMENT 定位类型组合类型类别 (段体) 段名 ENDS 功能: 定义一个逻辑段并赋予一个段名。,“SEGMENT”位于逻辑段的开始,指示逻辑段起始 “ENDS” 位于逻辑段的结尾,指示逻辑段的结束 二者前的段名必须一致,定位类型对本逻辑段边界定位,BYTE:字节边界, 即从任意边界开始 WORD:字边界, 即本段的起始地址必须是偶数 PARA:节(Paragraph)的边界开始, 16个字节为一个节, 节边界的地址应为0H PAGE:页(Page)边界,256个字节为一页, 页边界起始地址应为00H 若省略定位类型 , 则默认其为PARA,定位类型应用举例,例4.29 SEGMENT伪操作的定位类型应用举例 STACK SEGMENT STACK ; STACK段, PARA边界 DB 100 DUP(?) ; 长度为100字节 STACK ENDS ; STACK段结束 DATA1 SEGMINT BYTE ; DATA1段, BYTE边界 STRING DB this is an example!; 定义字符串 DATA1 ENDS ; DATA1段结束,DATA2 SEGMINT WORD ; DATA2段,WORD边界 BUFFER DW 40 DUP(0) ; 长度为40个字 DATA2 ENDS ; DATA2段结束 CODE1 SEGMINT PAGE ; CODE1段, PAGE边界 : CODE1 ENDS ; CODE1段结束 CODE2 SEGMENT ; CODE2段, PAGE边界 : START: MOV AX , STACK MOV SS , AX : CODE2 ENDS ; CODE2段结束 END START ; 源程序结束,定位类型应用举例,本例的源程序中共有五个逻辑段,段名和定位类型分别为: STACK段, PARA边界: 段长度为100个字节(64H) DATA1段, BYTE边界: 段长度为19个字节(13H) DATA2段, WORD边界: 段长度为80个字节(50H) CODE1段, PAGE边界: 段占用13个字节(0DH) CODE2段, PARA边界: 段占用52个字节(34H),定位类型应用举例,表4.2 例4.28各逻辑的起始地址和结束地址,定位类型应用举例,组合类型 (Combine-type)指示汇编程序, 各逻辑段组合方式,该项缺省:则各逻辑段不组合 PUBLIC: 将不同模块中具有相同段名的逻辑段连接成一个大逻辑段,连接次序由连接命令指定。 STACK:与PUBLIC类似, 但仅限于堆栈段的组合 COMMON:将各同名分段组合为一个段, 各同名分段有相同的起始地址, 因此会发生重叠,COMMEN段的长度等于原来最大逻辑分段的长度。,MEMORY:当几个逻辑段连接在一起时,指定本逻辑段定位在地址最高的地方。若连接时有几个指定MEMORY的段, 则汇编程序只将首先遇到的段作为MEMORY段, 其余的段则作为COMMON段。 AT 表达式:表示本逻辑段段地址是表达式所计算出来的结果。它不能用来指定代码段。,例如:AT 8A00H , 表示本段的段基址是8A00H, 本段从存储器的物理地址为8A00H开始装入。,组合类型 (Combine-type)指示汇编程序, 各逻辑段组合方式,类别 (class),类别必须放在单引号 之内 其作用是在连接时决定各逻辑段的装入顺序 当几个程序模块进行连接时, 具有相同类别名的逻辑段按连接出现的先后顺序被装入连续的内存区 没有类别名的逻辑段, 与其他无名逻辑段一起连续装入内存。,例4.30 假设一个主程序中有五个逻辑段,段名和类别为: STK1段 STACK CODE1段 无 DATA1 段 BUFFER DATA2 段 TABLE DATA3 段 BUFFER 一个子程序,有四个逻辑段,段名和类型分别为: DATA4 段 TABLE DATA5 段 BUFFER STK2 段 STACK CODE2 段 无 当将主程序和子程序进行连接时,两个程序模块中各逻辑段装入内存的顺序见图4.5,类别定义之例,段分配伪指令ASSUME,格式: ASSUME 段寄存器名:段名,段寄存器名:段名, 功能: 指示汇编程序源程序的逻辑段与段寄存器的关系; 说明 段寄存器名必须是CS、DS、ES和SS之一, 而段名则是由SEGMENT所定义; ASSUME语句通常位于代码段中紧接段定义语句之后;,说明 ASSUME NO THING的格式可取消前面由ASSUME所指定的段寄存器设置; ASSUME仅指示逻辑段与段寄存器的关系, 但并不对段寄存器赋值。,段分配伪指令ASSUME,通常给段寄存器赋值语句为: mov ax ,段名 mov 段寄存器 ,ax,例4.31 定义各逻辑段之例 data1 segment data1 ends data2 segment data2 ends,伪指令ASSUME应用之例,code segment assume cs: code, ds: data1, es: data2 start: mov ax ,data1 mov ds ,ax mov ax ,data2 mov es ,ax code ends end start,过程定义PROC/ENDP伪指令,格式:过程名 PROC NEAR/FAR (过程体) RET 过程名 ENDP 功能说明: 定义一个过程并赋予一个名字 定义该过程的类型(NEAR或者FAR),若没有指明类型,则默认为NEAR过程;,功能说明: ENDP标志过程结束,PROC与ENDP前的过程名必须一致; 调用指令CALL,位于调用程序中; 返回指令RET,处于过程内部,作为过程的出口; 过程的定义和调用均可嵌套。,过程定义PROC/ENDP伪指令(续),例4.32: name1 proc far call name2 ret name2 proc near ret name2 endp name1 endp name1、name2是两个过程; name1本身是一个可以被调用的过程,而它也可以再调用其他的过程。,PROC/ENDP伪指令应用举例,其它伪指令,模块开始伪指令NAME 格式:NAME module_name 功能:给汇编后得到的目标程序指定一个模块名,指示模块的开始, 供连接时用。,伪指令TITLE 格式: TITLE text 功能: 指定每一页上打印的标题;,若程序没有使用NAME伪操作, 则汇编程序将用text中的前6个字符作为模块名。,其它伪指令(续),结束伪指令END 格式: END LABEL: 功能说明: 源程序到此结束, 指示汇编程序停止汇编; LABEL为代码段中的一条指令语句的标号; 仅有一个程序时必须加LABEL; 当多个模块连接, 则只有主程序的END使用LABEL,ORG伪指令 格式: ORG 常数表达式 功能:定义其后的变量(名)的地址等于常数表达式的数值,伪操作举例,例4.33 伪操作示意 title absolt data_seg segment ; define data segment oper1 dw 12 oper2 dw 230 result dw ? data_seg ends code_seg segment ; define code segment assume cs: code_seg, ds: data_seg start: mov ax , data_seg ;datarea segment addr into DS ;register,mov ds , ax ;main part of program goes here mov ax , oper1 add ax , oper2 jge store neg ax store: mov result , ax hlt code_seg ends ;end of code segment end start,伪操作举例,例4.34 org伪操作之例 vectors segment org 10 vect1 dw 47a5h org 20 vect2 dw 0c596h vectors ends vect1的偏移地址值是0ah vect2的偏移地址值为14h。,伪操作举例,在汇编过程中,使用地址计数器来保存当前汇编指令的地址。地址计数器的值可用$符号来表示。,例如: ORG $8 表示跳过8个字节的存储区。 例如: JNE $6 表示转向地址是JNE指令的首地址加6,当$用在伪操作的参数字段时,它表示为地址计数器的当前值。,例如: org 0 array dw 1 , 2 , $+4 , 3 , $+4 若array的偏移地址为0, 以上操作等价为: array dw 1 , 2 , 8 , 3 , 12,4.4 汇编语言程序设计的基本方法,汇编语言程序设计的基本过程,汇编语言程序设计的步骤 建立数学模型 确定算法和处理方案 画流程图 编制程序 上机调试,试执行并分析结果 整理资料,投入运行,汇编语言程序设计的基本过程,程序的结构化设计(1969年,荷兰学者E.W.Digkstra等人提出) 程序由一些基本结构组成,它包括:顺序结构、分支结构、循环结构 大型复杂程序应按其功能分解成若干个功能模块程序,并把这些模块按层次关系进行组装 采用“自上而下,逐个求精”的方法进行程序设计,顺序结构程序 按语句实现的先后次序执行一系列操作 分支结构程序 可分为: 两分支结构(相当于高级语言中的IF-THEN-ELSE语句) 多分支结构(相当于高级语言中的CASE语句),汇编语言程序设计的基本过程,IF-THEN-ELSE结构,判定条件,程序1,Y,N,判定条件,程序1,CASE结构,程序2,程序2,程序 n,分支结构程序设计,通常用条件转移指令来产生分枝,例4.35 给定以下符号函数: 并设任意给定的x值存放在x单元中,y存放于y单元,根据x值确定函数y的值,分支结构程序举例,datax segment x db -25 y db ? datax ends codex segment main proc far assume cs:codex,dx:datax start: push ds mov ax , 0 push ax mov ax , datax mov ds , dx mov al , x ; (al) x,b.例4.35编写程序如下,分支结构程序举例,cmp al , 0 jge loop1 mov al , offh ; x 0 时 mov al , 1 ; y 1 mov y , al ret loop2: mov al , 0 ; x=0时 mov y , al ; y 0 ret main endp codex ends end start,分支结构程序举例,例4.36 设有首地址为array的字数组,已按升序排好,数组长度为n=15,且数据段与附加段占同一个段。在该书组中查找数number(如83), 若找到它,则从数组中将其删掉;若找不到,则把它插入正确位置,且变化后的数组长度在DX中。 编程如下:,data segment dw ? n dw 15 number dw 83 array dw 5 , 10 , 17 , , 150 data ends,分支结构程序举例,code segment main proc far assume cs:code , ds:data , es:data start: push ds mov ax , 0 push ax push es mov ax , data mov ds , ax mov es , ax mov ax , number ; (AX) 待查数 mov dx , n ; 初始化DX mov cx , n ; 设置计数器CX mov di , offset array ; 建立指针 cld ; 增量方向,分支结构程序举例,repne scasw ;串扫描查找 je delete dec dx mov si , dx add si , dx tt3: cmp ax , arraysi jl tt1 mov arraysi+2 , ax ;若未查到,将此数 jmp tt2 ; 插入正确位置 tt1: mov bx , arraysi mov arraysi+2 , bx sub si , 2 jmp tt3,分支结构程序举例,tt2: add dx , 2 ; 修改数组长度 jmp fan delete: jcxz next Loopt: mov bx , di ; 若查到,从数组中 mov di-2 , bx ; 删除此数 add di , 2 loop loopt next : dec dx ; 修改数组长度 fan : pop es ret main endp code ends end start,分支结构程序举例,循环程序设计,循环程序通常由三部分组成 设置初始状态 设置循环次数、准备工作寄存器、设置数据指针等 循环体 循环工作的主体,由循环的工作部分和修改部分组成 循环控制 循环条件控制与判断,控制循环运行和结束。,循环程序可以有两种循环结构形式: DO_UNTIL结构 先执行循环体,然后再判断控制退出条件,不满足就继续执行循环体,满足条件则退出循环。 DO_WHILE结构 把循环控制条件的判断放在循环的入口,先判断条件,满足条件就执行循环体,否则则退出循环。,循环程序设计,循环程序设计,例4.37 从xx单元开始的30个连续单元中存放有30个无符号数, 从中找出最大者送入yy单元。 编程如下: datasp segment xx db 73, 59, 61, 45, 81, 107, 14, 64, 54 db 3, 17, 9, 33, 55, 79, 115, 78, 132 db 234, 37, 76, 43, 98, 251, 9, 0, 62 db 9, 145, 54 yy db ? datasp ends ; ,循环程序设计举例,codesp segment assume cs: codesp, ds: datasp main proc far start: push ds mov ax , 0 push ax mov ax , datasp mov ds , ax mov al , xx mov bx , offset xx mov cx , 29 loop1: inc bx,循环程序设计举例,cmp al , bx jae loop2 xchg al , bx loop2: dec cx jnz loop1 mov yy , al ret main endp codesp ends end start,循环程序设计举例,子程序的设计,子程序的定义 定义格式: PROCEDURE NAME PROC ATTRIBUTE (过程体) PROCEDURE NAME ENDP 格式说明: ATTRIBUTE是可选项,指示类型属性 NEAR类型, 则过程的调用(call)和返回(ret)是本段内进行 FAR类型, 则过程的调用和返回就是段间进行 若未用“ATTRIBUTE”定义,默认为NEAR类型,CALL(过程调用) 指令,段内直接调用 格式: CALL near_proc 操作: SPSP2; SP1, SPIP; IPIPdisp16 near_proc为目标地址 , 它是一个近过程名(段内的过程),相对转移范围是32K。,段内间接调用 格式: CALL reg16/mem16 操作: SP(SP)2; SP 1 , SP IP; IP reg16/mem16 其中, reg16和mem16是16位的寄存器或存储器操作数。,CALL(过程调用) 指令,段间直接调用 格式: CALL far_proc 操作: SPSP2;SP 1, SPCS; CSSEG far_proc ;SPSP2; SP1,SPIP;CSOFFSET far_proc far_proc是一个远程过程名(其它代码段的过程) “SEG”和“OFFSET”是运算符, 功能为取得过程的段基址和偏移地址。,CALL(过程调用) 指令,段间间接调用 格式: CALL mem32 操作: SP SP 2 ; SP 1 , SP CS ; SP SP 2 ; SP 1 , SP IP ; IP mem32 ; CS mem322 mem32是一个32位的存储器操作数,CALL(过程调用) 指令,RET (Return) 过程返回,格式: RET 操作: NEAR返回: IP SP 1 , SP ; SP SP 2 FAR返回: IP SP 1 , SP ; SP SP 2 ; CS SP 1 , SP ; SP SP 2,子程序之例,例4.38 调用程序和子程序在同一代码段中。 MAIN PROC FAR ;定义主过程为FAR类型 ;它视为DOS调用的子程序 CALL SUBR1 RET MAIN ENDP SUBR1 PROC NEAR RET SUBR1 ENDP,过程定义可以嵌套,例4.37可用以下形式: MAIN PROC FAR ;定义主过程为FAR类型,指示为DOS调用 ;的子程序 CALL SUBR1 RET SUBR1 PROC NEAR RET SUBR1 ENDP MAIN ENDP,子程序之例,例4.39 调用程序和子程序不在同一代码段。 segx segment surt proc far ret surt endp call surt segx ends,子程序之例,segy segment call subt segy ends,子程序的设计和使用,正确选择过程的属性 正确使用堆栈 寄存器的保护与恢复,寄存器传送 地址表传递参数地址 通过堆栈传递参数,调用程序与子程序之间的参数传递主要有三种方式,例4.40 把一个2位压缩的BCD码转换成二进制数,程序如下: data_bin segment bcd_in db ? ; 存放bcd值 value db ? ; 存放二进制值 data_bin ends code segment assume cs: code; ds: data_bin main proc far push ds mov ax , 0 push ax mov ax , data_bin mov ds , ax mov al , bcd_in ; 待转换的 BCD码,子程序之例,call bcd_binary ; 送入al寄存器 mov value , al ret main endp bcd_ binary proc near pushf ; 保存状态字 push bx ; 保护bx和cx push cx mov ah , al ; BCD数送入ah and ah , 0fh ; 分离BCD数的低位数 mov bl , ah and al , 0f0h ; 分离BCD数的高位数 mov cl , 04h ; 把BCD数高位数字 ror al , cl ; 移到低位,子程序之例,mov bh , 0ah ; 将转换因子10送入bh mul bh ; BCD数的高位数字乘0ah add al , bl ; 乘积与BCD数的低位数 ; 相加,结果送入al中 pop cx ; 恢复被保护的寄存器 pop bx popf ret bcd_binary endp code ends end main,子程序之例,4.5 DOS系统功能与BIOS功能调用,DOS系统功能调用是微机的磁盘操作系统为用户提供的一组例行子程序, 分为4个方面 : 磁盘的读/写及控制管理 内存管理 基本输入/输出管理 时间、日期等子程序,DOS系统功能调用,所有的系统功能子程序按顺序编号,称之为功能号 DOS功能调用方法 子程序的入口参数送相应的寄存器; 功能号送AH寄存器; 发中断请求: INT 21H(系统功能调用指令),例4.41 显示字符串: Good morning! MSG DB Good morning!, $ MOV DX , OFFSET MSG MOV AH , 9 INT 21H 例4.42 退回到DOS MOV AH , 4CH INT 21H,DOS系统功能调用之例,表4.2 DOS键盘功能调用( INT 21H ),例4.43 程序显示一串信息,要求回答Y或 N,回答Y,程序转标号为YES程序段,而N使程序转标号为 NO程序段。编程如下: gat_key: mov ah , 1 ; read a key with int 21h ; echo cmp al , y ; is it y ? je yes ; if so, jump to yes cmp al , n ; is it n ? je no ; if so, jump to no jne get_key ; otherwise,wait for y or n,DOS键盘功能调用之例,例4.44 要求程序在按下Return键后才继续运行。程序段为: WAIT_HERE: MOV AH , 7 ; Wait for enter INT 21H CMP AL , 0DH ; ASCII code of JNE WAIT_HERE ; Return,DOS键盘功能调用之例,例4.45 清除键盘缓冲区,然后执行8号功能。 MOV AH , 0CH MOV AL , 08H INT 21H,0AH号功能说明,0AH号功能是从键盘接收一串字符送入内存缓冲区,其缓冲区的格式为: 第一字节:保存最大字符数,由用户给出; 第二字节:实际输入字符数,由功能A自动填入; 第三字节开始:字符串按字节顺序填入; 结束字符是回车符(Return)0DH, 它也占用一个字节, 故缓冲区空间至少应为最大字符数加3。,例4.46 设置一个缓冲区,并接收字符串 Hello . ; 字符串缓冲区定义如下: MAXLEN DB 10 ACTLEN DB ? STRING DB 10 DUP (?) ; 输入字符串的指令如下: MOV AX , SEG STRING ;Initialize DS MOV DS , AX LEA DX , MAXLEN ;Make DX point to buffer MOV AH , 0AH ;Input the string INT 21H,DOS系统0AH号功能调用之例,例如 缓冲区为10个字节,若键盘输入字符串 Hello! , 则存储示意为:,DOS系统0AH号功能调用之例,例4.47 检验键盘是否按下,只要任意键按下,程序就退出循环并返回。 SOUNDER: ; sound the tone MOV AH ,0BH ; get keyboard status INT 21H ; call DOS INC AL ; if al not 0ffh , then JNZ SOUNDER ; no key pressed RET ; key pressed return,DOS系统功能调用之例,表4.3 DOS显示功能调用( INT 21H ),DOS系统功能调用之例,例4.48 在屏幕上显示一个字符串 DATA SEGMENT MESSAGE DB HOW DO YOU DO ?, 0DH, 0AH, $ DATA ENDS CODE SEGMENT MOV AX , DATA MOV DS , AX MOV DX , OFFSET MESSAGE MOV AH , 9 INT 21H ,DOS系统功能调用之例,例4.49 利用DOS系统功能调用实现人机对话。 data segment pars db 100 db ? db 100 dup (?) mesg db what is your name ?,0dh,0ah,$ data ends stack segment para stack stack db 100 dup (?) stack ends,DOS显示功能调用之例,code segmet assume cs: code, ds: data, ss: stack start proc far push ds mov ax , 0 push ax mov ax , data mov ds , ax disp: mov dx , offset mesg mov ah , 09 ; 9号功能显示提示信息 int 21h keybd: mov dx , offset pars mov ah , 10 ; 10号功能输入字符串 int 21h ret start endp code segment end start,DOS显示功能调用之例,BIOS功能调用,BIOS( Basic input /output system ) 是驻留在系统板上ROM中的一组例行程序 BIOS提供了系统加电自检,引导装入和对主要I/O设备(如键盘,显示器, 磁盘,打印机,异步串行通信接口等) 的处理程序。 BIOS的功能可通过中断指令INT直接调用,调用格式为: 设置入口参数; 功能号送AH寄存器; 发中断请求: INT N (N为中断类型号),例4.50 清除左上角(0, 0), 右下角(24, 39)的窗口,初始化为反相显示,该窗口相当于全屏幕的左半部分。 mov ah , 7 ; scroll downward function mov al , 0 ; code to blank screen mov bh , 70h ; reverse video attribute mov ch , 0 ; upper left row mov cl , 0 ; upper left column mov dh , 24 ; lower right row mov dl , 39 ; lower right colum int 10h ; video rom call,BIOS功能调用之例,4.6 汇编程序的模块化设计,模块 能独立汇编的一个逻辑段,或者是能独立汇编的几个逻辑段的集合 在模块化程序中,只允许有一个主模块,其他均为子模块 子模块用“END”作为结束语句 主模块用“END 启动指令标号”作为源程序的结束语句。,模块的定义与连接,模块的连接是由段定义伪操作“SEGMENT”的组合类型及类别的定义来确定。它分为: PUBLIC COMMON STACK MEMORY,外部符号定义伪操作,外部符号 在某模块中定义,而在另一模块中引用的符号,PUBLIC定义 格式:PUBLIC 符号 , 功能:说明本模块的某些符号是公共的, 可提供给将被连接在一起的其他模块引用 符号是本模块中定义的变量、标号或名字 PUBLIC伪指令可安排在源程序的任意地方,EXTRN定义,格式:EXTRN 名字:类型 , 功能:说明本模块要引用的符号是由连接在一起的其他模块所定义的 (它们应被PUBLIC说明) 其中名字项可以是变量(名) 、标号、过程名 若是变量, 类型为: BYTE, WORD, DWORD 若是标号或过程名, 类型为: NEAR, FAR,模块化程序的设计考虑,合理划分模块,使每个模块有相对独立的功能,尽量减少模块之间的调用。 连接后同类逻辑段的体积不能超过64K。 要考虑模块之间的转移和调用时的类型匹配。 模块之间出现的符号名引用时必须用“PUBLIC,EXTRN”语句说明。,模块定义之例,例4.51 三个模块(module)的连接定义 ;模块1 extrn var3: word , ex1: near extrn ex2: far public

温馨提示

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

评论

0/150

提交评论