Chapter 7&8 Assembly Programming Instructor:Dr. Yu Youling
Assemble Language 一种面向机器的程序设计语言,是一种用符号表示的低级程序设计语言(机器语言的符号化描述),通常是为特定计算机或计算机系列专门设计的。 用汇编语言编写的程序不能由机器直接执行,而必须经汇编程序翻译成机器语言程序。汇编语言指令与翻译成的汇编过程示意。 2019/5/28
优缺点 优点 缺点 可充分利用机器的硬件功能和结构特点,加快程序的执行速度,减少目标程序所占用的存储空间 常用来编写实时控制程序、实时通信程序,有时也用来编制某些系统软件程序 缺点 编程效率低(与人们描述计算过程的需要差距大) 与机器硬件的具体结构联系过于紧密——在一种结构的机器上开发的程序极难移植到另一种不同结构的机器上去 2019/5/28
汇编过程 Prog.asm Prog.obj 编辑程序 汇编程序 文件 Edit.exe Masm.exe Prog.exe 连接程序 检查源程序; 测出源程序中的语法错误,并给出出错信息 产生目标文件(.OBJ), 列表文件(列出汇编语言源程序和机器语言目标程序的文件,称之为.LST文件) 交叉索引文件(列出程序中使用的符号、变量和标号以及引用情况,称之为.CRF文件)。 展开宏指令 编辑程序 Prog.asm 文件 汇编程序 Prog.obj 连接程序 Prog.exe Edit.exe Masm.exe Link.exe .OBJ .LST .CRF 2019/5/28
汇编程序 汇编程序分两种,一种是基本汇编(ASM.EXE),一种是宏汇编(MASM.EXE),宏汇编功能比较强。 汇编之后生成的OBJ文件必须经过链接过程,才能成为扩展名.EXE的可执行文件。 链接的过程就是调用连接程序(LINK.EXE),对OBJ文件进行定位、链接,最后生成扩展名为EXE的可执行文件。如果需要,也可生成MAP文件和LIB文件 2019/5/28
连接示意图: 调用LINK.EXE .OBJ .LIB 连接 .EXE .MAP 可选 2019/5/28
语句 汇编语言由指令性语句和指令性语句组成 指令性语句格式 指示性语句格式 有关属性 [标号:] 操作码 [操作数1,] [操作数2] ;[注释] 指示性语句格式 [标识符(名字)] 指示符(伪指令) 表达式 有关属性 存储器操作数的属性有三种:段值、段内偏移量和类型。 2019/5/28
伪指令 格式: NUM=34 符号定义语句 格式:符号名 EQU 表达式 例1: ⑴ PORT EQU 1234 等值语句 格式:符号名 EQU 表达式 例1: ⑴ PORT EQU 1234 ⑵ BUFF EQU PORT+58 ⑶ MEM EQU DS:[BP+20H] ⑷ COUNT EQU CX ⑸ ABC EQU AAA 等号语句 格式: NUM=34 …… NUM=34+1 2019/5/28
变量定义语句 格式: 符号名 DB/DW/DD 表达式 定义一组数据 定义一串字符 定义保留存储单元 复制操作 例2: BUFF DW 1234H, 0ABCDH, 8EH DW 79DH, 7B6AH 定义一串字符 例3: STR DB ‘ Welcome !’ 定义保留存储单元 例4: SUM DW ?,? 复制操作 复制操作符DUP(Duplication)可预置重复的数值 例5: ALL_ZERO DB 0,0,0,0,0 用复制操作可改为:ALL_ZERO DB 5 DUP(0) 2019/5/28
段定义语句 段定义语句 段定义语句格式: 段假设语句 ORG伪指令与地址计数器 $ PUBLIC和 EXTRN伪指令 段名 SEGMENT [定位类型] [组合类型] [‘类别’] …… 段名 ENDS 段假设语句 ASSUME 段寄存器名:段名[,…] ORG伪指令与地址计数器 $ ORG伪指令格式: ORG <表达式> PUBLIC和 EXTRN伪指令 2019/5/28
过程与宏 过程定义语句 宏定义语句 过程名 PROC NEAR/FAR …… RET 过程名 ENDP 宏名 MACRO PAR1,PAR2 宏名 ENDM 2019/5/28
宏指令的定义、调用和扩展 宏(MACRO)是源程序中一段有独立功能的程序代码、它只需在源程序中定义一次,就可以多次用一条宏指令来调用它。 宏定义是用伪指令来实现的。其格式为: Macro-name MACRO ּּּ ENDM [dummy Parameter List] 宏指令名 宏定义体 形式参数 (用逗号隔开) 其中MACRO和ENDM是一对伪指令,这对伪指令之间是 宏定义体——一组有独立功能的程序代码 宏指令名的第一个符号必须是字母,其后可以是字母、数字或下划线字符. 2019/5/28
宏指令的定义、调用和扩展 经宏定义定义后的宏指令就可以在源程序中调用,这种对宏指令的调用称宏调用,宏调用的格式为: Macro-name [actual parameter list](每一项之间用逗号隔开) 当源程序被汇编时,汇编程序将对每个宏调用作宏展开。 宏展开就是用宏定义体取代源程序中的宏指令名,而且用实在参数一一取代宏定义的形式参数。 2019/5/28
宏指令的定义、调用和扩展 例6 宏定义可以无变元 宏定义:SAVEREG MACRO PUSH AX PUSH BX PUSH CX PUSH DX PUSH SI PUSH DI ENDM 宏调用: SAVEREG 宏展开: 将宏定义体的内容(具有独立功能的代码段)全部列出。 宏定义开始 宏指令 宏定义体 宏定义结束 2019/5/28
宏指令的定义、调用和扩展 例7 宏定义带形式参数 宏定义: FOO MACRO P1, P2, P3 MOV AX, P1 P2 P3 ENDM 宏调用: FOO WORD_VAR, INC, AX 宏展开: + MOV AX, WORD_VAR + INC AX 2019/5/28
子程序调用和宏调用的区别 子程序调用工作方式 主程序 子程序Q(x,y) 执行时调用 X←A,y←B Q: . CALL Q RET x←C,y←D CALL Q 2019/5/28
子程序调用和宏调用的区别 宏调用工作方式 子程序Q(x,y) 主程序 汇编时展开 Q A,B Q(A,B) Q C,D Q(C,D) Q MACRO x,y 2019/5/28 ENDM
子程序调用和宏调用的区别 在处理时间上不同。 用宏指令得到的目标代码长,占内存空间大,而且宏调用的次数越多,所占内存空间越大;用子程序占内存空间小,而且不会随调用次数的增加而增加,但执行时间长。 传递参数的方式不同 2019/5/28
运算符 常用运算符 算术运算符 逻辑运算符 关系运算符 AND、OR、XOR、NOT EQ(相等)、NE(不等、) +(加)、-(减)、*(乘)、/(除)、MOD(求余)。 逻辑运算符 AND、OR、XOR、NOT 关系运算符 EQ(相等)、NE(不等、) LT(小于)、GT(大于)、 LE(小于等于)、GE(大于等于)。 例: MOV DL , 10H LT 16 例: AND AX , 555 GT 222 2019/5/28
运算符 常用运算符 分析操作符 OFFSET操作符 TYPE操作符 SEG操作符 对于变量有3种: 对于标号有2种: 例8: MOV AX , SEG BUFF OFFSET操作符 例9:MOV BX , OFFSET BUFF TYPE操作符 对于变量有3种: 1-字节型;2-字型;4-双字型; 对于标号有2种: -1-NEAR(段内), 2-FAR(段间)。 例10: BUFF DB 20H MOV BX , OFFSET BUFF MOV BX,01 2019/5/28
运算符 例11: BUFF DW 10 DIP(?) MOV CX,LENGTH BUF MOV CX,10 常用运算符 LENGTH操作符 SIZE操作符 SIZE=TYPE×LENGTH 例11: BUFF DW 10 DIP(?) MOV CX,LENGTH BUF MOV CX,10 MOV CX,SIZE BUF MOV CX,20 2019/5/28
综合运算符 PTR运算符 THIS操作符 格式: 类型 PTR 表达式 例12:INC WORD PTR [BX] 例13:FIRST EQU THIS BYTE SECOND DW 100 DUP (?) 2019/5/28
常用的汇编语言程序框架 DATA SEGMENT ;定义数据段 VAL1 DB 12H , 8EH ;定义变量 …… DATA ENDS ;数据段结束 CODE SEGMENT ;定义代码段 ASSUME DS:DATA , CS: CODE ;段属性说明 START: MOV AX , DATA ;初始化DS MOV DS , AX MOV AX , 4C00H ;返回DOS INT 21H CODE ENDS ;代码段结束 END START ;源程序结束 2019/5/28
程序设计基本步骤 分析问题 绘制流程图 编写程序 检查和调试 2019/5/28
程序的基本结构 顺序结构 循环结构 分支结构 混合结构 2019/5/28
程序设计实例 算术运算 LEA BX , ARRAY ;设数组首地址指针 DATA SEGMENT ARRAY DW 100 DUP (?) ;定义100个字型随机数 DATA ENDS CODE SEGMENT ASSUME DS:DATA,CS:CODE …… LEA BX , ARRAY ;设数组首地址指针 MOV CX , LENGTH ARRAY ;数组数据长 AA1: ADD WORD PTR [BX] , 1 ;指定为字型数加1 ADD BX , 2 ;移动地址指针 LOOP AA1 ;循环操作 2019/5/28
程序设计实例 算术运算 例15:有两个无符号字节型数组,设数组元素个数相等,编程将数组中的对应元素相加,结果存入另一内存区。 DATA SEGMENT ADC BYTE PTR[BX+1] ,0 M1 DB 20 DUP (?) ;存结果的进位 M2 DB 20 DUP(?) INC SI M3 DW 20 DUP (0) INC DI DATA ENDS ADD BX , 2 CODE SEGMENT LOOP AA1 …… LEA SI , M1 ;设数组1的地址指针 LEA DI , M2 ;设数组2的地址指针 LEA BX, M3 ;设结果区的地址指针 MOV CX , 20 AA1: MOV AL , [SI] ADD AL , [DI] MOV [BX] ,AL 2019/5/28
程序设计实例 逻辑处理 例16:将寄存器AL中高、低4位交换 …… MOV AL , 0ABH MOV CL , 4 ROL AL , CL ;移出位补充移空位4次 2019/5/28
程序设计实例 逻辑处理 例17:将AX中的内容按相反顺序存入BX中 …… MOV AL , 1234H MOV CX , 16 AA1: SHL AX , 1 ; 移出的位进到CF RCR BX , 1 ;AX中移出的位进入BX LOOP AA1 2019/5/28
程序设计实例 代码转换 例18:编程将以$结束的字符串中的小写字母改为大写字母 DATA SEGMENT SUB AL , 20H ;将小写字母改为大写 STR DB ‘heLLo,eveRyboBY !’,’$’ MOV [BX] , AL DATA ENDS NEXT: INC BX …… JMP A1 LEA BX , STR A1: MOV AL ,[BX] CMP AL , ‘$’ ;是$符,则结束 JE DONE CMP AL , ‘a’ JB NEXT ;低于,则为大写字母 CMP AL ,’z’ JA NEXT ;高于,则不是字母 2019/5/28
程序设计实例 代码转换 例19:十六进制数到十进制数的转换 除10取余法 …… MOV AX , 4B6CH MOV CX , 0 ;统计除法次数 MOV BX , 10 A1: MOV DX , 0 ;被除数扩展为32位 DIV BX PUSH DX ;将转换好的数存入堆栈 INC CX OR AX , AX ;转换直到商为0 JNZ A1 2019/5/28
程序设计实例 表格处理 明码和密码的映射关系为: 例20:编程序将0-9的数字转换成所要求的密码 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 2 7 1 6 9 0 8 3 4 5 DATA SEGMENT A1: MOV AL ,[SI ] ;取明码 TABLE DB 2,7, 1, 6 ,9, 0, 8, 3, 4, 5 ;密码表 XLAT ;转换为密码 MOV [DI] , AL VAL1 DB 8, 4, 1, 7, 5 ; 被加密码(明码) INC SI INC DI LOOP A1 VAL2 DB 5 DUP(?) DATA ENDS …… MOV SI , OFFSET VAL1 MOV DI , OFFSET VAL2 MOV CX , 5 LEA BX , TABLE ;表格首地址指针 2019/5/28
程序设计实例 数据排序 例21:编程序实现,从一串带符号字型数据中找出最大值 DATA SEGMENT JG AA2 ;前一个数大,则保留下次再比 BLOCK DW 762EH, 6A8BH, 664AH, 0B945H, 85DH MOV AX , [SI] ;否则,取后一个数 AA2: LOOP AA1 COUNT EQU ($-BLOCK)/2 DATA ENDS …… LEA SI , BLOCK MOV CX , COUNT MOV AX , [SI] ;取第1个数 DEC CX ;准备与下个数比较 AA1: ADD SI , 2 CMP AX , [SI] ;与下个数比较 2019/5/28
BIOS和DOS中断 ROM BIOS(Basic Input Output System)——装于从地址0FE00H开始的8k ROM中,提供了系统加电自检,引导装入,主要I/O设备的处理程序及接口控制等功能模块。 使用BIOS功能调用,使程序员不必了解硬件I/O的具体接口特性,可直接通过入口参数来调用,给编程带来方便。 调用格式 设置入口参数; 设置功能号; INT XXH; 例: MOV CX,0; MOV DX,0; MOV AH,1; 功能号为1 INT 1AH; 入口参数 2019/5/28
DOS 中断(DOS 系统功能调用) 指类型为21H的软件中断,其对应的中断处理程序中包含了一系列最常用的功能子程序,这些子程序分别实现外设管理、文件读/写和管理、目录管理等功能 例:在显示器上输出字符 $: MOV DL,’$’; (24H) 设置入口参数 MOV AH,6; 设置功能号为6 INT 21H; DOS系统功能调用 入口参数 2019/5/28
DOS功能调用与子程序设计 调用过程为: DOS功能调用号送AH寄存器; 如果需要,按要求给定输入参数(有的不需要输入参数); 写入中断指令INT 21H。 调用结束,按功能使用其输出参数。 2019/5/28
常用DOS中断 1号中断,单字符输入 2号中断,单字符输出 功能:从键盘输入1个字符 输入参数:无 输出参数:AL=ASCII码 输入参数:DL=ASCII码 输出参数:无 2019/5/28
程序设计实例 数据输入与显示 例22:从键盘输入两个1位十进制数,求两数之和并在屏幕上显示结果 MOV AH , 1 ;DOS调用输入第一个数 INT 21H MOV BL , AL ;保存输入的第一个数 MOV AH , 1 ADD AL , BL;两个ASCII码相加 AAA ;调整加法结果为非压缩BCD数 MOV DL , AL ADD DL , 30H ;加法结果转换成ASCII码 MOV AH , 2 ;DOS调用输出到屏幕 2019/5/28
常用DOS中断 0AH号中断,多字符输入 9号中断,多字符输出 功能: 多个字符输入到缓冲区 输入参数:DS:DX=输入缓冲区首地址 功能:多个字符输出到屏幕显示 输入参数:DS:DX=输出字符缓冲区首地址 输出参数:无 2019/5/28
程序设计实例 数据输入与显示 例23:在屏幕上显示一串字符 DATA SEGMENT BUFF DB ‘How do you do?’,0DH,0AH,’$’ DATA ENDS CODE SEGMENT ASSUME DS:DATA,CS:CODE START: MOV AX , DATA MOV DS , AX LEA DX , BUFF MOV AH , 9 INT 21H …… 2019/5/28
常用DOS中断 6H号中断,单字符输入输出 4CH号中断,过程终止 6号DOS功能实际上是1号和2号功能的组合 当DL寄存器的内容为0FFH时,6号功能与1号功能同,即从键盘输入单个字符 当DL寄存器中放入字符的ASCII值,它就是2号功能 4CH号中断,过程终止 该调用的功能是结束当前程序,并返回调用它的程序 如在DEBUG状态下运行,则返回DEBUG 如果在DOS下运行,则返回DOS。 在汇编语言程序结束处放上MOV AX ,4C00H和INT 21H两条指令,以利于程序执行完毕,返回操作系统控制 2019/5/28
DOS功能调用与子程序设计 设计子程序要提供以下信息: 子程序的功能 调用时需要的输入参数(入口参数) 调用后提供的输出参数(出口参数) 子程序中所使用的寄存器(以便调用前做必要的保护) 2019/5/28
程序设计实例 数据编码转换 例24:编写一子程序,完成一个2位十六进制数到对应的ASCII码的转换 子程序名: CONHA 输入参数: AL=待转换的数 输出参数: BX=转换好的ASCII码 使用寄存器:AL、AH、BX、CL 2019/5/28
程序设计实例 数据编码转换 例24:编写一子程序,完成一个2位十六进制数到对应的ASCII码的转换 CONHA PROC FAR ADD AH , 07 ;是,先加7 MOV AH, AL ;保存待转换的数 ASC2: ADD AH, 30H AND AL, 0FH ;处理十六进制数低位 MOV BH , AH ;保存转换好的高位 CMP AL, 0AH ;是16进制中的字母吗? RET JB ASC1 ;否,转移 CONHA ENDP ADD AL , 07 ;是,先加7 ASC1: ADD AL , 30H ;转换为ASCII码 MOV BL , AL ;保存转换好的低位 MOV CL , 4 ;移位控制 SHR AH , CL ;将原数右移,处理高位 CMP AH, 0AH ;是16进制中的字母吗? JB ASC2 ;否,转移 2019/5/28
程序设计实例 数据输入 例25:用子程序调用形式,编写从键盘输入4位16进制数的程序。 子程序名: ZH 功能:检查键盘输入错误,将键入值转换成16进制数 输入参数:AL 输出参数:AL 使用寄存器:BX,CX 2019/5/28
程序设计实例 数据输入 例25:用子程序调用形式,编写从键盘输入4位16进制数的程序。 CODE SEGMENT JBE A2 ;键入值≤’9’(‘0’-‘9’)则减30H ASSUME CS :CODE CMP AL, ‘a’ ;键入值<’a’(‘A’-‘F’) 则减37H JB A1 START: MOV CX , 4 ;输入4次 SUB AL, 20H;值在’a’ -‘f’则先减20H,再减37H MOV DX , CX ; 转换4次 A1: SUB AL , 7 MOV BX , 0 ;用BX保存输入数 A2: SUB AL , 30H RET RE1: MOV AH , 1 ; 从键盘输入 ZH ENDP INT 21H CALL ZH ;通过子程序转换 CODE ENDS SHL BX , CL ;组合成16进制数 END START ADD BL , AL DEC DX MOV AX , 4C00H JNZ RE1 ;循环输入4个数 INT 21H ZH PROC CMP AL , ‘9’;将ASCII码转换为16进制 2019/5/28