从今天开始,用心学习王爽的《汇编语言》!
扎扎实实,勿在浮沙建高楼!
—————2012.5.29 21:30
第1章 基础知识
以后用到的知识,以后再说。
汇编课程的研究重点放在如何利用硬件系统的编程结构和指令集有效灵活地控制系统进行工作。
每一种微处理器,由于硬件设计和内部结构的不同,就需要用不同的电平脉冲来控制,使他工作。所以每一种微处理器都有自己的机器指令集,也就是机器语言。
汇编语言由以下3类指令组成:
汇编指令:机器码的助记符,有对应的机器码。
伪指令:没有对应的机器码,由编译器执行,计算机并不执行。
其他符号:如:+、-、*、%等,由编译器识别,没有对应的机器码。
汇编语言的核心是汇编指令,它决定了汇编语言的特性。
要灵活地利用汇编语言编程,首先要了解CPU是如何从内存中读取信息,以及向内存中写入信息的。
总线:
根据传送信息的不同,总线从逻辑上又分为3类,即地址总线、控制总线和数据总线。
地址总线:
CPU是通过地址总线来指定存储器单元的。地址总线上能传送多少个不同的信息,CPU就可以对多少个存储单元进行寻址。
所以32位机器,地址总线有32根,能寻址2^32=4G空间。
数据总线:
CPU与内存或其他器件之间的数据传送是通过数据总线来进行的。数据总线的宽度决定了CPU和外界的数据传送速度。
32位的数据总线一次能传送4个字节的数据。
控制总线:
CPU对外部器件的控制是通过控制总线来进行的。在这里控制总线是个总称,控制总线是一些不同控制线的集合。有多少根控制总线,就意味这CPU提供了对外部器件的多少种控制。所以,控制总线的宽度决定了CPU对外部器件的控制能力。
内存地址空间
最终运行程序的是CPU,我们用汇编编程的时候,必须要从CPU角度考虑问题。对CPU来讲,系统中的所有存储器中的存储单元都处于一个统一的逻辑存储器中,他的容量受CPU寻址能力的限制。这个逻辑存储器即是我们所说的内存地址空间。
那么,80386PC的内存地址空间是如何分布的呢?
第2章 寄存器(CPU工作原理)
一、寄存器分类:
数据寄存器:AX、BX、CX、DX四个寄存器
指针寄存器:SP堆栈指针、BP基址指针
变址寄存器:SI源地址、DI目的地址
段寄存器:CS代码段、DS数据段、SS堆栈段、ES附加段
控制寄存器:IP指令指针寄存器、FLAG标志寄存器
数据寄存器,指针寄存器和变址寄存器统称为通用寄存器。这样称呼的理由是,这些寄存器除了各自规定的专门用途外,他们均可用于传送和暂存数据,可以保存算术逻辑运算中的操作数和运算结果。
二、寄存器访问规则:
1、两个操作对象的位数应当是一致的。
2、8086CPU不支持直接将数据送入段寄存器的操作。
3、只有mov、push、pop指令能对段寄存器进行操作。
4、8086CPU的入栈和出栈操作都是以字为单位进行的。
5、在8086CPU中,只有bx,si,di,bp这4个寄存器可以用在[]中来进行内存单元的寻址。
6、在[]中,这4个寄存器可以单个出现,或只能以4种组合出现:bx和si、bx和di、bp和si、bp和di。
7、只要在[]中使用寄存器bp,而指令中没有显性的给出段地址,段地址就默认在ss中。
一个典型的CPU由运算器、控制器、寄存器等器件构成,这些器件靠内部总线相连。
8086的所有寄存器都是16位的,可以存放两个字节。
16位结构描述了一个CPU具有下面几方面的结构特性:
1、运算器一次最多可以处理16位的数据。
2、寄存器的最大宽度为16位。
3、寄存器和运算器之间的通路为16位。
8086有20位地址总线,与CPU内部结构的16位不同。
采用一种在内部使用两个16位地址合成的方法来形成一个20位的物理地址。
物理地址=段地址*16 + 偏移地址
寻址模式的本质含义是:CPU在访问内存时,用一个基础地址和一个相对于基础地址的偏移地址相加,给出内存单元的物理地址。
所以,也可由此看出系统的CPU结构、地址总线、数据总线和控制总线宽度是不一定相同的。
提问:386之后的机器呢?
回答:
8080处理器拥有16位地址总线和8位数据总线;
8086内、外部数据总线均为16位,地址总线为20位;
80286内部和外部数据总线皆为16位,地址总线为24位;
80386,80486的内部和外部数据总线都是32位,地址总线也是32位;
Pentium是64位数据总线,32位地址总线;
Pentium Pro是64位数据总线,地址总线就已经上升为36根了。
具体可见下图,来自于《80x86汇编语言程序设计》:
段的概念:内存并没有分段,段的划分来自于CPU。在编程时根据需要,将若干地址连续的内存单元看做一个段,用段地址*16定位段的起始地址(基础地址),用偏移地址定位段中的内存单元。
在8086CPU加电启动或复位后,CS和IP被设置为CS=FFFFH,IP=0000H,即在8086PC机刚启动时,CPU从内存FFFF0H单元中读取指令执行,FFFF0单元中的指令是8086PC机开机后执行的第一条指令。
第3章实验2最后一题的猜测:
在网上看到别人的答案都是说,由于把此处的位置当做栈了,而t产生中断,所以就将 标识寄存器、CS、IP入栈保存。不过我发现除了以上之外,还总是保存了另外两个寄存器的内容,其顺序分别是:
ax,bp,ip,cs,eflags
----不知道为什么总是还保存了bp和ax。
DOS方式下,一般情况下,0:200~0:2ff空间中没有系统或其他程序的数据和代码;这是一段安全的空间!其实这属于中断向量表的空间,只是一般这一段的中断向量表项都是空的。
DOS加载exe:
1、程序加载后,ds中存放着程序所在内存区的段地址,这个内存区的偏移地址为0,则程序所在的内存区的地址为ds:0.
2、这个内存区的前256个字节中存放的是PSP,DOS用来和程序进行通信。从256(100H)字节处向后的空间存放的是程序。
3、CX寄存器存放的程序的长度。
即是:从ds中可以得到PSP的段地址SA,PSP的偏移地址为0,则物理地址为SA*16+0.
程序的物理地址为SA*16+0+256=SA*16+16*16+0=(SA+16)*16+0=SA+10H:0
第7章 更灵活的定位内存地址的方法
“如果一个问题的解决方案,使我们陷入一种矛盾之中。那么,很可能是我们考虑问题的出发点有了问题,或是说,我们起初运用的规律并不合适。”这段话包含很深刻的道理,不仅仅适用于计算机问题,技术问题,同样适用于生活中,人生上所有的问题。
更灵活的方式来指明内存单元:[bx+idata].写法:
mov ax,[bx+200]
mov ax,[200+bx]
mov ax,200[bx]
mov ax,[bx].200
si、di是两个和bx功能类似的寄存器,但是这两个不能拆分成两个8位寄存器。
[bx+si] ~ [bx+di] ~ [bx][si] ~ [bx][di]
[bx+si+idata] ~ [bx+di+idata]
mov ax,[bx+si+200]
mov ax,[bx+200+si]
mov ax,[200+bx+si]
mov ax,200[bx][si]
mov ax,[bx].200[si]
mov ax,[bx][si].200
本章结束语:
“下一章中,我们将对寻址方式的问题进行更深入地探讨。之所以如此重视这个问题,是因为寻址方式的适当应用,使我们可以以更合理的结构来看待所要处理的数据。而为所要处理的看似杂乱的数据设计一种清晰的数据结构是程序设计的一个关键问题。”
第8章 数据处理的两个基本问题
计算机是进行数据处理、运算的机器,那么有两个基本的问题就包含在其中:
1、处理的数据在什么地方?
2、要处理的数据有多长?
汇编语言中用3个概念来表达数据的位置:
1、立即数:执行前在CPU的指令缓冲器中,在汇编指令中直接给出。
2、寄存器:指令要处理的数据在寄存器中,在汇编指令中给出相应的寄存器名。
3、段地址(SA)和偏移地址(EA):指令要处理的数据在内存中,在汇编指令中可用[x]的格式给出EA,SA在某个段寄存器中。
当数据存放在内存中的时候,我们可以用多种方式来给定这个内存单元的偏移地址,这种定位内存单元的方法一般被称为寻址方式。寻址方式参见8.4节的寻址方式表。
汇编语言用以下方法处理数据长度的问题:
1、通过寄存器名指明要处理的数据的尺寸。
2、在没有寄存器名存在的情况下,用操作符X ptr指明内存单元的长度,X在汇编指令中可以为word或byte。
3、其他方法:有些指令默认了访问的是字单元还是字节单元,比如,push、pop指令只进行字操作。
div指令:除法指令,使用div做除法的时候应注意以下问题:
1、除数:有8位和16位两种,在一个reg或内存单元中。
2、被除数:默认放在AX或DX和AX中,如果除数为8位,被除数则为16位,默认在AX中存放;如果除数为16位,被除数则为32位,在DX和AX中存放,DX存放高16位,AX存放低16位。
3、结果:如果除数为8位,则AL存储除法操作的商,AH存储除法操作的余数;如果除数为16位,则AX存储除法操作的商,DX存储除法操作的余数。
第9章 转移指令的原理
可以修改IP,或同时修改CS和IP的指令统称为转移指令。
8086CPU的转移指令分为以下几类:
1、无条件转移指令(如jmp)。
2、条件转移指令
3、循环指令(如loop)。
4、过程
5、中断
offset操作符在汇编语言中是由编译器处理的符号,它的功能是取得标号的偏移地址。
段内短转移
jmp short 标号 功能:IP=IP+8位位移
1、8位位移=标号处的地址-jmp指令后的第一个字节的地址;
2、short指明此处的位移为8位位移;
3、8位位移的范围为-128~127,用补码表示;
4、8位位移由编译程序在编译时算出。
段内近转移
jmp near ptr 标号 功能:IP=IP+16位位移
1、16位位移=标号处的地址-jmp指令后的第一个字节的地址;
2、near ptr指明此处的位移为16位位移,进行的是段内近转移;
3、16位位移的范围为-32768~32767,用补码表示;
4、16位位移由编译程序在编译时算出。
段间转移
jmp far ptr 标号 实现的是段间转移,又称为远转移。功能:
cs=标号所在段的段地址;ip=标号在段中的偏移地址。
far ptr指明了指令用标号的段地址和偏移地址修改CS和IP。
所有的有条件转移指令都是短转移,在对应的机器码中包含转移的位移,而不是目的地址。对IP的修改范围都为-128~127.
jcxz 标号 == if((cx)==0) jmp short 标号
所有的循环指令都是短转移,在对应的机器码中包含转移的位移,而不是目的地址。对IP的修改范围都为-128~127.
loop 标号 == (cx)--;if((cx)!=0) jmp short 标号
段内转移对IP的修改时根据转移目的地址和转移起始地址之间的位移来进行的。在它们对应的机器码中不包含转移的目的地址,而包含的是到目的地址的位移。这种设计,方便了程序段在内存中的浮动装配。
注意,根据位移进行转移的指令,它们的转移范围受到转移位移的限制,如果在源程序中出现了转移范围超界的问题,在编译的时候,编译器将报错。---看到这个结论,我心里高兴放心多了,不然我还担心要我自己去算转移位移呢!
第10章 call和ret指令
call和ret指令都是转移指令,他们都修改ip,或同时修改cs和ip。他们经常被共同用来实现子程序的设计。
ret指令用栈中的数据,修改ip的内容,从而实现近转移。
retf指令用栈中的数据,修改cs和ip的内容,从而实现远转移。
ret == "pop IP"
retf == "pop IP ; pop CS"
CPU执行call指令时,进行两步操作:
1、将当前的IP或CS和IP压入栈中;
2、转移。
call 标号 == “push IP ; jmp near ptr 标号”
call far ptr 标号 == “push CS ; push IP ; jmp far ptr 标号”
call 16位reg == "push IP ; jmp 16位reg"
call word ptr 内存单元地址 == "push IP ; jmp word ptr 内存单元地址"
call dword ptr 内存单元地址 == "push CS ; push IP ;jmp dword ptr 内存单元地址"
mul乘法指令:
1、两个相乘的数,要么都是8位,要么都是16位。如果是8位,一个默认在AL中,另一个放在8位reg或内存单元中;如果是16位,一个默认在AX中,另一个放在16位reg或内存字单元中。
2、结果:如果是8位乘法,结果默认放在AX中;如果是16位乘法,结果高位默认在DX中,低位在AX中放。
第11章 标志寄存器
标志寄存器的3种作用:
1、用来存储相关指令的某些执行结果;
2、用来为CPU执行相关指令提供行为依据;
3、用来控制CPU的相关工作方式。
flag和其他寄存器不一样,其他寄存器是用来存放数据的,都是整个寄存器具有一个含义。而flag寄存器是按位起作用的,也就是说,它的每一位都有专门的含义,记录特定的信息。
flag寄存器各位示意图:
flag的1、3、4、12、13、14、15位在8086CPU中没有使用,不具有任何含义。
CF:进位标志位。一般情况下,在进行无符号数运算的时候,它记录了运算结果的最高有效位向更高位的进位值,或从更高位的借位值。
PF:奇偶标志位
AF:
ZF:零标志位
SF:符号标志位
DF:方向标志位
OF:溢出标志位。一般情况下,OF记录了有符号数运算的结果是否发生了溢出。如果发生溢出,OF=1;如果没有,OF=0.
一定要注意CF和OF的区别:CF是对无符号数运算有意义的标志位,而OF是对有符号运算有意义的标志位。
adc带进位加法指令,它利用了CF位上记录的进位值。
格式:adc op1,op2
功能: op1=op1+op2+CF
注意:如果用到这个指令,一定要密切注意所有可能影响CF标志的指令!!!
sbb带借位减法指令,它利用了CF位上记录的借位值。
格式:sbb op1,op2
功能:op1=op1-op2-CF
注意:如果用到这个指令,一定要密切注意所有可能影响CF标志的指令!!!
CPU提供了cmp指令,也提供了je等条件转移指令,如果将它们配合使用,可以实现根据比较结果进行转移的功能。但这只是“如果”,只是一种合理的建议,和事实上常用的方法。但究竟是否配合使用它们,完全是你自己的事情。这就好像call和ret指令的关系一样。
DF标志和串传送指令
DF:方向标志位。在串处理指令中,控制每次操作后si、di的增减。
df=0 每次操作后si、di递增;
df=1 每次操作后si、di递减。
cld指令:将标识寄存器的df位置0
std指令:将标识寄存器的df位置1
串传送指令:
movsb:将ds:di指向的内存单元中的字节送入es:di中,然后根据标志寄存器df位的值,将si和di递增或递减。
功能相当于如下几步:
1、((es)*16+(di))=((ds)*16+(si))
2、如果df=0,则:(si)=(si)+1 , (di)=(di)+1
如果df=1,则:(si)=(si)-1 , (di)=(di)-1
movsw:将ds:di指向的内存单元中的字送入es:di中,然后根据标志寄存器df位的值,将si和di递增2或递减2。
功能相当于如下几步:
1、((es)*16+(di))=((ds)*16+(si))
2、如果df=0,则:(si)=(si)+2 , (di)=(di)+2
如果df=1,则:(si)=(si)-2 , (di)=(di)-2
movsb和movsw进行的是串传送操作中的一个步骤,一般来说,movsb和movsw都和rep配合使用,格式如下:
rep movsb.用汇编语法来描述rep movsb的功能就是:
s:movsb
loop s
pushf的功能是将标志寄存器的值压栈,而popf是从栈中弹出数据,送入标志寄存器中。
pushf和popf,为直接访问标志寄存器提供了一种方法。
第12章 内中断
中断向量表:对于8086PC机,中断向量表指定放在内存地址0处。从内存0000:0000到0000:03FF的1024个单元中存放。
中断向量表的一个表项占两个字,高地址字存放段地址,低地址字存放偏移地址。
8086CPU在收到中断信息后,引发中断过程:
1、从中断信息中取得中断类型码;
2、标志寄存器的值入栈;
3、设置标志寄存器的第8位TF和第9位IF的值为0;
4、CS的内容入栈;
5、IP的内容入栈;
6、从内存地址为中断类型码*4 和 中断类型码*4+2 的两个字单元中读取中断处理程序的入口地址设置IP和CS。
更简洁的描述:
1、取得中断类型码N;
2、pushf
3、TF=0,IF=0
4、push CS
5、push IP
6、(IP)=(N*4),(CS)=(N*4+2)
TF和IF设为0,是为了避免在中断程序处理过程中还是单步调试状态。
中断处理程序的编写方法和子程序的比较相似,下面是常规步骤:
1、保存用到的寄存器;
2、处理中断;
3、恢复用到的寄存器;
4、用iret指令返回。
iret指令的功能用汇编语法描述为:
pop IP
pop CS
popf
定制中断处理程序,就是将中断处理程序代码写到固定的内存地址,然后修改中断向量表中该中断类型对应的处理程序的偏移地址。
第13章 int指令
int指令和iret指令的配合使用与call指令和ret指令的配合使用具有相似的思路。
编写中断例程,就类似于编写子程序,我们希望中断处理完成后能继续回到原程序继续运行,所以应该使得中断例程返回。像上一章中中断程序用int 21h终止进程的情况是很特殊的。不过要注意的是,中断例程的返回需要用iret!
BIOS和DOS所提供的中断例程
在系统板的ROM中存放着一套程序,称为BIOS(基本输入输出系统),BIOS中主要包含以下几部分内容。
1、硬件系统的检测和初始化程序;
2、外部中断和内部中断的中断例程;
3、用于对硬件设备进行I/O操作的中断例程;
4、其他和硬件系统相关的中断例程。
操作系统DOS也提供了中断例程,从操作系统的角度来看,DOS的中断例程就是操作系统向程序员提供的编程资源。
BIOS和DOS在所提供的中断例程中包含了许多子程序,这些子程序实现了程序员在编程的时候经常需要用到的功能。程序员在编程的时候,可以用int指令直接调用BIOS和DOS提供的中断例程,来完成某些工作。
和硬件设备相关的DOS中断例程中,一般都调用了BIOS的中断例程。
BIOS和DOS中断例程安装过程:
1、开机后,CPU一加电,初始化CS=0FFFFH,IP=0,自动从FFFF:0单元开始执行程序。FFFF:0处有一条跳转指令,CPU执行该指令后,转去执行BIOS中的硬件系统检测和初始化程序。
跳转指令:jmp F000:998A
此处的指令不可修改!
2、初始化程序将建立BIOS所支持的中断向量,即将BIOS提供的中断例程的入口地址登记在中断向量表中。注意,对于BIOS所提供的中断例程,只需将入口地址登记在中断向量表中即可,因为它们是固化到ROM中的程序,一直在内存中存在。
3、硬件系统检测和初始化完成后,调用int 19h进行操作系统的引导。从此将计算机交由操作系统控制。
证明int 19h只是BIOS提供的功能。
4、DOS启动后,除完成其他工作外,还将它所提供的中断例程装入内存,并建立相应的中断向量。
BIOS中断例程:
int 10h中断例程是BIOS提供的中断例程,其中包含了多个和屏幕输出相关的子程序。
一般来说,一个供程序员调用的中断例程中往往包括多个子程序,中断例程内部用传递进来的参数来决定执行哪一个子程序。BIOS和DOS提供的中断例程,都用ah来传递内部子程序的编号。
DOS中断例程:
int 21h中断例程是DOS提供的中断例程,其中包含了DOS提供给程序员在编程时调用的子程序。
第14章 端口
我们前面讲过,各种存储器都和CPU的地址线、数据线、控制线相连。CPU在操控它们的时候,把它们都当做内存来对待,把它们总地看做一个由若干存储单元组成的逻辑存储器,这个逻辑存储器我们称其位内存地址空间。
在PC机系统中,和CPU通过总线相连的芯片除各种存储器外,还有以下3中芯片。
1、各种接口卡(比如,网卡、显卡)上的接口芯片,他们控制接口卡进行工作;
2、主板上的接口芯片,CPU通过它们对部分外设进行访问;
3、其他芯片,用来存储相关的系统信息,或进行相关的输入输出处理。
在这些芯片中,都有一组可以由CPU读写的寄存器。这些寄存器,它们在物理上可能处于不同的芯片中,但是他们在以下两点上相同。
1、都和CPU的总线相连,当然这种连接是通过它们所在的芯片进行的。
2、CPU对它们进行读或写的时候都通过控制线向它们所在的芯片发出端口读写命令。
可见,从CPU的角度,将这些寄存器都当做端口,对它们进行统一编址,从而建立了一个统一的端口地址空间。每一个端口在地址空间中都有一个地址。
#######问题:
1、如何将某个芯片绑定到某个端口?还是操作系统预设的?那要是出现冲突怎么办?
2、端口地址空间被内存地址空间是同一个吗?也就是说:端口地址空间是内存地址空间的一个子集,还是另一个独立的地址空间?
3、这里讲的端口与网络程序中说的端口是一个概念吗?
CPU可以直接读写以下3个地方的数据。
1、CPU内部的寄存器;
2、内存单元;
3、端口。
端口的读写
在访问端口的时候,CPU通过端口地址来定位端口,因为端口所在的芯片和CPU通过总线相连,所以,端口地址和内存地址一样,通过地址总线来传送。在PC系统中,CPU最多可以定位64KB个不同的端口。则端口地址的范围为0~65535.
对端口的读写不能用mov、push、pop等内存读写指令。端口的读写指令只有两种:in和out,分别用于从端口读取数据和往端口写入数据。
注意,在in和out指令中,只能使用ax或al来存放从端口中读入的数据或要发送到端口中的数据。访问8为端口时用al,访问16位端口时用ax。
对0~255以内的端口进行读写时,地址直接写端口号。
in al,20h ;从20h端口读入一个字节
out 20h,al ;往20h端口写入一个字节
对256~65535的端口读写时,端口号放在dx中。
mov dx,3f8h ;将端口号3f8h送入dx
in al,dx ;从3f8h端口读入一个字节
out dx,al ;想3f8h端口写入一个字节
对存储芯片的操作需要两个端口:地址端口和数据端口,读写分两步进行,先将单元号送地址端口,然后再利用数据渡口进行读或者写。
但对一些别的外设,比如键盘输入,就只有一个端口。
但是如何知道一个芯片到底有多少个有效单元呢?有指令能查询吗?
shl和shr逻辑移位指令:
shl是逻辑左移指令,功能为:
1、将一个寄存器或内存单元中的数据向左移位;
2、将最后移出的一位写入CF中;
3、最低位用0补充。
如果移动位数大于1时,必须将移动位数放在cl中。
shr是逻辑右移指令,功能为:
1、将一个寄存器或内存单元中的数据向右移位;
2、将最后移出的一位写入CF中;
3、最高位用0补充。
如果移动位数大于1时,必须将移动位数放在cl中。
第15章 外中断
在PC系统中,外中断源一共有以下两类:
1、可屏蔽中断
可屏蔽中断是CPU可以不响应的外中断。CPU是否相应可屏蔽中断,要看标志寄存器的IF位的设置。当CPU检测到可屏蔽中断信息时,如果IF=1,则CPU在执行完当前指令后相应中断,引发中断过程;如果IF=0,则不响应可屏蔽中断。
2、不可屏蔽中断
不可屏蔽中断是CPU必须响应的外中断。当CPU检测到不可屏蔽中断信息时,则在执行完当前指令后,立即响应,引发中断过程。
对于8086CPU,不可屏蔽中断的中断类型码固定为2,所以中断过程中,不需要取中断类型码。
几乎所有由外设引发的外中断,都是可屏蔽中断。
CPU对外设输入的通常处理方法:
1、外设的输入送入端口;
2、向CPU发出外中断(可屏蔽中断)信息;
3、CPU检测到可屏蔽中断信息,如果IF=1,CPU在执行完当前指令后响应中断,执行响应的中断例程;
4、可在中断例程中实现对外设输入的处理。
端口和中断机制,是CPU进行I/O的基础。
第16章 直接定址表
注意:标号定位的是绝对地址,如果需要将程序安装到别的地址,类似于中断程序,由标号定位的地址可能产生错误。
《80x86汇编语言程序设计教程》学习笔记
8086指令系统
8086指令系统可分为如下六个功能组:
1、数据传送
2、算术运算
3、逻辑运算
4、串操作
5、程序控制
6、处理器控制
对于每一条指令,程序员要注意:
1、指令的功能;
2、适用于指令的操作数的寻址方式;
3、指令对标志的影响;
4、指令的长度和执行时间。
数据传送指令组又可分为:传送指令,交换指令,地址传送指令,堆栈操作指令,标志传送指令,查表指令,输入输出指令。
除了SAHF和POPF指令外,这组指令对各标志没有影响。
传送指令mov;变换指令xchg;
地址传送指令LEA:lea reg,oprd 该指令把操作数oprd的有效地址传送到操作数reg。
LDS:lds reg,oprd 该指令把操作数oprd中所含的一个32位地址指针的段值部分送到数据段寄存器DS,把偏移部分送到指令给出的通用寄存器REG。
LES:les reg,oprd 该指令把操作数oprd中所含的32位地址指针的段值部分送到附加段寄存器ES,把偏移部分送到指令给出的通用寄存器reg。
入栈push;出栈pop。
标志传送指令:
LAHF:该指令把标志寄存器的低8位(包括SF、ZF、AF、PF、CF)传送到AH的指定位。
SAHF:与LAHF相反,把AH的指定位送到标志寄存器的低8位。
PUSHF/POPF.
标志位操作指令,属于处理器控制指令组:
CLC:使进位标志为0
STC:使进位标志为1
CMC:使进位标志取反。
CLD:使方向标志DF=0.
STD:使DF=1
CLI:IF=0
STI:IF=1