除串操作指令外,所有指令只允许有一个操作数在存储器中。
1. 传送类指令
(数据传送指令,专用累加器传送指令,标志位传送指令,地址传送指令)
(一) 数据传送指令
(1) MOV数据传送指令
指令格式:MOV DST,SRC;
操作数可以是字节、字,源、目的操作数位数必须一致且不能同时在存储器中。
源操作数:可在通用R、段R、存储器中、或为立即数。
目的操作数:不能为立即数。
目的地址是段R名时,源操作数不能是立即数(立即数不能直接传给段R)段R间不能直接传送数据。
例 1:立即数送R或存储单元
• MOV AH,2AH; 字节传送;
• MOV CX,1234H; 字传送;
• MOV DA_BYTE, 02FH; 字节传送;
• MOV DA_WORD,1020H; 字传送;
例 2: 寄存器之间传送 MOV AL, BL; MOV ES, AX;
例 3:R 与 M 之间传送。 MOV AL, DB_BYTE
例 4: 把DA_BYTE1字节单元内容传送到DA_BYTE2字节单元中。
MOV AH, DA_BYTE1
MOV DA_BYTE2, AH
例 5: 把立即数1020H传送给DS ,ES。
MOV AX , 1020H
MOV DS , AX
MOV ES , AX
(2)XCHG交换指令
XCHG DST, SRC
☐(SRC DST) 将源地址的内容与目的地址内容相互交换。
☐交换数据可为字、字节,只能在通用R之间或R 与M 之间进行。不能使用段R、立即数。
例、数据段中定义了两个字变量VAR1和VAR2,(VAR1)= 1234H,(VAR2)= 5678H;
将这两个字单元内容互换。
MOV AX,VAR1 XCHG VAR2,AX MOV VAR1,AX(或:XCHG VAR1,AX)
(3)PUSH进栈指令 格式:PUSH SRC
<1> 8086的堆栈由SS指定的一段存储器( KB)构成。
自下向上生成的堆栈。 SP初始化:堆栈段长(MAX:FFFFH)
SP初始值指向:(SS)*16 + 段长;(即:栈底+2单元
<2> 8086/8088堆栈规定:以字(2个字节)为单位进行存取。
低地址存放字的低字节单元的内容; 高地址存放字的高字节单元的内容。
<3> 堆栈操作:
设置堆栈:对堆栈段R(SS)及堆栈指针(SP)赋初值。编程设置堆栈段。
(4)POP出栈指令 格式:POP DST
(5)、IN(input)输入指令
1、直接I/O端口寻址方式:
IN AL,pn (字节) IN AX,pn (字)
指令功能:AL/AX ←(pn);其中:pn表示I/O端口地址(或称作:I/O端口号)。
2、间接I/O端口寻址方式:
IN AL,DX (字节) IN AX,DX (字)
指令功能:AL/AX ←(DX);其中:DX中的内容为I/O端口地址。
例、把I/O端口379H的字节内容传送到主存数据段的VARBYTE字节单元中。
MOV DX,379H
IN AL,DX
MOV VARBYTE,AL
(6)OUT(output)输出指令
1、直接I/O端口寻址方式:
OUT pn,AL (字节) OUT pn,AX (字)
指令功能:pn ←(AL/AX);其中:pn表示I/O端口地址(或称作:I/O端口号)。
2、间接I/O端口寻址方式:
OUT DX,AL (字节) OUT DX,AX (字)
指令功能:DX ←(AL/AX);其中:DX中的内容为I/O端口地址。
例、 把主存数据段的VARBYTE字节单元中的内容传送到I/O端口230H中。
MOV DX,230H
MOV AL,VARBYTE
OUT DX,AL
(7)XLAT(translate)换码指令
指令格式:XLAT [TABADDR]
指令功能:AL ←((BX)+(AL))
其中: [TABADDR]中的方括号表示本项内容可以省略,TABADDR表示换码表首地址的符号地址。BX的内容为换码表的首地址在数据段中的偏移量,AL的内容是相对于表格首地址的偏移量。
例、 把十进制数“3”转换为相应的ASCII码。
在主存的数据段设置一个转换表,内容为09的ASCII码(30H39H),表名为TAB1,位于数据段偏移2字节处,假定(DS)=1200H。可用下述指令完成转换:
MOV BX,0002H
MOV AL,3
XLAT TAB1
指令执行后,(AL)=33H,即:十进制数“3”的ASCII码。
(二)标志位传送指令 对标志位进行存取操作,无操作数
(1)取标志指令LAHF:将标志R的低八位传送到AH中。
(2)存标志指令SAHF:将AH内容传送给标志R的低八位。
(设置或恢复SF、ZF、AF、PF、CF,对高八位无影响)。
例:将标志R的低8位清0 。
MOV AH ,00H; SAHF
(3)标志R进栈指令:PUSHF
16位标志R内容送SP所指栈顶字单元中。
(4)标志R出栈指令:POPF
栈顶字单元内容弹出到标志R中。
(三)地址传送指令
将存储器操作数的地址(偏移量、段基值)传送给R。
(1)装入有效地址指令
LEA DST,SRC; 将源OP数的有效地址(偏移量)传送到目的地址中。
例: LEA SI ,BUF;
• 源操作数须是存储器操作数(可以是字节也可以是字) 。
• 目的操作数只能是16位通用R。
(2)装入地址指针指令(LDS/LES)
存储单元的地址指针:4个字节
段基值:存于2个高字节单元中
偏移量:存于2个低字节单元中
指令功能:从存放地址指针的4个字节存储单元中,同时取出段基值和偏移量,分别送到段R(DS/ES)和通用R中。
LDS DST ,SRC; 从存放地址指针的4个单元中,同时取出
•LES DST ,SRC; 段基值→ DS(ES) 偏移量→ 通用R
SRC: 存储器OP数 DST: 16位通用R
例: LDS SI, ADDR_TABLE[BX];
• DS:ADDR_TABLE[BX]中存放的偏移量→ SI,新的段基值→ DS。
2、算术运算类指令
(一)加法运算指令
(1)加法指令
指令格式: ADD DST, SRC; (SRC)+(DST) → DST
设置标志寄存器的OF、SF、ZF、AF、PF、CF标志位。
源操作数:可在通用R、存储单元中,或为立即数。
目的操作数: 在通用R或存储单元中。
(2)带进位加法指令
指令格式:
ADC DST,SRC; (SRC)+(DST)+CF → DST (主要用于大于16位数的加法运算)
例:32位无符号数存放在DX(高16),AX(低16位)中,若要加上常数76F1A23H,则用下述指令实现: ADD AX,1A23H
ADC DX,76FH;(将低16位进位加上)
(3)加“1”指令: 指令格式:INC DST;(不影响CF)
(DST)+1 → DST (OP数:字、字节、无符号数 )
只能在通用寄存器或存储单元中,不能是立即数。主要用于计数或修改地址指针。
(二)减法运算指令
(1)减法指令
指令格式: SUB DST , SRC; (DST)-(SRC) → DST
例:SUB AL,DA_BYTE;
(AL)-(DA_BYTE) → AL
(2)带借位减法指令 指令格式: SBB DST, SRC; (DST)-(SRC)-CF → DST
(3)减“1”指令 指令格式: DEC DST;
(DST)-1 → DST(不影响CF) (OP数:字、字节、无符号数 )
只能在通用寄存器或存储单元中,不能是立即数。
主要用于计数或修改地址指针。
(4)求负数指令 指令格式: NEG DST; 0-(DST) → DST
• 字节操作数:-128;字操作数:-32768;执行NEG后,操作数不变,OF置“1”。
• 操作数为0,NEG后仍为0,CF置0;否则CF置1。
例: (AL)=25H=(00100101)2
• NEG AL; (AL)=DBH=(11011011)2
(5)比较指令
指令格式: CMP DST,SRC; (DST)-(SRC) →置标志位 ,不保留两数相减结果
若:ZF=1,则(DST)=(SRC)
无符号数: CF=0:(DST)≥(SRC);
带符号数: OF=SF:(DST)>(SRC); OF≠SF:(DST)<(SRC);
(三)乘法指令
(1)无符号数乘法指令
指令格式: MUL SRC ; (另一操作数在AL或AX中)
•字节无符号数相乘:(SRC)*(AL) → AX;
• AH为全0 , CF=OF=0; 否则:CF=OF=1 ;
• 字无符号数相乘 :(SRC)*(AX) → DX: AX;
• DX为全0, CF=OF=0;否则: CF=OF=1;
• 只影响CF,OF标志位。
例: 两个字节存储单元BYTE1、BYTE2内容(无符号数)相乘,乘积放在字单元PROC中。 MOV AL,BYTE2
MUL BYTE1
MOV PROC,AX
(2)带符号数乘法指令
指令格式 :IMUL SRC;
操作数及乘积均带符号,且用补码表示。若乘积的高半字AH(字节乘法)、或DX(字乘法)不是低半部的符号扩展,则为乘积的符号和有效数:CF=OF=1;否则,CF=OF=0。
(四)除法指令
(1)无符号数除法指令 指令格式: DIV SRC;
SRC存除数,8位(字节)或16位(字)
字节除法:(AX)/(SRC) → AL, 余数→ AH
字除法:(DX:AX)/(SRC) → AX, 余数→ DX
当:除数为0,即(SRC)=0 ;或商溢出:即(AL)>0FFH 或 (AX)>0FFFFH ;
产生0型中断(除法出错中断)。
(2)带符号数除法指令 指令格式: IDIV SRC
操作数、商及余数均带符号且用补码表示。
当除数为0 或商超出最大值或最小值时,产生0型中断。
最大正数商:+127(字节),+32767(字) 最小负数商:-128(字节), -32768(字)
(五)类型转换指令
指令格式:CBW/CWD;隐含使用AH/DX
CBW :扩展AL中的符号位至AH中
CWD:扩展AX中的符号位至DX中
例: 两个8位带符号数存于BYTE1,BYTE2字节单元中,将BYTE1除以BYTE2,商放入QUOT字节单元中。
MOV AL , BYTE1 CBW IDIV BYTE2 MOV QUOT , AL
3.逻辑运算类指令
(一)逻辑运算指令(按位进行逻辑运算)
指令格式:
逻辑与:AND DST ,SRC; SF,ZF,PF 逻辑或:OR DST,SRC;
按结果设定 逻辑异或:XOR DST,SRC; CF,OF总为0 AF不确定
逻辑非指令:NOT DST; 对标志位无影响
例: (AL)=10100101, AND AL,0FH 指令运算结果:
( AL ) = 10100101
∧ 0F = 00001111
——————————
00000101 → AL
标志位:SF=0,ZF=0,PF=1
例:AL中最高位置1; OR AL ,80H
例: AL中最低位求反 ; XOR AL ,01H
(二)测试指令
指令格式: TEST DST, SRC; 按位与,结果不送DST(同AND)影响 SF,ZF,PF。
例:测试AL的第3位是否为0;TEST AL,08H; ZF=1: 则为0 ZF=0: 则不为0
(三)移位指令 (,对R或M中的操作数进行指定移位)
(1)算术移位指令
指令格式:算术左移:SAL DST , COUNT 算术右移:SAR DST, COUNT
(2)逻辑移位指令
指令格式:逻辑左移:SHL DST ,COUNT 逻辑右移:SHR DST, COUNT
(3)循环移位指令
指令格式:循环左移:ROL DST ,COUNT 循环右移:ROR DST, COUNT
带进位循环左移: RCL DST , COUNT 带进位循环右移: RCR DST , COUNT
注意: DST: R或M ; 字或字节 ;
COUNT: 移位次数;
COUNT=1:可用“1”代替。
COUNT≠1:用CL代替 。
左、右移中移出的位均送CF中。 算术/逻辑移位: 修改 OF,ZF,SF,PF,CF。
循环移位:修改OF,CF。只移一位且移位前后操作数的符号位发生变化:OF=1,否则 OF=0。若移位位数大于1,则OF不定。
例1:AX中存放一带符号数,完成(AX)*3/2运算。
例2: 把存放在M+4,M+2,M 三个字单元中的一个无符号数右移一位。
例1 MOV DX, AX 例2 SHR M+4,1
SAL AX , 1; 乘2 → AX RCR M+2,1
ADD AX, DX; 乘3 → AX RCR M ,1
SAR AX, 1 ; (AX)*3/2
4、控制转移类指令
(一)无条件转移指令 JMP 目标地址
(二)条件转移指令 JXXX 目标地址
指令功能:
测试条件满足:IP ←(IP)+ 8位位移量
其中:(IP)的值为JXXX指令下一条指令的地址,8位位移量采用补码表示;
测试的条件满足,则转到目标地址执行
测试的条件不满足,则顺序执行下一条指令
(三)CX寄存器的值测试转移指令
指令格式: JCXZ 目标地址
指令功能: 测试 CX内容,(CX)=0,转到目标处,否则,顺序执行。
(四)循环控制指令 位移量是8位二进制以补码表示的带符号数。
(1)LOOP指令 格式:LOOP 目标地址
功能:循环次数(CX)-1 CX;(CX)不为零,继续循环,转到目标处,否则,顺序执行。
(2)LOOPE/LOOPZ指令 格式: LOOPE/LOOPZ 目标地址
功能:循环次数(CX)-1 CX;若(CX)不为零,且ZF=1,转到目标处,继续执行, 否则((CX)=0或ZF=0),顺序执行。
(3)LOOPNE/LOOPNZ指令 格式: LOOPNE/LOOPNZ 目标地址
功能:循环次数(CX)-1 CX;(CX)不为零,且ZF=0,转到目标处,继续执行, 否则((CX)=0或ZF=1) ,顺序执行。
(五)子程序的调用与返回指令
(1)CALL调用子程序指令 CALL 目标地址返回地址入栈转移到(过程名所代表的)入口地址
CALL SUB1
CALL BX
CALL WORD PTR [BX]
(2)RET从子程序返回指令 指令格式:RET [PARA]
过程返回地址从栈中弹出到 IP (CS)中返回原来的调用点
(六)中断子程序的调用与返回指令
(1)INT软中断指令 指令格式:INT n (其中:n为中断类型码)
指令功能: PUSHF,TF、IF清0,CS、IP入栈 按中断类型码n,从中断向量表对应位置取出将要调用的功能子程序的入口地址CS,IP
(2)IRET从中断子程序返回指令 指令格式:IRET
指令功能:从中断子程序返回断点
5、处理器控制类指令
(一)标志位处理指令
(1)清除进位标志指令 CLC: 置CF=0(2)进位标志置位指令STC: 置CF=1
(3)进位标志取反指令CMC: CF取反 (4)清除方向标志指令CLD: 置DF=0
(5)方向标志置位指令STD: 置DF=1 (6)清除中断标志指令CLI: 置IF=0
(7)中断标志置位指令STI: 置IF=1
(二)处理器控制指令
(1)HLT :停机指令 (2)WAIT:等待指令(CPU等待外部事件就绪达到同步目的)
(3)ESC: 换码指令,外部协处理器指令的前缀
(4)LOCK:总线封锁前缀指令 (5)NOP: 空操作指令,用于延时
七、CISC与RISC指令系统
1. CISC (Complex Instruction Set Computer)
复杂指令系统计算机
①执行一条指令要多次访问主存。
②执行一条指令需要多个微周期。
③流水线作业中,长指令的执行,妨碍其他指令的操作。
④寻址方式复杂,不易优化。
第八章汇编语言
五、汇编语言数据与运算符
1.常数 数值常数:二、八、十、十六进制 B,O,D,H 字符串常数
(1)在指令语句的原操作数中作立即数. MOV AL, 0A9H MOV BX, ‘AB’
(2) 存储器操作数的寻址方式中作位移量。 MOV AL, DS: [340H]
(3)在数据定义语句中,对存储单元预置初值。 DB 12H, 34H
2. 变量
(1) 用数据定义语句定义并预置初值后,变量代表存储单元的数据,并作为该单元的符号地址。
例如在某数据段已定义一变量: DATA_VAR DB 40H DUP (?)
几种含有变量名的地址表达式为:
直接寻址: DATA_VAR+08H
基址变址寻址: DATA_VAR [BX] [DI]
☐地址表达式的值:存放操作数的存储单元偏移量。
☐地址表达式的类型:同变量名的类型。
2. 变量
(2)在用DW或DD的数据定义语句中,若操作数字段引用了变量名,则在分配的存储单元中,预置被引用的变量名的地址部分:偏移量、段基值
NUM1 DB 10H DUP (?)
NUM2 DW 10H DUP (?)
ARRAY DB 10H DUP (‘ABCD’)
ADR1 DW ARRAY
ADR2 DD ARRAY
3. 标号:一条指令的符号地址。 段属性 偏移属性 类型属性
NEAR:段内转移,作为标号所在段的转移、调用指令的目标地址。
FAR:段间转移,作为其他段的转移、调用指令的目标地址。
类型属性设置:
(1)隐含方式:NEXT:MOV AX, 3000
(2)用LABEL伪指令设置类型属性:
标号伪指令LABEL格式: 名字 LABEL 类型
☐ 与指令语句配合使用:
名字(新标号) LABEL 类型(NEAR/FAR)
SUB1_FAR LABEL FAR
SUB1: MOV AX,1234H
☐ 与数据定义语句配合使用:
名字(新变量名)LABEL 类型(DB/DW/DD)
DATA _BYTE LABEL BYTE
DATA _WORD DW 20H DUP(563H)
4. 运算符
(1)算术运算符
只有减法运算可以用同一段内的两个变量相减
NUM = 15*5 ;NUM=75
NUM = NUM/8 ;NUM=9
NUM = NUM MOD 5 ;NUM=4
NUM = -NUM-6 ;NUM= -10
NUM = -NUM ;NUM= 10
ORG 30H ;下面定义数据的起始偏移是30H
DA1 DB ‘ABCDEFGH’
DA2 DB ‘IBM PC COMPUTER’
COUNT EQU DA2 - DA1 ;38H-30H=8
DA3 EQU DA2+4
NUM=11011011B
DATA1 DW NUM SHL 3 , NUM SHR 2
...
MOV AX , NUM SHL 3 MOV AX , 011011011000B
MOV BX , NUM SHR 2 MOV BX , 00110110B
MOV CX , NUM SHL 8 MOV CX , 1101101100000000B
MOV CX , NUM SHL 16 MOV CX , 0
MOV DX , NUM SHR 8 MOV DX , 0
MOV DX , NUM SHR 16 MOV DX , 0
DATA1 DW 6D8H , 36H
...
算术运算符 移位运算符和移位指令区别
移位运算符不能对寄存器或存储单元进行移位运算
MOV AX,CX SHL 5
MOV DX,DATA1 SHR 3
(2)逻辑运算符
MOV AL , NOT 0F0H
MOV DX , NOT 0F0H
MOV BL , 55H OR 0F0H
AND BH , 55H AND 0F0H
XOR CX , 55H XOR 50H
(3)关系运算符
全1为真,全0为假比较时,若为常数按无符号数比较,如果是变量按偏移量比较
DATA SEGMENT
ORG 10H
NUM1=1234
NUM2=1234H
DA_BYTE DB 10H DUP(0)
DA_WORD DW 10H DUP(0)
DA_VAR1 DW
NUM2+DA_BYTE GT NUM1+DA_WORD
DA_VAR2 DB NUM1 LE NUM2
DATA ENDS
...
MOV AX , NUM1 LT NUM2
MOV BL , NUM1 GE NUM2
MOV CX , DA_WORD GT DA_BYTE
...
DA_VAR1 DW 0FFFFH
DA_VAR2 DB 0FFH
...
MOV AX , 0FFFFH
MOV BL , 0
MOV CX , 0FFFFH
...
可以对两个常数进行比较,不能用常数与偏移量进行比较
(4)数值返回运算符
格式:<运算符> <地址表达式>
运算对象是存储器操作数,由变量名或标号组成地址表达式
SEG : 返回变量所在的段值 OFFSET:返回变量所在偏移
TYPE:返回变量的类型 LENGTH:返回数组变量的元素个数
SIZE:返回数组变量所占的总字节数 SIZE= TYPE* LENGTH
假设DATA的段基值是7A4EH
DATA SEGMENT
ORG 30H
DA1 DB 20H DUP(12H)
DA2 DW DA1
...
DATA ENDS
...
MOV AX , SEG DA1
MOV BX , SEG DA2
MOV SI , OFFSET DA1
MOV CX , DA2
MOV DI , OFFSET DA2
MOV DX , OFFSET DA1+4
MOV AX , 7A4EH
MOV BX , 7A4EH
MOV SI , 30H
MOV CX , DA2
MOV DI , 50H
MOV DX , 34H
TYPE 运算符
用数字形式表示变量和标号的类型属性
DA_BYTE DB 12H
DA_WORD DW 3456H
DA_DWORD DD 7AH
...
MOV AL , TYPE DA_BYTE
MOV BL , TYPE DA_WORD
MOV CL , TYPE DA_DWORD
...
MOV AL , 1
MOV BL , 2
MOV CL , 4
LENGTH与SIZE运算符
LENGTH运算符
返回数组变量的元素个数 如果变量用DUP定义,Length为外层DUP的值 如果没有DUP定义,结果为1
SIZE运算符
数组变量所占的总字节数 SIZE是LENGTH和TYPE的乘积
DATA SEGMENT
VAR1 DB 10H DUP(0)
VAR2 DB 10H, 20H, 30H, 40H
VAR3 DW 10H DUP(‘A’, 4 DUP(3))
VAR4 DB ‘COMPUTER’
DATA ENDS
...
MOV AL , LENGTH VAR1 ; (AL)=10H
MOV AH , SIZE VAR1 ; (AH)=10H
MOV BL , LENGTH VAR2 ; (BL)=1
MOV BH , SIZE VAR2 ; (BH)=1
MOV CL , LENGTH VAR3 ; (CL)=10H
MOV CH , SIZE VAR3 ; (CH)=20H
MOV DL , LENGTH VAR4 ; (DL)=1
MOV DH , SIZE VAR4 ; (DH)=1
求数组ARRAY的各数据项的累加和,从数组最后一个数据项开始进行累加。
ARRAY DW 20H DUP(4)
...
XOR AX , AX
MOV SI , OFFSET ARRAY
ADD SI , SIZE ARRAY-TYPE ARRAY
MOV CX , LENGTH ARRAY
LOP: ADD AX , [SI]
SUB SI , TYPE ARRAY
LOOP LOP
(5)属性运算符
PTR: 类型 PTR 地址表达式
类型可以是:BYTE ,WORD,DWORD 或NEAR FAR
仅在当前语句中有效,是一种临时设置。
DA_BYTE DB 20H DUP(0)
DA_WORD DW 10H DUP(0)
MOV WORD PTR DA_BYTE [10], AX
ADD BYTE PTR DA_WORD [DI], BL
INC BYTE PTR [SI]
SUB WORD PTR[BX],30H
JMP FAR PTR SUB1
THIS:THIS 类型
THIS常与等值语句EQU一起用,形成新变量名或标号,使它们具有THIS后所指的类型,而段基值和偏移量与紧接的变量名或标号相同。
例: DATA _BYTE EQU THIS BYTE
DATA _WORD DW 20H DUP(0)
JUMP_FAR EQU THIS FAR
JUMP_NEAR : XOR AX, AX
(6)分离字节运算符
HIGH 表达式
LOW 表达式
分离运算对象的高字节和低字节部分 表达式必须具有常量值,如常数、地址表达式, 不能是存储器操作数或寄存器内容
DATA SEGMENT
ORG 20H
CONST EQU 0ABCDH
DATA1 DB 10H DUP(?)
DATA2 DW 20H DUP(?)
...
DATA ENDS
...
MOV AH , HIGH CONST MOV AH , 0ABH
MOV AL , LOW CONST MOV AL , 0CDH
MOV BH , HIGH (OFFSET DATA1) MOV BH , 0
MOV BL , LOW (OFFSET DATA2) MOV BL , 30H
MOV CL , LOW (CONST SHL 3) MOV CL , 68H
7)运算符的优先级
1. 段定义伪指令
段名 SEGMENT [定位类型] [组合类型] [‘类别名’]
...
段名 ENDS
定位类型(Align Type):
PAGE(页):本段从一个页的边界开始,起始地址能被256整除。
PARA(节):本段从一个节的边界开始,起始地址能被16整除。
WORD(字):本段从偶字节地址开始。
BYTE(字节):本段从任意地址开始。
1. 段定义伪指令
组合类型(Combine Type):
⏹NONE:本段与其它段无连接关系,是的。
⏹PUBLIC:本段与其它同段名同类型的段相连接在一起,然后为所有这些段指定一个共同的段基地址,形成一个新的逻辑段。
⏹COMMON:本段与其它同段名同类型的段设置相同的段基址,共享相同的存储区,段长度由同名段中最大的段确定。(覆盖段)
⏹STACK:与PUBLIC段相似,但此段为堆栈段,系统自动对SS寄存器和SP指针初始化。
⏹AT表达式:本段的起始单元可以定位在表达式所示的节边界上。
⏹MEMORY:本段定位在所有其它段的最高地址,有多个段,只把第一遇到的当作此段。 类别名(Class)
2. 段寻址伪指令
ASSUME 段寄存器名:段名,段寄存器名:段名,...
DS_DATA SEGMENT
VAR1 DB 12H
DS_DATA ENDS
ES_DATA SEGMENT
VAR2 DB 34H
ES_DATA ENDS
CODE SEGMENT
VAR3 DB 56H
ASSUME CS:CODE , DS:DS_DATA
START: ......
...
INC VAR1
INC VAR2
INC VAR3
...
CODE ENDS
END START
可用关键字NOTHING取消前面的某些设置。
例: ASSUME DS:NOTHING;取消对DS的设置
ASSUME NOTHING; 取消全部4个段R的设置
3.段寄存器的装入
⏹DS,ES的装入
DATA_DS SEGMENT
DB1 DB 10H DUP(?)
DATA_DS ENDS
CODE SEGMENT
ASSUME CS:CODE , DS:DATA_DS , ES:DATA_ES
START: MOV AX , DATA_DS ;设置DS
MOV DS , AX
MOV AX , DATA_ES ;设置ES
MOV ES , AX
...
CODE ENDS
⏹SS的装入
(1) STACK1 SEGMENT PARA STACK
DW 20H DUP(?)
STACK1 ENDS
(2) STACK2 SEGMENT
DW 30H DUP(?)
TOP LABEL WORD
STACK2 ENDS
...
CODE SEGMENT
...
MOV AX , STACK2 ;设置SS
MOV SS , AX
MOV SP , OFFSET TOP ;修改SP
⏹CS的装入
...
CODE SEGMENT
ASSUME CS:CODE , ......
...
START:............
...
CODE ENDS
END START
七、过程定义伪指令
过程名 PROC [NEAR/FAR]
...
RET
过程名 ENDP
1.有三个属性 2.一个过程内,至少有一条返回指令RET
3.调用过程使用CALL 过程名 4.段内返回与段间返回
八、其它伪指令
1. ORG , $
ORG 表达式
将表达式的值赋给位置计数器
$ 存放位置计数器的当前值
ORG , $举例
DATA SEGMENT
ORG 30H
DB1 DB 12H , 34H
ORG $+20H
STRING DB ‘STRING’
DATA ENDS
ORG , $举例
DATA SEGMENT
DA1 DB 10H DUP(?)
DA2 DB 12H , 34H
DA3 DW 56H , $+10H , 78H , $+20H
...
DATA ENDS
CODE SEGMENT
...
ORG 50H
MOV AX , OFFSET $
MOV BX , OFFSET $
...
CODE ENDS
MOV AX , 0050H
MOV BX , 0053H
2. EVEN 伪指令 定位偶地址
3. INCLUDE伪指令
INCLUDE 文件名
例: INCLUDE FILE.MAC
INCLUDE B:\\MASM\\ABC.ASM
4. PUBLIC
PUBLIC 符号1,符号2, ......
5. EXTRN 伪指令
EXTRN 符号 1:类型 ,符号 2: 类型, ...
PUBLIC NUM1 , STRING , SUB1 , LOOP1
DATA1 SEGMENT
NUM1 EQU 1234H
...
STRING DB ‘CHARACTER STRING’
...
DATA1 ENDS
...
CODE1 SEGMENT
...
SUB1 PROC FAR
...
SUB1 ENDP
EXTRN NUM1:ABS , STRING:BYTE
EXTRN SUB1:FAR , LOOP1:NEAR
:
CODE2 SEGMENT
:
MOV AX , NUM1
LEA BX , STRING
:
CALL SUB1
:
JMP FAR PTR LOOP1
:
CODE2 ENDS
END
5. TITLE (标题)伪指令,指定一个标题
格式:TITLE 文本 字符不超过80个
例:TITLE EXAMPLE PROGRAM
例:
MULTAX10 MACRO
PUSH BX
SAL AX,1
MOV BX,AX
SAL AX,1
SAL AX,1
ADD AX,BX
POP BX
ENDM
九、宏指令
1. 宏定义
宏名 MACRO [形参1,形参2,...]
...
ENDM
EXCHANGE MACRO MEM1,MEM2,REG
MOV REG,MEM1
XCHG REG,MEM2
MOV MEM1,REG
ENDM
2. 宏调用
宏名 [实参1,实参2,...]
EXCHANGE DA_BY1 , DA_BY2 , AL
3. 宏展开
宏定义
MULTAX10 MACRO
PUSH BX
SAL AX,1
MOV BX,AX
SAL AX,1
SAL AX,1
ADD AX,BX
POP BX
ENDM
;------------------------------------------------------------
EXCHANGE MACRO MEM1,MEM2,REG
MOV REG,MEM1
XCHG REG,MEM2
MOV MEM1,REG
ENDM
设置数据段
DATA SEGMENT
DA_W01 DW 1234H
DA_W02 DW 5678H
DATA ENDS
;设置堆栈段
STACK1 SEGMENT PARA STACK
DW 20H PUP(?)
STACK1 ENDS
;设置代码段
COSEG SEGMENT
ASSUME CS:COSEG,DS:DATA,SS:STACK1
START: MOV AX , DATA
MOV DS , AX
...
MULTAX10 ;宏指令语句
+ PUSH BX
+ SAL AX , 1
+ MOV BX , AX
+ SAL AX , 1
+ SAL AX , 1
+ ADD AX , BX
+ POP BX
...
EXCHANGE DA_W01 , DA_W02 , CX :宏指令语句
+ MOV CX , DA_W01
+ XCHG CX , DA_W02
+ MOV DA_W01 , CX
...
COSEG ENDS
END START
4. 宏操作符
•连接操作符 &
定义:SHIFT_VAR MACRO R_M , DIRECT, COUNT
MOV CL , COUNT
S&DIRECT R_M , CL
ENDM
调用:SHIFT_VAR AX,HL,2
SHL AX,CL
SHIFT_VAR AX,HR,2
SHR AX,CL
表达式操作符 %
格式:%表达式;获取表达式的值(出现在宏调用中)
SHIF0 MACRO CNT
MOV CL , CNT
ENDM
SHIF1 MACRO REG , DIRECT , NUM
COUNT=NUM
SHIF0 %COUNT
S&DIRECT REG , CL
ENDM ;宏调用
SHIF1 AX , HL , 2
SHIF1 BL , AR , 3 ;宏展开
SHIF1 AX , HL , 2
+ MOV CL , 2
+ SHL AX , CL
SHIF1 BL , AR , 3
+ MOV CL , 3
+ SAR BL , CL
•文本操作符 <>
EXCHANGE 宏展开 MOV AL , BYTE PTR DA_WORD1 XCHG AL , BYTE PTR DA_WORD2 MOV BYTE PTR WORD1 , AL •字符操作符 ! 格式: !字符 宏定义:PROMPT MACRO NUM , TEXT PROMP&NUM DB ‘&TEXT&’ ENDM 宏调用:PROMPT 23, 宏展开: PROMPT23 DB ‘Expression > 255’ •宏注解符 ;; 5. LOCAL伪指令 LOCAL <符号表> 在汇编过程中,宏定义中的内容会在每一次宏调用处展开。因此当多次调用一个宏时,宏定义中的标号会造成标号重复定义。 在宏定义中使用LOCAL伪指令可以使标号被局部化,从而避免重复定义。 LOCAL伪指令只能用在宏定义中,并且它必须是宏定义中紧跟在MACRO伪指令之后的第一个语句。 用连续相加的办法实现无符号数乘法运算 MULTIP MACRO MULT1 , MULT2 , MULT3 LOCAL LOP , EXIT0 MOV DX , MULT1 MOV CX , MULT2 XOR BX , BX XOR AX , AX JCXZ EXIT0 LOP: ADD BX , DX ADC AX , 0 LOOP LOP EXIT0: MOV MULT3 , BX MOV MULT3+2 , AX ENDM 设数据段有如下定义的变量: DA1 DW 1234H , 5678H DA2 DW 120H , 210H DA3 DW 4 DUP(?) 宏展开: ... MULTIP DA1 , DA2 , DA3 + MOV DX , DA1 + MOV CX , DA2 + XOR BX , BX + XOR AX , AX + JCXZ 0001 +0000:ADD BX , DX + ADC AX , 0 + LOOP 0000 +0001: MOV DA3 , BX + MOV DA3+2 , AX ... MULTIP DA1+2 , DA2+2 , DA3+4 + MOV DX , DA1+2 + MOV CX , DA2+2 + XOR BX , BX + XOR AX , AX + JCXZ 0003 +0002:ADD BX , DX + ADC AX , 0 + LOOP 0002 +0003: MOV DA3+4 , BX + MOV DA3+6 , AX ... 6. 宏嵌套 ☐宏定义嵌套 嵌套的宏定义: JUMP MACRO COND J&COND&S MACRO DEST LOCAL NEXT , EXIT J &COND NEXT JMP EXIT NEXT: JMP DEST EXIT: ENDM ENDM 外层宏调用为: JUMP E JUMP NE JUMP G JUMP GE 内层宏调用为:JES SUB1 ;等于0转移 JGES SUB2 ;大于或等于转移 当宏汇编程序对内层宏展开后,可得到如下结果: JE 0000 JMP 0001 0000: JMP SUB1 0001: : JGE 0002 JMP 0003 0002: JMP SUB2 0003: : ☐宏定义内嵌套宏调用 两个宏定义: 对32位数左移一位 SHIFT MACRO NUM1 , NUM2 SAL NUM2 ,1 RCL NUM1 ,1 ENDM 对32位数乘以12 MULT12 MACRO M_R1 , M_R2 , REG1 , REG2 PUSHF PUSH REG1 PUSH REG2 SHIFT M_R1 , M_R2 SHIFT M_R1 , M_R2 MOV REG1 , M_R1 MOV REG2 , M_R2 SHIFT M_R1 , M_R2 ADD M_R2 , REG2 ADC M_R1 , REG1 POP REG2 POP REG1 POPF ENDM 某数据段已定义变量: 在程序中可以编写宏指令语句: : MULT12 DA_WORD+2,DA_WORD,AX,BX : MULT12 AX,BX,CX,DX下载本文