常用汇编指令

参考资料:《汇编语言第三版王爽》

一 说明

  所谓IA32就是“Intel32位体系结构”(Intel Architecture 32-bit),而我们常说的X86-64就是IA32的64为拓展。

二 数据格式

C声明Intel数据类型汇编代码后缀大小(字节)
char字节b1
shortw2
int双字l4
long四字q8
char *双字q4
float单精度s4
double双精度l8

    C语言数据类型在X86-64中的大小,指针8字节

C声明Intel数据类型汇编代码后缀大小(字节)
char字节b1
shortw2
int双字l4
long int双字l4
long long int————4
char *双字l4
float单精度s4
double双精度l8
long double扩展精度t10/12

    C语言数据类型在IA32中的大小,指针4字节
  其实x86-64的汇编指令也是从8086来的,可以说是对8086的命令进行了一些扩展,例如数据传输命令:movb(传送字节)、movw(传送字)、movl(传送双字)和movq(传送四字)。后缀就是表示传送数据的大小。

三 访问信息

  一个X86-64的CPU包含一组16个存储64位值的通用目的寄存器,对于IA32来说,是一组8个存储32位值的通用寄存器,下图红框中即为IA32的寄存器。而且相对于8086,IA32是在寄存器前面加了%e的前缀,X86-64是加了%r的前缀。

四 大小端

  采用Little-endian模式的CPU对操作数的存放方式是从低字节到高字节,而Big-endian模式对操作数的存放方式是从高字节到低字节。
  例如,16bit宽的数0x1234在Little-endian模式CPU内存中的存放方式(假设从地址0x4000开始存放)为:

内存地址0x40000x4001
存放内容0x340x12

而在Big-endian模式CPU内存中的存放方式则为:

内存地址0x40000x4001
存放内容0x120x34

  32bit宽的数0x12345678在Little-endian模式CPU内存中的存放方式(假设从地址0x4000开始存放)为:

内存地址0x40000x40010x40020x4003
存放内容0x780x560x340x12

而在Big-endian模式CPU内存中的存放方式则为:

内存地址0x40000x40010x40020x4003
存放内容0x120x340x560x78

五 寄存器

  32位CPU所含有的14个寄存器有:
  a) 4个数据寄存器(EAX,EBX,ECX,EDX)
  b)2个变址和指针寄存器(ESI EDI)和2个指针寄存器(ESP EBP)
  c)6个段寄存器(ES CS DS SS FS GS)
  d)1个指令指针寄存器(EIP)和1个标志位寄存器(EFlags)

1 数据寄存器

  数据寄存器主要用来保存操作数和运算结果等信息,从而节省读取操作数所需占用总线和访问存储器的时间。32位CPU有4个32位的通用寄存器EAX、EBX、ECX和EDX。对低16位数据的存取,不会影响高16位的数据。
  这些低16位寄存器分别命名为:AX、BX、CX和DX。4个16位寄存器又可分割成8个独立的8位寄存器(AX:AH-AL、BX:BH-BL、CX:CH-CL、DX:DH-DL),每个寄存器都有自己的名称,可独立存取。
  寄存器EAX通常称为累加器,用累加器进行的操作可能更少时间;寄存器EBX称为基地址寄存器,它可用存储器指针来使用;寄存器ECX称为计数寄存器,在循环和字符串操作时,要用它来控制循环次数。

2 变址寄存器

  32位CPU有2个32位通用寄存器ESI和EDI。其低16位对应先前CPU中的SI和DI,对低16位数据的存取,不影响高16位的数据。
  寄存器ESI、EDI、SI和DI称为变址寄存器(Index Register),它们主要用于存放存储单元在段内的偏移量,
用它们可实现多种存储器操作数的寻址方式,为以不同的地址形式访问存储单元提供方便。

  变址寄存器不可分割成8位寄存器。作为通用寄存器,也可存储算术逻辑运算的操作数和运算结果。

3 指针寄存器

  32位cpu有2个32位通用寄存器EBP,ESP。他们主要访问堆栈内存单元,ESP:栈指针寄存器(extended stack pointer),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的栈顶。EBP:基址指针寄存器(extended base pointer),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的底部。

4 标志寄存器

  一、运算结果标志位
  1、进位标志CF(Carry Flag)
  进位标志CF主要用来反映运算是否产生进位或借位。如果运算结果的最高位产生了一个进位或借位,那么,其值为1,否则其值为0。使用该标志位的情况有:多字(字节)数的加减运算,无符号数的大小比较运算,移位操作,字(字节)之间移位,专门改变CF值的指令等。
  2、奇偶标志PF(Parity Flag)
  奇偶标志PF用于反映运算结果中“1”的个数的奇偶性。如果“1”的个数为偶数,则PF的值为1,否则其值为0。
利用PF可进行奇偶校验检查,或产生奇偶校验位。在数据传送过程中,为了提供传送的可靠性,如果采用奇偶校验的方法,就可使用该标志位。

  3、辅助进位标志AF(Auxiliary Carry Flag)
  在发生下列情况时,辅助进位标志AF的值被置为1,否则其值为0。
  (1)、在字操作时,发生低字节向高字节进位或借位时;
  (2)、在字节操作时,发生低4位向高4位进位或借位时。
  4、零标志ZF(Zero Flag)
零标志ZF用来反映运算结果是否为0。如果运算结果为0,则其值为1,否则其值为0。在判断运算结果是否为0时,可使用此标志位。

  5、符号标志SF(Sign Flag)
  符号标志SF用来反映运算结果的符号位,它与运算结果的最高位相同。在微机系统中,有符号数采用码表示法,所以,SF也就反映运算结果的正负号。运算结果为正数时,SF的值为0,否则其值为1。
  6、溢出标志OF(Overflow Flag)
  溢出标志OF用于反映有符号数加减运算所得结果是否溢出。如果运算结果超过当前运算位数所能表示的范围,则称为溢出,OF的值被置为1,否则,OF的值被清为0。
  对以上6个运算结果标志位,在一般编程情况下,标志位CF、ZF、SF和OF的使用频率较高,而标志位PF和AF的使用频率较低。
  二、状态控制标志位
  状态控制标志位是用来控制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的值。
  三、32位标志寄存器增加的标志位
  1、I/O特权标志IOPL(I/O Privilege Level)
  I/O特权标志用两位二进制位来表示,也称为I/O特权级字段。该字段指定了要求执行I/O指令的特权级。如果当前的特权级别在数值上小于等于IOPL的值,那么,该I/O指令可执行,否则将发生一个保护异常。
  2、嵌套任务标志NT(Nested Task)
  嵌套任务标志NT用来控制中断返回指令IRET的执行。具体规定如下:
  (1)、当NT=0,用堆栈中保存的值恢复EFLAGS、CS和EIP,执行常规的中断返回操作;
  (2)、当NT=1,通过任务转换实现中断返回。
  3、重启动标志RF(Restart Flag)
  重启动标志RF用来控制是否接受调试故障。规定:RF=0时,表示“接受”调试故障,否则拒绝之。在成功执行完一条指令后,处理机把RF置为0,当接受到一个非调试故障时,处理机就把它置为1。
  4、虚拟8086方式标志VM(Virtual 8086 Mode)
  如果该标志的值为1,则表示处理机处于虚拟的8086方式下的工作状态,否则,处理机处于一般保护方式下的工作状态。

六 字

  汇编伪指令db定义字节类型变量,一个字节数据占1个字节单元,读完一个,偏移量加1;dword定义字类型变量,一个字数据占2个字节单元,读完一个,偏移量加2;dd定义双字类型变量,一个双字数据占4个字节单元,读完一个,偏移量加4。

七 指令

1 push指令

  对于8086CPU,push指令,为入栈操作指令,可以将寄存器、段寄存器、存储器的内容送入堆栈保存。

push 1 ;push后面是可以直接加数字的,相当于将后面这个数字压入当前栈顶。

2 pop指令

  出栈操作。

pop ebp ;出栈,esp+4,将出栈的值赋给ebp

mov指令

  传送指令 MOV,指令的汇编格式:MOV DST,SRC指令的基本功能:(DST)<-(SRC),将原操作数(字节或字)传送到目的地址。使用时要注意它与MOV指令的区别,MOV指令传送的一般是源操作数中的内容而不是地址。

add指令

  两数相加,格式:ADD A,B //A=A+B;

cmp指令

  cmp是比较指令,cmp的功能相当于减法指令。它不保存结果,只是影响相应的标志位。其他的指令通过识别这些被影响的标志位来得知比较结果。

lea指令

  目标地址传送指令: 将一个近地址指针写入到指定的寄存器。格式:

LEA reg16,mem16

  其中reg16必须是一个16位通用寄存器,mem16必须是一个存储器,执行这个指令后,就将mem16所指的16位偏移地址传送reg16中。
  区别MOV传送指令:MOV传送的是地址所指的内容,而LEA只是地址。

ret指令

  完成两件事:1、pop,出栈,esp+4;2、其出栈内容,即下一行的地址放到PC寄存器中。

rep stos指令

lea     edi,[ebp-0C0h] 
mov     ecx,30h 
mov     eax,0CCCCCCCCh 
rep stos dword ptr es:[edi]

  rep指令的目的是重复其上面的指令.ECX的值是重复的次数,STOS指令的作用是将eax中的值拷贝到ES:EDI指向的地址。

跳转指令

  一、无条件跳转: JMP;
  二、根据 CX、ECX 寄存器的值跳转: JCXZ(CX 为 0 则跳转)、JECXZ(ECX 为 0 则跳转);
  三、根据 EFLAGS 寄存器的标志位跳转, 这个太多了。
  根据标志位跳转的指令:
  JE ;等于则跳转
  JNE ;不等于则跳转
  JZ ;为 0 则跳转
  JNZ ;不为 0 则跳转
  JS ;为负则跳转
  JNS ;不为负则跳转
  JC ;进位则跳转
  JNC ;不进位则跳转
  JO ;溢出则跳转
  JNO ;不溢出则跳转
  JA ;无符号大于则跳转
  JNA ;无符号不大于则跳转
  JAE ;无符号大于等于则跳转
  JNAE ;无符号不大于等于则跳转
  JG ;有符号大于则跳转
  JNG ;有符号不大于则跳转
  JGE ;有符号大于等于则跳转
  JNGE ;有符号不大于等于则跳转
  JB ;无符号小于则跳转
  JNB ;无符号不小于则跳转
  JBE ;无符号小于等于则跳转
  JNBE ;无符号不小于等于则跳转
  JL ;有符号小于则跳转
  JNL ;有符号不小于则跳转
  JLE ;有符号小于等于则跳转
  JNLE ;有符号不小于等于则跳转
  JP ;奇偶位置位则跳转
  JNP ;奇偶位清除则跳转
  JPE ;奇偶位相等则跳转
  JPO ;奇偶位不等则跳转

[]符号

  [ ]表示是间接寻址,bx和[bx]的区别是,前者操作数就是bx中存放的数,后者操作数是以bx中存放的数为地址的单元中的数。

文章链接

  at&T语法格式:http://blog.sina.com.cn/s/blog_51e9c0ab010099ow.html
  X86_64汇编与IA32比较:https://blog.csdn.net/iva_brother/article/details/80463105

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值