汇编

1.寄存器

1.1 段寄存器

段寄存器是根据内存分段的管理模式而设置的。内存单元的物理地址由段寄存器的值和一个偏移量组合而成的,这样可用两个较少位数的值组合成一个可访问较大物理空间的内存地址。
8个顺序固定的段寄存器:ES、CS、SS、DS、FS、GS、LDTR、TR
CPU内部的段寄存器:
CS——代码段寄存器(Code Segment Register),其值为代码段的段值;
DS——数据段寄存器(Data Segment Register),其值为数据段的段值;
ES——附加段寄存器(Extra Segment Register),其值为附加数据段的段值;
SS——堆栈段寄存器(Stack Segment Register),其值为堆栈段的段值;
FS——附加段寄存器(Extra Segment Register),其值为附加数据段的段值;
GS——附加段寄存器(Extra Segment Register),其值为附加数据段的段值。
在16位CPU系统中,它只有4个段寄存器,所以,程序在任何时刻至多有4个正在使用的段可直接访问;在32位微机系统中,它有6个段寄存器,所以,在此环境下开发的程序最多可同时访问6个段。32位CPU有两个不同的工作方式:实方式和保护方式。在每种方式下,段寄存器的作用是不同的。有关规定简单描述如下:
实方式: 前4个段寄存器CS、DS、ES和SS与先前CPU中的所对应的段寄存器的含义完全一致,内存单元的逻辑地址仍为”段值:偏移量”的形式。为访问某内存段内的数据,必须使用该段寄存器和存储单元的偏移量。
保护方式: 在此方式下,情况要复杂得多,装入段寄存器的不再是段值,而是称为”选择子”(Selector)的某个值。
Win32 保护模式下编程它们不再重要了.

1.2 寄存器

eax, ecx, edx, ebx, esp. ebp, esi, edi ,eip. efl

名称说明名称说明
EAX累加(Accumulator)寄存器AX(AH、AL)常用于乘、除法和函数返回值
EBX基址(Base)寄存器BX(BH、BL)常做内存数据的指针, 或者说常以它为基址来访问内存.
ECX计数器(Counter)寄存器CX(CH、CL)常做字符串和循环操作中的计数器
EDX数据(Data)寄存器DX(DH、DL)常用于乘、除法和 I/O 指针
ESI来源索引(Source Index)寄存器SI常做内存数据指针和源字符串指针
EDI目的索引(Destination Index)寄存器DI常做内存数据指针和目的字符串指针
ESP堆栈指针(Stack Point)寄存器SP只做堆栈的栈顶指针; 不能用于算术运算与数据传送
EBP基址指针(Base Point)寄存器BP只做堆栈指针, 可以访问堆栈内任意地址, 经常用于中转 ESP 中的数据, 也常以它为基址来访问堆栈; 不能用于算术运算与数据传送

EAX、ECX、EDX 三个寄存器相对自由些, 所以学习时使用较多.

1.2.1 分类

4个数据寄存器(EAX、EBX、ECX、EDX)

用来保存操作数和运算结果等信息,节省读取操作数所需占用总线和访问存储器的时间,32位CPU有4个32位的通用寄存器EAX、EBX、ECX和EDX。对低16位数据的存取,不会影响高16位的数据。这些低16位寄存器分别命名为:AX、BX、CX和DX,它和先前的CPU中的寄存器相一致。4个16位寄存器又可分割成8个独立的8位寄存器(AX:AH-AL、BX:BH-BL、CX:CH-CL、DX:DH-DL),每个寄存器都有自己的名称,可独立存取。程序员可利用数据寄存器的这种“可分可合”的特性,灵活地处理字/字节的信息。

寄存器AX和AL通常称为累加器(Accumulator),用累加器进行的操作可能需要更少时间。累加器可用于乘、 除、输入/输出等操作,它们的使用频率很高;
寄存器BX称为基地址寄存器(Base Register),它可作为存储器指针来使用;
寄存器CX称为计数寄存器(Count Register),在循环和字符串操作时,要用它来控制循环次数;在位操作 中,当移多位时,要用CL来指明移位的位数;
寄存器DX称为数据寄存器(Data Register),在进行乘、除运算时,它可作为默认的操作数参与运算,也 可用于存放I/O的端口地址。

16位CPU中,AX、BX、CX和DX不能作为基址和变址寄存器来存放存储单元的地址,但在32位CPU中,其32位寄存器EAX、EBX、ECX和EDX不仅可传送数据、暂存数据保存算术逻辑运算结果,而且也可作为指针寄存器,所以,这些32位寄存器更具有通用性。

2个变址和指针寄存器(ESI、EDI)

32位CPU有2个32位通用寄存器ESI和EDI。其低16位对应先前CPU中的SI和DI。ESI、EDI、SI和DI称为变址寄存器(Index Register),它们主要用于存放存储单元在段内的偏移量,用它们可实现多种存储器操作数的寻址方式,为以不同的地址形式访问存储单元提供方便。变址寄存器不可分割成8位寄存器。
作为通用寄存器,也可存储算术逻辑运算的操作数和运算结果。它们可作一般的存储器指针使用。在字符串操作指令的执行过程中,对它们有特定的要求,而且还具有特殊的功能。

2个指针寄存器(ESP、EBP)

其低16位对应先前CPU中的BP和SP,EBP、ESP、BP和SP称为指针寄存器(Pointer Register)。主要用于存放堆栈内存储单元的偏移量,用它们可实现多种存储器操作数的寻址方式,为以不同的地址形式访问存储单元提供方便。指针寄存器不可分割成8位寄存器。作为通用寄存器,也可存储算术逻辑运算的操作数和运算结果。
主要用于访问堆栈内的存储单元,并且规定:
BP为基指针(Base Pointer)寄存器,通过它减去一定的偏移值,来访问栈中的元素;
SP为堆栈指针(Stack Pointer)寄存器,它始终指向栈顶。
说明:因栈的生长方向是从高地址向低地址生长,所以,进栈时,sp自减;出栈时,sp自增;

1.3 指令寄存器 (Instruction Pointe)

EIP 指令指针(Instruction Pointer)寄存器 总是指向下一条指令的地址; 所有已执行的指令都被它指向过.
32位CPU把指令指针扩展到32位,并记作EIP,EIP的低16位与先前CPU中的IP作用相同。
指令指针EIP、IP(Instruction Pointer)是存放下次将要执行的指令在代码段的偏移量。在具有预取指令功能的系统中,下次要执行的指令通常已被预取到指令队列中,除非发生转移情况。所以,在理解它们的功能时,不考虑存在指令队列的情况。
在实模式下,由于每个段的最大范围为64K,所以,EIP中的高16位肯定都为0,此时,相当于只用其低16位的IP来反映程序中指令的执行次序。

1.4 标志寄存器

标志中文名说明
CF进位标志(carry flag)主要反映算术运算是否产生进位或借位,若产生,则CF=1,否则CF=0
ZF零标志反映运算结果是否为0
SF符号标志(sign flag)根据运算结果的最高位,若最高位为1则SF为1,否则为0,反映了有符号数运算结果的正负(0正1负)
OF溢出标志(overflow flag)反映有符号数运算结果是否产生溢出,是置1,否置0
PF奇偶标志(parity flag)偶数置1奇数置0
AF辅助进位标志

EFLAGS 中的 32 位:
第 0、2、4、6、7、11 位是状态标志位;
第 10 位是字符串操作控制标志位;
其他标志位一般不用或无权使用

code名称说明
0CF进位(Carry)标志目标无法容纳无符号算术运算的结果, 需要进位或借位时被设置; 可用 STC 指令设置, CLC 指令取消.
1
2PF奇偶(Parity)标志低 8 位中有偶数个 1 时被设置
3
4AF辅助(Auxiliary)标志使用 BCD 码运算导致 3 位到 4 位产生进位时被设置
5
6ZF零(Zero)标志运算结果为 0 时被设置
7SF符号(Sign)标志运算结果为负数时被设置
8TF追踪标志 Trap Flag
9IF中断允许标志Interrupt-enable Flag
10DF方向(Direction)标志字符串操作是从高位到低位时被设置; 可用 STD 指令设置, CLD 指令取消.
11OF溢出(Overflow)标志因有符号运算的结果太宽而导致数据丢失时被设置
31

进位标志CF(Carry Flag)

CF主要用来反映运算是否产生进位或借位。如果运算结果的最高位产生了一个进位或借位,那么,其值为1,否则其值为0。

奇偶标志PF(Parity Flag)

PF用于反映运算结果中”1″的个数的奇偶性。如果”1″的个数为偶数,则PF的值为1,否则其值为0。

辅助进位标志AF(Auxiliary Carry Flag)

在发生下列情况时,辅助进位标志AF的值被置为1,否则其值为0:
(1)、在字操作时,发生低字节向高字节进位或借位时;
(2)、在字节操作时,发生低4位向高4位进位或借位时。

零标志ZF(Zero Flag)

零标志ZF用来反映运算结果是否为0。如果运算结果为0,则其值为1,否则其值为0。

符号标志SF(Sign Flag)

SF用来反映运算结果的符号位,它与运算结果的最高位相同。在微机系统中,有符号数采用补码表示法,所以,SF也就反映运算结果的正负号。运算结果为正数时,SF的值为0,否则其值为1。

溢出标志OF(Overflow Flag)

OF用于反映有符号数加减运算所得结果是否溢出。如果运算结果超过当前运算位数所能表示的范围,则称为溢出,OF的值被置为1,否则,OF的值被清为0。

状态控制标志位

用来控制CPU操作的,它们要通过专门的指令才能使之发生改变。

  1. 追踪标志TF(Trap Flag)
    TF被置为1时,CPU进入单步执行方式,即每执行一条指令,产生一个单步中断请求。这种方式主要用于程序的调试。指令系统中没有专门的指令来改变标志位TF的值。
  2. 中断允许标志IF(Interrupt-enable Flag)
    IF是用来决定CPU是否响应CPU外部的可屏蔽中断发出的中断请求。但不管该标志为何值,CPU都必须响应CPU外部的不可屏蔽中断所发出的中断请求,以及CPU内部产生的中断请求。具体规定如下:
    (1)、当IF=1时,CPU可以响应CPU外部的可屏蔽中断发出的中断请求;
    (2)、当IF=0时,CPU不响应CPU外部的可屏蔽中断发出的中断请求。
    CPU的指令系统中也有专门的指令来改变标志位IF的值。
  3. 方向标志DF(Direction Flag)
    DF用来决定在串操作指令执行时有关指针寄存器发生调整的方向。在微机的指令系统中,还提供了专门的指令来改变标志位DF的值。

1.5 其他寄存器

FPU、MMX 系列寄存器

2.指令

硬编码指令格式分类中文名说明备注
89MOVMOV DEST,SRC传送指令传送指令DEST<=SRC
87XCHGXCHG OPER1,OPER2传送指令交换指令把操作数oper1的内容与操作数oper2的内容交换per1和oper2可以是通用寄存器或存储单元,但不能同时是操作单元,也不能是立即数。
83ADDADD DEST,SRC加减指令DEST<=DEST SRC
SUBSUB DEST,SRC加减指令减法指令DEST<=DEST SRC
INCINC DEST加减指令加1指令DEST<=DEST+1
DECDEC DEST加减指令减1指令DEST<=DEST-1
NEGNEG OPRD加减指令取补指令OPRD=0-OPRD对操作数取补(相反数)
CLCCLC状态标志操作指令清进位标志指令clear carry flag使进位标志CF为0
STCSTC状态标志操作指令置进位标志指令(set carry flag)使进位标志CF为1
CMCCMC状态标志操作指令进位标志取反指令complement carry flag使进位标志CF取反
LAHFLAHF状态标志操作指令获取状态标志操作指令load status flags into AH register把位于标志寄存器低端的5个状态标志位信息同时送到寄存器AH的对应位
SAHFSAHF状态标志操作指令设置状态标志操作指令store AH into Flags对标志寄存器中的低8位产生影响,使得状态标志位SF、ZF、AF、PF和CF分别成为来自寄存器AH中对应位的值,但保留位(位1、位3、位5)不受影响
ADCADC DEST,SRC加减指令带进位加法指令(add with carry)DEST<=DEST SRC CF与add指令不同之处是要再加上进位标志cf的值
SBBSBB DEST,SRC加减指令带借位减法substraction with borrowDEST<=DEST-(SRC CF)与sub指令不同之处是要再减上借位标志cf的值
LEALEA REC,OPRD取有效地址指令把操作数oprd的有效地址传送到操作数rec,源操作数oprd必须是一个存储器操作数,目的操作数rec必须是一个16位或32位的通用寄存器与mov指令的区别:mov:移动地址中的值lea:将地址进行移动
CMPCMP DEST,SRC比较指令比较指令根据dest-src的差影响各状态标志寄存器不把dest-src的结果送入dest
JMPJMP LABEL转移指令无条件段内直接转移指令使控制无条件地转移到标号为label的位置指令本身不影响标志
PUSHPUSH SRC堆栈指令进栈指令把源操作数src压入堆栈源操作数src可以是32位通用寄存器、16位通用寄存器和段寄存器,也可以是双字存储单元或者字符存储单元,还可以是立即数
POPPOP DEST堆栈指令出栈指令从栈顶弹出一个双字或字数据到目的操作数如果目的操作数是双字的,那么就从栈顶弹出一个双字数据,否则,从栈顶弹出一个字数据,出栈至少弹出一个字(16位)
PUSHAPUSHA堆栈指令16位通用寄存器全进栈指令将所有8个16位通用寄存器的内容压入堆栈压入顺序是AX CX DX BX SP BP SI DI,然后对战指针寄存器SP的值减16,所以SP进栈的内容是PUSHA指令执行之前的值
POPAPOPA堆栈指令16位通用寄存器全出栈指令以PUSHA相反的顺序从堆栈中弹出内容,从而恢复PUSHA之前的寄存器状态SP的值不是由堆栈弹出的,而是通过增加16来恢复
PUSHADPUSHAD堆栈指令32位通用寄存器全进栈指令将所有8个32位通用寄存器的内容压入堆栈压入顺序是EAX ECX EDX EBX ESP EBP ESI EDI,然后对战指针寄存器SP的值减32,所以SP进栈的内容是PUSHAD指令执行之前的值
POPADPOPAD堆栈指令32位通用寄存器全出栈指令以PUSHAD相反的顺序从堆栈中弹出内容,从而恢复PUSHAD之前的寄存器状ESP的值不是由堆栈弹出的,而是通过增加32来恢复
CALLCALL LABEL过程调用过程调用指令段内直接调用LABEL与jmp的区别在于call指令会在调用label之前保存返回地址(call 中return之后主程序还可以继续执行,jmp 当label执行完毕后不能返回主程序继续执行)
RETRET过程调用段内过程返回指令使子程序结束,继续执行主程序
MUL乘除指令无符号数乘法指令
IMULIMUL DEST,SRC,[SRC2]乘除指令有符号数乘法指令
DIV乘除指令无符号数除法指令
IDIV OPRD乘除指令有符号数除法指令
CBW符号拓展指令字节转化为字指令把寄存器AL中的值符号拓展到寄存器AH
CWD符号拓展指令字转化为双字指令把寄存器AX中的值符号拓展到寄存器DX
CDQ符号拓展指令双字转化为四字指令把寄存器EAX中的值符号拓展到EDX
CWDE符号拓展指令字转化为双字指令把AX中的值符号拓展到EAX的高16位
MOVSXMOVSX DEST,SRC传送指令符号拓展传送指令把源操作数SRC符号拓展后送至目的操作数DESTsrc可以是通用寄存器或者存储单元,但是dest只能是通用寄存器(零拓展传送指令不会改变源操作数,也不影响标志寄存器的状态)
MOVZXMOVZX DEST,SRC传送指令把源操作数SRC零拓展后送至目的操作数DEST零拓展传送指令不会改变源操作数,也不影响标志寄存器的状态
NOTNOT OPRD逻辑运算指令否运算指令把操作数OPRD按位取反,然后送回OPRD
ANDAND DEST,SRC逻辑运算指令与运算指令把两个操作数进行与运算之后结果送回DEST同1得1,否则得0
OROR DEST,SRC逻辑运算指令或运算指令把两个操作数进行或运算之后结果送回DEST同0得0,否则得1
XORXOR DEST,SRC逻辑运算指令异或运算把两个操作数进行异或运算之后结果送回DEST相同得0不同得1
TESTTEST DEST,SRC逻辑运算指令测试指令与AND指令类似,将各位相与,但是结果不送回DEST,仅影响状态位标志,指令执行后,ZF、PF、SF反映运算结果,CF和OF被清零通常用于检测某些位是否为1,但又不希望改变操作数的值
SALSAL OPRD,count移位指令算术左移把操作数oprd左移count位,右边补0与shl指令一样,通过截取count的低5位,实际的移位数被限于0到31之间。
SHLSHL OPRD,count移位指令逻辑左移把操作数oprd左移count位,右边补0与sal指令一样,通过截取count的低5位,实际的移位数被限于0到31之间。
SARSAR OPRD,count移位指令算术右移把操作数oprd右移count位,同时每右移一位,左边补符号位,移出的最低位进入标志位CF通过截取count的低5位,实际的移位数被限于0到31之间。
SHRSHR OPRD,count移位指令逻辑右移把操作数oprd右移count位,左边补0,移出的最低位进入标志位CF通过截取count的低5位,实际的移位数被限于0到31之间。
ROLROL OPRD,count移位指令左循环移位指令通过截取count的低5位,实际的移位数被限于0到31之间。
RORROR OPRD,count移位指令右循环移位指令通过截取count的低5位,实际的移位数被限于0到31之间。
RCLRCL OPRD,count移位指令带进位左循环移位相当于CF在最高位参与循环移位大循环左移,通过截取count的低5位,实际的移位数被限于0到31之间。
RCRRCR OPRD,count移位指令带进位右循环移位相当于CF在最高位参与循环移位大循环右移,通过截取count的低5位,实际的移位数被限于0到31之间。
LOOPLOOP LABEL循环指令计数循环指令使ECX的值减1,当ECX的值不为0的时候跳转至LABEL,否则执行LOOP之后的语句
LOOPELOOPE LABEL循环指令等于循环指令使ECX的值减1,如果结果不等于0并且零标志ZF等于1(表示相等),那么就转移到LABEL,否则执行LOOPE之后的语句
LOOPZLOOPZ LABEL循环指令零循环指令使ECX的值减1,如果结果不等于0并且零标志ZF等于1(表示相等),那么就转移到LABEL,否则执行LOOPZ之后的语句
LOOPNELOOPNE LABEL循环指令不等于循环指令使ECX的值减1,如果结果不等于0并且零标志ZF等于0(表示不相等),那么就转移到LABEL,否则执行LOOPNE之后的语句
LOOPNZLOOPNZ LABEL循环指令非零循环指令使ECX的值减1,如果结果不等于0并且零标志ZF等于0(表示不相等),那么就转移到LABEL,否则执行LOOPNZ之后的语句
JECXZJECXZ LABEL循环指令计数转移指令当寄存器ECX的值为0时转移到LABEL,否则顺序执行通常在循环开始之前使用该指令,所以循环次数为0时,就可以跳过循环体
JZ转移指令等于0 跳转 Jump if zeroZF=1
JE转移指令相等跳转 Jump if equalZF=1
JNZ转移指令不等于0 跳转 Jump if not zeroZF=0
JNE转移指令不相等跳转 Jump if not equalZF=0
JS转移指令为负跳转 Jump if signSF=1
JNS转移指令为正数跳转 Jump if not signSF=0
0x70JO转移指令溢出跳转 Jump of overflowOF=1
0x71JNO转移指令不溢出跳转 Jump of not overflowOF=0
JP转移指令偶跳转 Jump if parityPF=1
JPE转移指令偶跳转 Jump if parity evenPF=1
JNP转移指令奇跳转 Jump if not parityPF=0
JPO转移指令奇跳转 Jump if parity oddPF=0
0x72JB转移指令低于跳转 Jump of belowPF=1
JNAE转移指令不高于等于跳转 Jump if not above or equalPF=1
JC转移指令进位位被置跳转 Jump if carryCF=1
JNB转移指令不低于跳转 Jump if not belowCF=0
JAE转移指令高于等于跳转 Jump if above or equalCF=0
JNC转移指令进位位被清跳转 Jump if not carryCF=0
JBE转移指令低于等于跳转 Jump if below or equalCF=1 或者 ZF=1
JNA转移指令不高于 跳转 Jump if not aboveCF=1 或者 ZF=1
JNBE转移指令不低于等于跳转 Jump if not below or equalCF=0 并且 ZF=0
JA转移指令高于跳转 Jump if aboveCF=0 并且 ZF=0
JL转移指令小于跳转Jump if lessSF 不等于 OF两个标志(有符号数)
JNGE转移指令不大于等于跳转 Jump if not greater or equalSF 不等于 OF两个标志(有符号数)
JNL转移指令不小于等于 Jump if not lessSF 等于 OF两个标志(有符号数)
JGE转移指令大于 等于跳转 Jump if greater or equalSF 等于 OF两个标志(有符号数)
JLE转移指令小于等于跳转 Jump if less or equalZF=1 或者 SF 不等于 OF三个标志(有符号数)
JNG转移指令不大于 跳转 Jump if not greaterZF=1 或者 SF 不等于 OF三个标志(有符号数)
JNLE转移指令不小于等于跳转 Jump if not less or equalZF=0 或者 SF 等于 OF三个标志(有符号数)
JG转移指令大于 跳转 Jump if greaterZF=0 或者 SF 等于 OF三个标志(有符号数)
JCXZ转移指令计数器 CX 为 0 跳转CX=0
JECXZ转移指令计数器ECX 为 0 跳转ECX=0

4.汇编语言中PTR

ptr – pointer (既指针),是用来临时指定类型(相当于C语言中的强制类型转换)。比如:
如 mov ax,bx ; 是把BX寄存器“里”的值赋予AX,由于二者都是寄存器,长度已定(word型),所以没有必要加“WORD”
mov ax,word ptr [bx]; 是把内存地址“ [bx]”所存放的数据,赋予ax。由于只是给出一个内存地址,不知道希望赋予ax的,是byte还是word,所以可以用word明确指出;如果不用,既(mov ax, [bx]; )则在8086中是默认传递一个字,既两个字节给ax。
在没有寄存器名存在的情况下,既都是在内存,得用操作符 [byte,word或者DWORD] ptr 指明内存单元的长度。
可以放在ptr前面的类型有byte(字节)、word(字)、dword(双字)、qword(四字)、tbyte(十字节)、far(远类型)和near(近类型)

MOV WORD PTR DS:[0],1
inc word ptr ds:[0]
inc byte ptr [bx]

用于临时变量转换:cmp word ptr[si],'#'

jmp near ptr label
jmp far ptr label
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ynchyong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值