汇编指令(一):数据传输指令

目录

数据传输指令

通用数据传送指令

传送指令 MOV

进栈指定 PUSH 出栈指令POP

交换指令 XCHG

累加器专用传送指令

输入指令 IN、输出指令 OUT

换码指令XLAT

地址传送指令

有效地址传送器 LEA

LDS,LES

标志寄存器传送指令

LAHF 标志寄存器的低字节送AH 

SAHF AH送标志寄存器低字节

PUSH 标志进栈指令

POPF 标志位出栈


数据传输指令

通用数据传送指令

传送指令 MOV

这个是最常用的一个命令了。

命令的格式:MOV dst,src

功能:将源操作数(字节或者字)传送到目的地址。

寻址方式:不支持dst,src同时为存储器寻址方式,这个限制适用于所有指令。(都是存储器寻址是没法确定数据长度的)

对标志位的影响:不影响

特殊性:dst,src不能同时为段寄存器、目的操作数dst不能是CS(规定),也不能是立即数(这个好理解吧,立即数应该不算地址,只是一个具体的数据data)

因为dst,src不能同为段寄存器,所以都是通过通用寄存器作为中间值来实现段寄存器之间的数据交换。

进栈指定 PUSH 出栈指令POP

关于栈的概念应该是接触很久了。栈的操作还是很简单优雅的。

命令格式:push src,pop dst

功能:push将数据入栈,保存在栈内。pop指令将数据出栈。栈对数据的操作是遵循先进后出规则的。

这里还有一个要注意的点是:和这两个命令有关的寄存器是SS和SP。在进行push操作时是先将SP-2(两个指令都是以字为单位操作的),然后将数据写入。pop指令是先将数据输出,再将SP+2.

这里有两个要注意的地方:SP加减2。为什么入栈是SP-2,出栈是SP+2(这里需要指定的在8086中,其他CPU可能不一样。)。这是因为在8086中数据是从大地址往小地址方向存数据的。所以,数据写入时需要将栈顶指针像下移。写出是相反(在一个CPU中,栈的存放方向只能是一种,要么从小到大,要么从大到小)。第二个注意点是,为什么进栈时是先移动SP,再放数据。出栈是先拿出数据再移动SP,其实这个也是很好理解的:首先要知道的是,SP是栈顶指针,他会指向栈顶那个数据,如果我们先放数据的话,我们不能直接放入SP指向的偏移地址中,我们需要先计算出SP+2的值然后去放数据,然后还需要将SP+2使SP指向栈顶,你会发现这样做了重复的工作。如果我们先将SP的值加2赋值给SP的话,我们就可以直接把数据放入SP指向的偏移地址中。

指令的寻址方式:push和pop都不能使用立即数寻址。

指令不会对标志位产生影响。

特殊要求:红字部分,还有就是:pop指令的dst不能是CS寄存器。

交换指令 XCHG

指令格式:XCHG OPR1,OPR2

指令的功能:将两个地址的数据交换

寻址方式:一个操作数必须在寄存器中,另一个操作数可以在寄存器或存储器中。

不影响标志位

特殊要求:不允许使用段寄存器!

分割记录,下次补坑 ;


回来补坑

累加器专用传送指令

输入指令 IN、输出指令 OUT

小知识:在IBM-PC机中,外部设备最多有65535个I/O端口,0000~FFFFH,长指令可以直接给出前256(一个字的寻址范围)个端口,如果需要访问其他的端口,需要采用短指令来访问-------也就是把端口号放在DX寄存器中,在使用I/O指令

格式:长格式:IN AL,PORT(字节);IN AX,PORT(字);

短格式:IN AL/AX,DX

PORT为8位地址,DX可以指定16位地址。

注:这里的长格式和短格式是指指令的长短,而不是指寻址范围的大小。

OUT对应的格式和IN是一样的。

OUT PORT,AL;OUT PORT,AX;(长格式)|||| OUT DX,AL/AX(短格式);

其中IN是指从端口中读取数据,OUT是往端口中写数据。

注:这里的PORT,DX都是地址,指向一个端口,具体放多少数据,拿多少数据是通过AX/AL判断的,DX和PORT是无法确定数据长度的。他们只是指向了一个端口。

注:指令只限于在AL或AX与I/O之间传送信息。

换码指令XLAT

指令格式:XLAT opr 或者 XLAT

指令格式很简单,但理解起来有点麻烦,很多地方说的过于理论化,使得我看的稀里糊涂,在网上找到了一个让我理解这个指令的例子。:

array db 3,5,8,2,4,7,9,6,10    ;这里定义了一个数组,名字是array
lea bx,array                   ;这个指令大概是将数组的地址赋值给了bx
mov al,1                       ;这里给al赋值为al
xlat                           ;这里返回值是AL=array[al]=5

看完了例子,我们来看看这个指令的文字解释:这个指令根据AL寄存器提供的位移量,将BX指向的字节表格(这里的数组)中的数据存在AL中。简单的说就是将bx指向的数组,以下标为AL所取得的数据,存放在AL中。

指令对标志位没有影响。

注:所建的表格长度不能超过256字节,这是由于偏移量AL是8位寄存器。其中的opr参数是表格的首地址,由于首地址存放在BX中了,所以可有可无,如果有的话可以增加程序的可读性。

地址传送指令

有效地址传送器 LEA

指令的格式:LEA reg,src

基本功能:把源操作数的有效地址送到指定的16位通用寄存器,有效地址为一种存储器寻址方式确定。所以他的寻址方式可以是各种存储器寻址。也可以是变量名,标号。

指令不会影响标志位。

注:指令中reg不能是段寄存器。虽然mov指令在速度上比lea更快但offset只能处理简单的符号地址而不能处理list[si]等复杂地址

LDS,LES

格式:

LDS reg,src     ;(reg)<-(src)  (DS)<-(src+2)
LES reg,src     ;(reg)<-(src)  (ES)<-(src+2)

功能是:将src指定的字放入通用寄存器中,将src+2指定的字放入DS/ES中。

指令不影响标志位。

注:reg不能是段寄存器


标志寄存器传送指令

LAHF 标志寄存器的低字节送AH 

格式:LAHF

指令的基本功能:(AH)<-(FLAGS)0-7

不影响标志位。

SAHF AH送标志寄存器低字节

指令格式:SAHF

指令的基本功能:(FLAGS)0-7 <- (AH)

对低标志位的低八位有影响。

PUSH 标志进栈指令

格式:PUSHF

基本功能:将十六位标志位进栈。

不影响标志位

POPF 标志位出栈

格式:POPF

功能:将栈顶的字赋值给标志寄存器

对标志位进行重新赋值。

 

 

你可能感兴趣的:(学习笔记,汇编,指令,8086)