快捷链接
数据传送指令
通用数据传送指令
MOV DST,SRC
普通的传送指令,src表示源操作数,dst表示目的操作数。
双操作数指令不允许两个操作数都使用存储器。
如果其中一个操作数为段寄存器,则另一个操作数必须为存储器或者寄存器。
段寄存器不能是CS寄存器,另外,对于MOV segreg,mem/reg指令不会触发中断。
MOVSX DST,SRC
带符号拓展的传送指令,386及其后继机型可用。
MOVZX DST,SRC
带零拓展的传送指令,386及其后继机型可用。
PUSH SRC
进栈指令,src必须为字(或者双字),不允许字节堆栈
段地址存放在SS寄存器中,是一个段寄存器
对字执行push的本质:
(SP)←(SP)-2
((SP)+1,(SP))←(SRC) ;这儿表明这玩意不处理字节
POP DST
出栈指令,也不允许字节堆栈
目的操作数为段寄存器时不能为CS寄存器
PUSHA
通用寄存器依次进栈,顺序为AX,CX,DX,BX,(指令执行前的)SP,BP,SI,DI
执行完后(SP)←(SP)-16
栈里存的是之前的
POPA
通用寄存器依次出栈,顺序为PUSHA的逆序
执行完后(SP)←(SP)+16
实际上为了保证能正确的对BX进行出栈操作,SP的出栈只是修改了指针,即自增2,而之前PUSHA存入的SP的原始内容被丢弃了而不是真正地送入了SP寄存器中。
XCHG OPR1,OPR2
交换两个操作数。
该指令的操作数须有至少一个寄存器,但不是段寄存器。
因此该指令可以使用除了立即数以外的任何寻址方式。
此指令不影响标志位
累加器专用指令
IN AL,PORT
也可以是IN AX,PORT或者IN EAX,PORT,三个格式依次为字节,字和双字。
OUT PORT,AL
也可以是OUT PORT,AX或者OUT PORT,EAX
注意:在IN和OUT指令中的PORT表示外部设备的端口号,端口号的范围为0000~0FFFFH,如果指定的PORT为00到0FFH,则可以用立即数直接在指令中指定,否则就需要先把端口号存在DX寄存器中。
这两个指令被称为累加器专用指令是因为CPU只能用累加器AX接收或发送信息。
必须注意:这里的端口号或者DX中的内容均为地址,而传送的是端口中的信息,而且在用DX指明地址时DX的内容就是端口号本身,不需要任何段寄存器来修改它的值。
地址传送指令
LEA REG,SRC
指令将源操作数的有效地址送到指定的寄存器中,该指令的目的操作数不能为段寄存器,源操作数可以使用除立即数和寄存器外的任何一种存储器寻址方式。
举个栗子:
LEA BX,[BX+SI+0F62H]
如果指令执行前(BX)=0400H,(SI)=003CH
那么指令执行后(BX)就是0400+003C+0F62=139EH
区别于以下指令:
MOV BX,[BX+SI+0F62H]
这个指令执行后(BX)为地址139EH里的内容。
实际上:
LEA BX,LIST 和 MOV BX,OFFSET LIST
的结果一样(LIST为一个符号地址)
LDS/LES REG,SRC
将源操作数送进指定的寄存器中,然后将源操作数+2送进段寄存器中。
源操作数只能是存储器寻址。
上述的寄存器为REG,段寄存器则取决于用的是LDS还是LES
LDS代表目的段寄存器为DS,LES代表目的段寄存器为ES
注意:SRC默认使用的段寄存器为DS,不受使用的是LDS还是LES影响,若要显式表明用的段寄存器为ES请使用ES:SRC,比如ES:[BX]。
标志寄存器传送指令
LAHF 标志送AH
SAHF AH送标志寄存器
PUSHF 标志进栈
POPF 标志出栈
类型转换指令
CBW 将字节转换为字
将AL中的内容符号拓展到AH,形成AX中的字。
即如果(AL)的最高有效位为0,则(AH)=0,否则为0FFH
CWD 将字转换为双字
类似于AL变AX,这里是AX变DX:AX
CWDE 将字转换为双字
类似于AL变AX,这里是AX变为EAX
CDQ 将双字变为四字
类似于AL变AX,这里是EAX变EDX:EAX