汇编基础之寄存器及汇编指令

参考链接:
http://www.cnblogs.com/technology/archive/2010/05/16/1736782.html
http://anonymalias.github.io/2017/01/09/ucontext-theory/

最近在学习协程方面的知识,在协程的一种实现方式中有一种是用汇编实现的,所以这里再把汇编知识复习一下。

寄存器

寄存器按照其用途可分为以下4类:

  • 数据寄存器
  • 指针及变址寄存器
  • 段寄存器
  • 控制寄存器

数据寄存器

数据寄存器包括4个16位的寄存器(AX,BX,CX,DX)或者8个8位的寄存器(AH,AL,BH,BL,CH,CL,DH,DL),这些寄存器都是用来暂时存放操作数,运算结果或者其他信息,但同时又具有某些专门的用途。

  • AX(累加寄存器):算术运算中的主要寄存器,在乘除运算中用来指定除数和被除数,也是乘除运算后积和商的默认存储单元。,另外IO指令均使用该寄存器与IO设备传送信息
  • BX(基址寄存器):指令寻址时常用作基址寄存器,存入偏移量或者偏移量的构成部分。
  • CX(计数寄存器):在循环指令操作或者串处理指令中隐含计数
  • DX(数据寄存器):在双字节运算中,与AX构成32位操作数,DX为高16位。在某些IO指令中,DX被用来存放端口地址

指针及变址寄存器

这些寄存器都是16位的寄存器,用来存放16为的操作数或者中间结果,但是更常见的是存放偏移量或者位移量

  • SP(堆栈指针寄存器):指向栈顶的位置,与SS寄存器一起组成栈顶数据的物理地址
  • BP(基址指针寄存器):系统默认其指向堆栈中的某一单元,即提供栈中该单元偏移量,加段前缀后,BP可作为非堆栈段的地址指针。一般用于识别栈帧的起始位置。
  • SI(源变址寄存器):与DS联用, 指示数据段中某操作的偏移量. 在做串处理时, SI指示源操作数地址, 并有自动增量或自动减量的功能. 变址寻址时, SI与某一位移量共同构成操作数的偏移量
  • DI(目的变址寄存器):与DS联用, 指示数据段中某操作数的偏移量, 或与某一位移量共同构成操作数的偏移量. 串处理操作时, DI指示附加段中目的地址, 并有自动增量或减量的功能

段寄存器

  • CS(代码段):存放当前程序的指令代码
  • DS(数据段):存放程序所涉及的源数据以及结果
  • SS(堆栈段):以先进后出原则的数据区
  • ES(附加段):辅助数据区,存放串或者其他数据

控制寄存器

  • IP(指令寄存器): 存放下一条要执行的指令的偏移量
  • FR(控制标志位):
    • CF(进位标识位):进行加减运算时, 如果最高二进制位产生进位或错位, CF则为1, 否则为0. 程序设计中, 常用条件转移指令JC, JNC指令据此标志位实现转移
    • PF(奇偶标志位):操作结果中二进制位1的个数为偶数是, PF为1, 某则为0
    • AF(辅助进位标志位):运算时半字节产生进位或借位时, AF为1, 某则为0. 主要用于BCD码的调整
    • ZF(零标志位):运算结果为0时, ZF为1, 否则为0
    • SF(符号标志位):当运算结果的最高位为1时, SF为1, 否则为0. 最高位表示符号数的正和负
    • TF(跟踪标志位):用于调试程序时进入单步方式工作. TF=1时, 每条指令执行完后产生一个内部中断, 让用户检查指令运行后寄存器, 存储器和各标志位的内容. TF=0时, CPU工作正常, 不产生内部中断
    • IF(中断允许标志位):IF=1同时中断屏蔽寄存器的相应位为0, 允许系统响应可屏蔽中断, 反之, 不接收外部发出的中断请求
    • DF(方向位标志位):用于控制串操作时地址指针位移方向. 当DF=1时, 指针向高地址方向移动
    • OF(溢出标志位):算术运算时结果超出系统所能表示的数的范围. 溢出时, OF=1

注意:上述为16位处理其器中的寄存器的名字,在32和64位系统中,寄存器中名字有相应的变化,具体看下面(32位在前面加E,64在前面加R,64位系统的中含有16个64位的通用寄存器):

i386常用的16个寄存器

  • EAX、EBX、ECX、EDX这四个寄存器,主要就是用来暂时存放计算过程中所用的操作数、结果或其它信息。
  • ESP为堆栈指针寄存,它和堆栈段寄存器SS共同决定了当前的栈指针,每当执行push,pull操作时,或者因为某些原因(如中断),CPU自动将数据入栈时,就会使用该指针来找到堆栈栈顶(或栈底)的位置,然后执行压栈、出栈的操作。系统管理软件,如操作系统会根据其分配的栈空间地址来设定这两个寄存器的值。
  • EBP称为基址指针寄存器,它和ESP都可以与堆栈段寄存器SS联用来确定堆栈中的某一存储单元的地址,ESP用来指示段顶的偏移地址,而EBP可作为堆栈区中的一个基地址以便访问堆栈中的信息。
  • ESI(源变址寄存器)和EDI(目的变址寄存器)一般与数据段寄存器DS联用,用来确定数据段中某一存储单元的地址。这两个变址寄存器有自动增量和自动减量的功能,可以很方便地用于变址。在串处理指令中,ESI和EDI作为隐含的源变址和目的变址寄存器时,ESI和DS联用,EDI和附加段ES联用,分别达到在数据段和附加段中寻址的目的。
  • EIP指令指针寄存器,它用来存放代码段中的偏移地址。在程序运行的过程中,它始终指向下一条指令的首地址。它与段寄存器CS联用确定下一条指令的物理地址。当这一地址送到存储器后,控制器可以取得下一条要执行的指令,而控制器一旦取得这条指令就马上修改EIP的内容,使它始终指向下一条指令的首地址。那些跳转指令,就是通过修改EIP的值来达到相应的目的的
  • FLAGS标志寄存器,又称PSW(program status word),即程序状态寄存器。这一个是存放条件标志码、控制标志和系统标志的寄存器。
  • 段寄存器:一共六个,分别是CS代码段,DS数据段,ES附加段,SS堆栈段,FS以及GS这两个还是附加段。
    EFLAGS寄存器中的IF位表示是否允许中断,为1允许,否则不允许。
  • TR寄存器:用来指向当前任务的TSS段
  • IDTR寄存器:用来指向当前IDT(中断表述符表或者说是中断向量表),因为在保护模式下,IDT的起始地址可以在任何位置,而不仅限于地址0。
  • GDT和LDT : 前者是全局描述符表,位置由GDTR寄存器确定,后者是局部描述符表,位置由LDTR寄存器确定,具体使用哪一个,取决于段选择码中的TI位。

汇编指令

汇编指令格式

汇编指令的格式如下:

1
[标号:] 指令助记符[[目的操作数][,源操作数]][;注释]

  • 指令助记符:如MOV,ADD之类标识传送,加法。不区分大小写
  • 目的操作数:作用有两个,1.参与指令操作2,暂时存储操作结果
  • 源操作数:主要提供原始数据或操作对象。面向所有寻址方式
  • 注释:用分号隔开

汇编指令中常见的符号:

  • imme:立即数
  • DST:目的操作数
  • SRC:源操作数
  • mem:存储器操作数
  • OPR:操作数
  • reg:通用寄存器
  • EA:偏移地址
  • Sreg:段寄存器
  • Port:端口地址
  • Lable:标号

汇编指令可以分成六类:

  • 数据传送指令
  • 算数运算指
  • 逻辑运算与移位指令
  • 串操作指令
  • 程序控制指令
  • 处理器控制指令

    数据传送指令

    数据传送指令

  • MOV DST,SRC(传送指令):把源操作数的内容送入目的操作数
    • 立即数做源操作数时,立即数的长度必须小于等于目的操作数的长度
    • 操作数分别为reg,reg或reg,sreg或sreg,sreg或reg,sreg时,两者的长度必须保持一致
    • 立即数不能作为目的操作数
    • CS和IP寄存器不能做目的操作数,不允许用立即数为段寄存器赋值
    • 不能将一个段寄存器的内容直接送到另一个段寄存器中, 可借助通用寄存器或PUSH, POP指令实现这一要求
  • PUSH SRC(压栈指令): 将一个字数据压入当前栈顶, 位移量disp=-2的地址单元. 数据进栈时, 栈指针SP首先向低地址方向移动两个字节位置, 接着数据进栈, 形成新的栈顶
  • POP DST(出栈指令):弹出栈顶元素, 后将栈顶指针向栈底方向移动一个字
  • XCHG OPR1, OPR2(交换指令):交换指令: 将这两个操作数交换

地址传送指令

  • LEA DST, SRC(装载有效指令):该指令将源操作数的偏移量OA装载到目的操作数中
  • LDS DST, SRC(装载数据段指针指令):将当前数据段中的一个双字数据装入到一个通用寄存器SI(双字数据的低字)和数据段寄存器DS(双字数据的高字)中
  • LES DST,SRC(装载附加段指针指令):将附加数据段中的一个32位地址数据指针(附加段指针)送到DI(低字)和ES(高字)寄存器中

标志传送指令

  • LAHF(标志寄存器送AH指令): 将标志寄存器的低字节送入AH中
  • SAHF(AH送标志寄存器指令): 将AH寄存器内容送标志寄存器FR的低字节
  • PUSHF(标志进栈指令): 标志寄存器进栈
  • POPF (标志出栈指令): 标志寄存器出栈

累加器专用传送指令

  • IN AL, Port:从端口读入数据, 存放在AL中
  • OUT PORT,AL:传送AL中的数据到端口
  • XLAT OPR或XLAT:用于将AL中当前内容转换为一种代码

算术运算指令

加法指令

  • ADD DST, SRC:DST+SRC的和存放到DST中去
  • ADC DST, SRC:带进位加法指令, DST+SRC+CF
  • INC DST:增1指令

减法指令

  • SUB DST, RSC:DST-SRC, 存放到DST中
  • SBB DST, SRC:带借位减法指令, DST-SRC-CF
  • DEC DST :减1指令
  • NEG DST:求补指令, 求补码
  • CMP OPR1, OPR2:比较指令

乘法指令

  • MUL SRC:无符号数乘指令, AL*SRC, 结果放入AX中
  • IMUL SRC:有符号数乘指令, AL*SRC, 结果放入AX中

除法指令

  • DIV SRC :无符号数除指令, AX/SRC, 商放入AL中, 余数放在AH中
  • IDIV SRC:符号数除指令, AX/SRC, 上放入AL中, 余数放在AH中
  • CBW, CWD:都是符号扩展指令. 将AL的符号扩到AX中; 将AX的符号扩到DX

逻辑运算与移位指令

逻辑运算指令

  • NOT OPR:逻辑非指令
  • AND OPR:逻辑与指令
  • OR OPR:逻辑或指令
  • XOR OPR :逻辑异或指令

移位指令:

  • SHL DST, CNT:逻辑左移
  • SHR DST, CNT:逻辑右移
  • SAL DST, CNT:算术左移
  • SAR DST, CNT:算术右移

循环移位指令

  • ROL DST, CNT:循环左移
  • ROR DST, CNT:循环右移
  • RCL DST, CNT:带进位循环左移
  • RCR DST, CNT:带进位循环右移

串操作指令

  • MOVS:串传送指令
  • CMPS:串比较指令
  • SCAS:串扫描指令
  • LODS:装入串指令
  • STOS:存储串指令

控制转移指令

转移指令:

  • JMP:无条件转移指令
  • JX:条件转移指令(JC/JNC, JZ/JNZ, JE/JNE, JS/JNS, JO/JNO, JP/JNP…)

循环指令

  • LOOP 标号:该指令执行时, 技术寄存器CXX首先减1, 然后判断CX, 若为0, 跳出循环

条件循环指令

  • LOOPZ/LOOPE, LOOPNZ/LOOPNE:前者用于找到第一个不为0的事件, 后者用于找到第一个为0的事件

子程序调用指令

  • CALL 子程序名:段内直接调用
  • RET

中断指令

  • INT N(中断类型号):软中断指令
  • IRET:中断返回指令

处理器控制指令

标志处理指令:

  • CLC:进位标志CF置0
  • CMC:进位标志CF求反
  • STC:进位标志值1
  • CLD:方向标志置0
  • STD:方向标志置1
  • CLI:中断允许标志置0
  • STI:中断允许标志置1

其他处理器控制指令:

  • NOP:空操作
  • HLT:停机
  • WAIT:等待
  • ESC:换码
  • LOCK:封锁

Comment and share

  • page 1 of 1

魏传柳(2824759538@qq.com)

author.bio


Tencent


ShenZhen,China