1、1,第四章 汇编语言程序格式, 汇编程序功能 汇编语言程序格式 伪操作 操作符 上机过程,2,程序功能(Masm,Link),Edit progr,Progr.asm,Progr.obj,汇编程序(masm),Progr.exe,连接程序(Link),3,2.汇编语言程序格式汇编语言语句可由四项组成 格式为:名字 操作项 操作数 ; 注释MASM对语句格式的要求:1)大小写无关。2)每条语句必须占行,但可以使用续行符“”。3)为了提高可读性,应该使各个域对齐。,指令 伪操作(伪指令) 宏指令,操作所需信息,标号和变量,例: D1 segmentascstr db comput a D1 end
2、s Code1 segment.mov si ,-1mov al ,20h Next: inc si,4,变量与标号的3种属性:段地址、偏移地址、类型。变量的类型包括BYTE(字节)、WORD(字)、DWORD(双字)等。 . 标号的类型包括NEAR(表示在本段内引用)和FAR(表示在其他段中引用) 。地址表达式。 地址表达式的基本形式为:变量名或标号名 常数其类型由相应的变量或标号确定。 两个地址表达式的差表示两个地址之间的距离(字节数),两个地址必须在同一个段内。注意,不能将两个地址表达式相加。$是一个特殊的地址表达式,表示当前地址,即地址计数器的当前值。,如:mov bx ,block+
3、10,5,操作项,指令 伪操作(伪指令) 宏指令,伪操作: 汇编期间由汇编程序(MASM)处理的操作。数据定义分配存储区指示程序结束。,6,2. 伪操作, 处理器选择伪指令段定义伪指令ASSUME伪指令程序开始/结束伪指令数据定义及存储器分配伪指令表达式赋值伪指令 EQU地址计数器与对准伪指令LABEL伪指令,7,. 处理器选择伪指令,主要包括:.8086 .286 .286P .386 .386P.486 .486P .586 .586P .686 .686P在缺省方式下,MASM只承认8086指令。为了使用更高的CPU指令,必须使用处理器选择伪指令,分别表示其后面的代码使用相应CPU的指令
4、。其中,结尾的P表示使用特权指令。若使用32位CPU新增指令以及寄存器或内存寻址方式,则至少要用.386 伪指令。 一般放在程序最前,也可放在某条指令之前。,8,. 段定义伪指令 基本形式:段名 SEGMENT STACK USE16段名 ENDS其中,STACK仅用于堆栈段。USE16指出使用16位段。注意:(1)在实模式下,只能使用16位段,而32位段只能用于保护模式程序。故USE16可缺省(2)段名作为操作数 出现在指令中时,MASM 将其视为立即数,表示段 地址。,D1 segmentascstr db comput a D1 ends Code1 segmentASSUME CS:C
5、ode1, DS:D1mov ax , D1mov ds , ax Code1 ends,9,. ASSUME伪指令 基本形式:ASSUME 段寄存器名:段名, , 段寄存器名:段名功能: 指明段与段寄存器之间的对应关系.即告诉MASM某 个段的段地址在哪个段寄存器里。 当程序定义一个段后,需要告诉汇编器该段的段地址在哪个段寄存器中。ASSUME就提供这种信息。例如:ASSUME CS:CSEG, DS:DSEG, ES:ESEG, SS:SSEG 指出CSEG、DSEG、ESEG和SSEG分别为代码段、数据段、附加段和堆栈段。,10,例:d1 segment ;define data seg
6、ment.d1 ends d2 segment ;define extra segment.d2 ends code1 segment ;define code segmentassume cs:code1,ds:d1,es:d2 .code1 ends,11,程序开始/结束伪指令,结束伪指令 基本形式:END 地址功能:表示汇编语言源程序到此结束,对END之后的语句不再进行汇编。可选的地址指出程序执行的起始点,通常是标号或过程名。 若程序包含多个源文件,则每个源文件的最后必须有一条END语句,但只有主模块文件可以指出执行的起始地址。,12,开始伪指令 基本形式:NAME 模块名功能:为模块起
7、名字。也可用: TITLE text他们并非必须。,13, 数据定义及存储器分配伪指令(变量定义伪指令),功能:为数据分配内存空间,并设置相应内存单元的初始值。形式:变量名 变量定义符 操作数,操作数变量名是一个符号地址,表示其后操作数的首地址, 变量名为可选项,给出变量名只是为了按名存取其对应的内存单元。,14,例:编写一段显示字符串STRING的程序DATA SEGMENTSTRING DB HAPPY NEW YEAR!, 0DH , 0AH , $ COUNT DW 17DATA ENDS . . . 变量名 变量定义符 操作数,操作数,15,变量定义符主要包括下列几种:DB(Defi
8、ne Byte):定义字节,后面的每个操作数占1个 字节。DW(Define Word):定义字,后面的每个操作数占1个字。DD(Define Dword):定义双字,后面的每个操作数占2 个字。操作数可以是常数、 用EQU或=定义的符号常量、 表达式、 ?和DUP子句等。其中,?表示只保留内存空间,未定义初始值。复制操作符DUP子句的格式为: 重复次数 DUP (操作数,操作数),16,Such as: DATA SEGMENT D1 db 10,10H D2 dw -5 D3 dd 3*20, 0FFFDH DATA ENDS,0aH 10H FB FF 3C 00 00 00 FD FF
9、 00 00,D1,D2,D3,60d=0000003cH,操作数可以是 表达式,17,Such as: DATA SEGMENT a1 db 2 DUP(0, 2, ?) a2 db 100 DUP(?) DATA ENDS,0 20 2. .,a1,a2,操作数可以是 复制操作符DUP,100个字节单元,18,说明: (1)变量可以定义在任何段(包括代码段),但一般定义在数据段。 (2)用DB/DW/DD/DQ/DT定义的数据在内存按“低字节在低地址”的方式存放例如: S1 DB AB ; 等价于 S1 DB 41H, 42H S2 DW AB ; 等价于 S2 DW 4142H,S1S2
10、,41H 42H 42H 41H,19,(3)可以用DW把变量或标号的偏移地址存入存储器。 (4) 可以用DD把变量或标号的段地址和偏移地址存入存储器(段地址在高字,偏移地址在低字)。例如:X DB 10 ADDR1 DW X ADDR2 DD X ADDR1的内容(字)为变量X的偏移地址ADDR2的高字为X的段地址,低字为X的偏移地址,x ADDR1ADDR2,0AH 02H 00H 02H 00H 00H 20H,2000:0002,20,(5)MASM是强类型的。即: 变量在定义后,其类型便被确定,使用时要注意类型匹配。例如:OP1 DB ?, ?OP2 DW ?, ?下列两条指令执行不
11、同类型的操作:MOV OP1 + 1, 0 ; 字节操作指令,将0作为1 个字节送到地址OP1 + 1MOV OP2 + 2, 0 ; 字操作指令,将0作为1个字送到地址OP2 + 2,21,下列两条指令是错误的:MOV OP1, AX ; 类型不匹配MOV OP2, AL ; 类型不匹配若希望进行与变量类型不一致的操作,例如,对字变量实施字节操作,如何处理?可以采用后面要介绍的类型操作符PTR等。,22, 表达式赋值伪指令 EQU(符号定义伪指令 ),基本形式:符号名 EQU 表达式符号名 = 常数表达式功能:给表达式指定一个名字(当程序中多次出现同一个表达式时,更加方便)。说明: (1)=
12、 后的表达式只能是常数,对于字符或字符串,汇编时按整数处理。例如: COUNT = 20 MOV CX, COUNT ; 等价于MOV CX, 20(2)EQU后的表达式可以是数值、字符串、寄存器名、指令助记符等。,23,例: ALPHA EQU 7Beta EQU ALPHA+8(3)EQU不能重复定义,而 = 可重复定义,其作用域从定义点到重新定义之前。Such as:.E=7.E=E+1.,24, 地址计数器与对准伪指令1. 地址计数器2. ORG伪指令3. EVEN伪指令,地址计数器 ( $ 的使用)$ -地址计数器的值 Such as1:Jne $+6 ;跳转到这条指令的首地址加6的
13、地址.Jne-运算结果不相等时则转移(ZF=0),25,Such as2:array dw 1, 2, $+4, 3, $+4,array,01H 00H 02H 00H 7cH 00H 03H 00H 80H 00H,0074H 0075 0076 0077 0078 0079 007a 007b 007c,26,2. ORG通常,段中的数据或指令是按顺序一个接着一个存放的。ORG可以设置数据或代码的偏移地址。形式:ORG 常数表达式功能 :设置其后数据或代码的起始偏移地址为n (n为常数表达式的值)。也就是将地址计数器的值置为n。,27,【例】 已知下列数据段,指出变量V1、V2的偏移地址
14、。data segment org 200hv1 dw 1,2 org $ + 4 v2 db 6 data ends,v1 v2,01H 00H 02H 00H06H,0200H 0201 0202 0203 0204 0205 0206 0207 0208,28,3。EVEN伪指令使其后的地址从偶数开始.Such as:data segment org 200hv1 db 1 ;EA=0200Heven v2 dw 6 ;EA=0202Hdata ends,29, LABEL伪指令基本形式:名字 LABEL 类型功能:指定名字的类型,地址由所在 位置确定。然而,并不为名字分配内存空间。说明
15、:当类型是BYTE、WORD、DWORD时,名字作为相应类型的变量;当类型是NEAR或FAR时,名字作为相应类型的标 号。,30,【例】 定义地址相同、类型不同的两个变量。ba label bytewa dw 50 dup (?)将100个字节的数组首地址赋予两个不同类型的变量:字节类型变量BA与字类型变量WA。尽管WA + 2与BA + 2指向同一内存地址,但下列两条指令的操作类型不同:mov wa + 2, 0 ; 将0作为1个字送到; 地址wa + 2mov ba + 2, 0 ; 将0作为1个字节送到地址 ; ba + 2,ba wa,00H 00H,31,汇编语言语句可由四项组成 格
16、式为:名字 操作项 操作数 ; 注释,指令 伪操作(伪指令) 宏指令,操作所需信息(一项/多项) 可以是:常数寄存器 标号变量表达式,标号和变量,表达式:常数,寄存器, 标号,变量与操作符组合构成,32,4. 操作符,.算术操作符(+ , - , * , / , MOD ),.逻辑( AND,)与移位(,)操作符,.关系操作符 (),(),(),(),(=),。数值回送操作符(地址操作符) 。属性操作符,NEXT,33,。数值回送操作符(地址操作符) 数值回送操作符的返回值都是数值,相当于立即数,是汇编时由MASM自动计算的。 (1)SEG 形式:SEG 地址表达式 功能:返回地址表达式的段地
17、址,作为立即数使用(汇编时求值)。(2)OFFSET 形式:OFFSET 地址表达式 功能:返回地址表达式的偏移地址,作为立即数使用(汇编时求值)。,34,Such as1:已知 数据段从05000H起( 即(ds)=0500H ).oper1在数据段中已定义。 则mov bx , SEG oper1 ;使(bx)=0500HSuch as2: mov bx , OFFSET oper1 ;使(bx)=oper1的偏址;等效与 lea bx, oper1,35,(3)TYPE、SIZE和LENGTH 形式:TYPE 变量 / 标号SIZE 变量 LENGTH 变量 功能:TYPE返回一个常数,
18、表示变量/标号的类型。对于变量, DB为1,DW为2,DD为4;对于标号 NEAR为-1 ,FAR为-2 。LENGTH使用dup时,返回分配给该变量的单元数。其他情况返回1SIZE返回直接分配给指定变量的字节数。SIZE=LENGTHTYPE,36,Such as: Array dw 1,2,3. Add si , type array,Add si , 2,汇编后,Such as:a1 dd ?, 10 dup(0) Type: 4 .length: 1 , size : 4,37,d1 segmentta dw 10 dup(1)tb db 10 dup(2)tc db 1234td d
19、d ?,10 dup(3) d1 ends code1 segmentassume cs:code1;ds:d1 start: mov ax, d1mov ds, axmov dx, length ta ;汇编成 mov dx, 0ah mov bl, length tb ;(bl)=0ahmov cl, length tc ;(cl)=1mov al, length td ;(al)=1MOV AL, TYPE TA ;(AL)=2MOV AL, TYPE TB ;(AL)=1MOV AL, SIZE TA ;(AL)=LENGTH*TYPE=10*2=14HMOV AL, SIZE TD
20、;(AL)=LENGTH*TYPE=1*4=4mov ah,4chint 21h code1 endsend start,参看习题 4.13,38,。属性操作符(类型操作符)(1)PTR 形式:类型 PTR 内存操作数或标号功能:返回一个指定类型的内存操作数或标号,而地址不变。对于内存操作数,类型包括BYTE、WORD、DWORD等。对于标号,类型包 括NEAR和FAR。说明:PTR只是临时改变操作数的类型,类似于C语言的强制类型转换。,39,何时需要PTR? (1)要转换为一种新类型时 Such as:X 是字变量MOV X , 5 ;(X)=0005H MOV BYTE PTR X , 5
21、 ;(X)=05H(2) 指令类型不确定时,需要明确指出。SUCH AS:MOV BX , 5 MOV BYTE PTR BX , 5 MOV WORD PTR BX , 5 ,40,(2)THIS形式: THIS 类型功能:返回一个指定类型的内存操作数或标号,地址由所在位置确定,即地址计数器的当前值。,【例】设有如下定义:WordVar dw 10 dup (?)欲将WordVar的第0个字节置为1,如何处理?,方法1:用PTR操作符。WordVar dw 10 dup (?)mov byte ptr WordVar, 1 方法2:用THIS与EQU。ByteVar equ this byt
22、eWordVar dw 10 dup (?)mov ByteVar, 1,41,5.上机过程源程序的一般结构源程序由若干个代码段、数据段、附加段和堆栈段组成。 段之间的顺序可以随意安排。通常需要一个代码段、一个数据段和一个堆栈段,有时 可包含一个附加段。,42,源程序的基本框架.386 ; 若干符号定义 dseg segment ; 数据定义(DB/DW/DD) dseg endseseg segment ; 数据定义(DB/DW/DD) eseg ends,sseg segment stack dw 512 dup ( ? )sseg ends,43,cseg segment assume
23、cs:cseg, ds:dseg, es:eseg, ss:sseg start: mov ax, dsegmov ds, axmov ax, eseg mov es, ax,. . . ; 指令序列. . . . . .mov ah, 4chint 21h ; 程序退出,返回DOS cseg endsend start,44,说明 (1)为什么要用ASSUME语句?每当MASM遇到一个变量名时,首先检查看哪个段定义 了该变量。例如,遇到指令MOV TABLE,0 时,MASM首先确定TABLE所在的段。然后,看该段是否已在ASSUME语句中声明。若未声明,则显示错误信息“不能访问该变量”;若
24、该段不对应于DS,假设对应于ES,则 MASM产生一个段超越前缀ES:,即MOV ES:TABLE, 0注意,ASSUME只是告诉汇编器段寄存器指向哪个段,并不设置段寄存器的值。,45,(2)设置段寄存器的初值。CS与IP的初值不能在程序中显式设置,由系统自动设置。 通常有如下几种情况:A) .用户程序END后有标号或过程名, .EXE程序自动将该标号或过程名的分段地址 CS:IP 。end start B). 遇JMP及CALL指令时,自动修正CS,IP的值C). 当用INT nH或产生硬件中断时, CS=4*n+2 , IP=4*n 硬件复位时,自动实现CS=0FFFFH,IP=0,指向R
25、OM中的初始化程序。,46,DS、ES的初值必须在程序中设置。 由SEGMENG/ENDS定义的段名是作为一个立即数看待的,表示段的段基值。但立即数不能直接送段寄存器,所以段名先16位通寄(AX,BX等)DS或ES。SS与SP的初值可在程序中显式设置。然而,若堆栈段定义时给出了属性STACK,则由系统自动设置。,sseg segment dw 512 dup ( ? )tos label word sseg ends。,mov ax, sseg mov ss, ax mov sp, offset tos,512个字,(ss):0000,(sp),47,【例】设置段寄存器的初值一例 DATA S
26、EGMENTA DW 0,1,2 DATA ENDS STACK1 SEGMENTSTA DW 50 DUP(?)TOP LABEL WORD STACK1 ENDS CODE SEGMENTASSUME CS:CODE,DS:DATA,ES:DATA,SS:STACK1 START: MOV AX,DATA ;DS的初始化MOV DS,AX,MOV ES,AX MOV AX,STACK1 ;SS的初始化 MOV SS,AX MOV SP,OFFSET TOP ;栈顶的偏移 ; 量SP CODE ENDS END START,48,. 具体上机过程 命令行方式: (1) 源程序的编辑(建立.a
27、sm文件)C:EDIT (2)源程序的汇编(用MASM程序产生.obj文件)C:MASM e423.asm (3)目标文件的连接(用LINK程序产生.exe文件)C:LINK e423.obj (4)可执行文件的运行C:e423 (5)可执行文件的调试C:DEBUG e423.exe,MASM6.11 的集成化环境C:MASM611BINPWB用鼠标点击相应目录下的pwb,49,补充内容: 1. DOS下汇编语言程序的正常结束方式方法一:当主程序不定义为过程时,不需保存PSP首址,用DOS的4CH功能调用 MOV AH,4CHINT 21H方法二:当主程序定义为过程时,需保存PSP首址,用RE
28、T返回( p144(P111)的例 )。,50,补充内容,2.PSP 程序段前缀汇编语言程序汇编、连接后生成.EXE文件,DOS执行.EXE文件时,首先由DOS的命令处理程序(COMMAN.COM)从内存的用户存储区的第一个地址开始建立一个有256B的PSP,它存有执行程序的有关信息,向被执行程序传送一些参数和提供程序正常结束时返回DOS的途径。建立PSP后,DOS便将可执行程序装入内存,由DOS自动设置寄存器的值。DS和ES指向PSP的开始位置,CS指向代码段,设堆栈段组合类型为STACK,SS指向堆栈段,SP设置成堆栈长度。可执行的第一条指令地址IP。在PSP的开始处,即DS:0处是指令
29、INT 20H, (DOS程序结束中断) 执行INT 20H可返回DOS,所以保存PSP首址即将DS:0入栈。保存了PSP首址,可用RET 返回。RET指令功能: 堆栈中的PSP首址CS:IP,转到PSP的开始处, 执行INT 20H。,51,3. . EXE文件和. .COM 文件的特点 .EXE文件的程序结构,一般要定义一个数据段和一个代码段,根据需要还可定义堆栈段和附加段。通常指令放在代码段,变量放在数据段。程序的最大长度可达256KB,便于组织大型的应用程序。程序中不需用ORG重定位。 .COM文件只有一个代码段,并限制在64KB之内,程序中不能分段重定位。堆栈段由DOS 自动产生,数
30、据定义在代码段内。COM程序不必初始化寄存器,操作系统将所有段寄存器设置为PSP(程序段前缀)的地址。COM程序总是从偏移地址100H开始执行,需用ORG伪指令定位。 .EXE文件可由EXE2BIN程序转换成.COM文件,补充内容,52,【例】将字变量A的内容取反送B.EXE文件格式的程序:DATA SEGMENTA DW 50HB DW ?DATA ENDSSTACK SEGMENTSTA DB 20 DUP(?)TOP EQU LENGTH STASTACK ENDS,补充内容,53,CODE SEGMENTASSUME CS:CODE,DS:DATA,ES:DATA,SS:STACK S
31、TART:MOV AX,DATA ;DS的初始化MOV DS,AXMOV AX,STACK ;SS的初始化MOV SS,AXMOV SP,OFFSET TOP ;栈顶的偏移量SPMOV AX,ANOT AXMOV B,AXMOV AH,4CHINT 21H CODE ENDS END START,补充内容,54,CODE SEGMENTASSUME CS:CODEORG 100H BEGIN:JMP STARTA DW 50HB DW ? START:MOV AX,ANOT AXMOV B,AXMOV AH,4CHINT 21HCODE ENDS END START,.COM文件格式的程序:,
32、CODE SEGMENTA DW 50HB DW?ASSUME CS:CODEORG 100H START:MOV AX,ANOT AXMOV B,AXMOV AH,4CHINT 21HCODE ENDS END START,55,定位类型:指定实际段起始地址的边界。 PAGE 页边界00H PARA 段边界0H WORD 偶地址边界 BYTE 任意地址边界 组合类型:指定与同名段连接的方式 PUBLIC 同名段连接成一个物理段 COMMON 同名段重叠在一起成一个段 STACK 各堆栈段紧接着组成一个堆栈段 MEMORY 该段装入模块的最高地址 AT 指定段的起始地址,但不能指定代码段 类别
33、“class”,同类别的段装配在相邻的位置,4. 段的定义中的定位类型和组合类型(p101),连接程序把本程序与其他程序模块相连接时用,56,本章小结,构成汇编语言源程序的基本成分是指令和伪指令。汇编器在汇编每个段时,由地址计数器跟踪代码或数据的偏移地址。在生成可执行文件后,代码或数据的偏移地址已确定,但段地址只有在装入内存运行时,根据实际的装入地址才能确定,也就是说,需要重定位。变量与标号均为符号地址,都具有3种属性:段地址、偏移地址和类型。变量的类型包括BYTE、WORD、DWORD等,标号的类型分为NEAR和FAR。大多数程序包含一个代码段、一个数据段和一个堆栈段。用汇编语言开发程序,需要经过编辑、汇编、连接、试运行和调试的过程, 通常可能要反复多次,直到满足功能需求为止。,57,第四章作业,4.1 , 4.2, 4.3 ,4.4 , 4.5 ,4.8,上机题:3.18 , 3.38(3.47) , 4.11 , 4.17(4.18)5.1 ,5.3 , 5.4,5.17 , 5.20 , 5.23 在最后一次上课时(17周)交5.17 , 5.20 , 5.23 题的实 验报告 内容包括:题目,程序清单,程序注释,程序调试中 所遇到的问题及解决方法。 其他题目将在上机课 时提问。(实验占30分),