x64汇编要点总结

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012581760/article/details/86538003
	int a = 1;                 mov dword ptr [ebp - 8], 1
    int b = 2;                 mov dword ptr [ebp - 14h],2
  	int c = a + b;          mov eax, dword ptr [ebp - 8]
                                 add eax, dword ptr [ebp - 14h]
                                 mov dword ptr [ebp - 20h], eax
   
   汇编语言:8086汇编(16bit),x86汇编(32bit),x64汇编(64)bit (汇编语言不区分大小写)
   AT&T汇编 vs Intel汇编
   
   寄存器命名   %eax                               eax                Intel的不带%
   操作数顺序   movl %eax,%edx      mov edx, eax        将eax的值赋值给edx
   常数\立即数  movl $3,%eax           mov eax,3             将3赋值给eax
   
   jmp指令    jmp *%edx          jmp edx
               jmp *0x4001002     jmp 0x4001002       在AT&T的jmp地址前面要加星号*
                  jmp *(%eax)        jmp [eax]
   
   操作数长度  movl %eax, %edx    mov edx, eax
                       movb $0x10, %al    mov al, 0x10
                     leaw 0x10(%dx),%ax  lea ax, [dx + 0x10]
   // b=byte(8-bit)
      s=short(16-bit integer or 32-bit floating point)
      w=word(16-bit)
      l=long(32-bit integer or 64-bit floating point)
      q=quad(64-bit)
      t=ten bytes(80-bit floating point)
   x64汇编 - 寄存器(学汇编是先学寄存器再学汇编指令)
   常用寄存器(寄存器的大小跟CPU的位数挂钩,如果是64位的证明寄存器是64位的,那么一个寄存器是占8个字节)
   RAX
   RBX
   RCX
   RDX
   RBP
   RSI
   RDI
   RSP
   R8
   R9
   R10
   R11
   R12
   R13
   R14
   R15
 
   x86是(32bit),x64汇编兼容x86
   EAX
   EBX
   ECX
   
   |63..32|31..16|15-8|7-0|  63位
                		 |AH. |AL.|
                		|AX.........| 64位中低2个字节16位变为AX寄存器(64位兼容16位)
          	 |EAX..................| 64位中低4个字节32位变为EAX(x64兼容x8664位兼32)
  |RAX.............................|
   
   一般的规律
   R开头的寄存器是64bit,占8个字节
   E开头的寄存器是32bit,占4个字节
   
   
   x64汇编要点总结( 权威参考:Intel白皮书  链接地址:https://software.intel.com/en-us/articles/intel-sdm)
   mov dest src   // 将src的内容赋值给dest,类似于dest=src
   [地址值] // 中括号里面的东西都是地址值,都是内存地址
   word是2字节
   dword是4字节(double word)
   qword是8字节(quad word)
   mov dword ptr [ebp-8],1  // 将1放到内存地址值为ebp-8这个地址对应的存储空间内容中,1的存储要覆盖掉4个字节(小端模式)
   call 函数地址 // 调用函数
   mov eax, [01332132H] // 将地址值对应的存储空间的内容取出四个字节的数据放到寄存器eax中,
   lea dest, [地址值]  // 直接将地址值赋值给dest,类似于dest = 地址值
   lea eax, [01332132H] 相等于 mov eax, 01332132H 伪代码eax = 01332132H
   ret // 函数返回
   xor op1, op2 // 异或,将op1和op2异或的结果赋值给op1,类似于op1 = op1 ^ op2
   add op1, op2 // 类似于op1 = op1 + op2
   sub op1, op2 // 类似于op1 = op1 - op2
   inc op  // 自增,类似于op = op + 1
   dec op  // 自减,类似于op = op - 1
   一个变量的地址值是他最小字节的
   jmp 内存地址 // 跳转到某个内存地址去执行代码,以j开头的一般都是跳转,大多数是带条件的跳转,一般跟test,cmp等指令配合使用
   cmp eax, ebx
   jz 01332132H 比较两个寄存器的值,如果相等,就跳转,如果d比较结果不相等,就不跳
  
   // jcc表示带条件的跳转指令jmp condition command
   JE,JZ 结果为零则跳转(相等时跳转) ZF=1
   JNE,JNZ 结果不为零则跳转(不相等时跳转) ZF=0
   JS 结果为负则跳转 S代表sign(有符号\有负号)       SF=1
   JNS 结果为非负则跳转                SF=0
   JP,JPE  结果中1的个数为偶数则跳转 parity even     PF=1
   JNP,JPO 结果中1的个数为奇数则跳转 parity odd     PF=0
   JO   结果溢出了则跳转  overflow          OF=1
   JNO  结果没有溢出则跳转 not overflow          OF=0
   JB,JNAE  小于则跳转(无符号数) (below,not above equal <)  CF=1
   JNB,JAE  大于等于则跳转(无符号数) (not below, above equal >=) CF=0
   JBE,JNA  小于等于则跳转(无符号数) (below equal, not above <=) CF=1 or ZF=1
   JNBE,JA  大于则跳转(无符号数) (not below equal, above >) CF=0 and ZF=0
   JL,JNGE  小于则跳转(有符号数)(little, not great equal <) SF!=OF
   JNL,JGE  大于等于则跳转(有符号数)(not little,great equal >=) SF=OF
   JLE,JNG  小于等于则跳转(有符号数) (little equal, not great <=) ZF=1 or SF!= OF
   JNLE,JG  大于则跳转(有符号数) (not little equal, great >) ZF=0 and SF=OF
   
   
   硬盘 (运行软件)装载到 内存 读(写) CPU(读取内存中的代码,修改将某个变量的值改掉写内存,控制其他硬件设备(显示器,音响,话筒,其他设备))
   
   
   CPU (寄存器,运算器,控制器) 比如做加法操作,先将内存中的某个值放到寄存器中,再通过运算器进行加或者减另一个值将结果再放到寄存器中,运算完再将结果送回到内存中,因为寄存器就在CPU,所以CPU操作寄存器速度比操作内存的速度快
   
具体事例如下:
   执行一个函数的时候,编译器首先会估算一下这个函数中大概要用到多少空间,编译代码的时候就会知道,函数中用到了几个变量,这个函数应该分配多少空间,执行函数的时候,就已经分配好一段连续的内存的栈空间了(给函数分配的内存空间一般叫做栈空间,栈内存空间的特点是由CPU自动分配和回收的达到栈平衡)hex16进制,一个变量的地址值是它所有字节中最小字节的地址值.
   
   int a = 1;              mov dword ptr [ebp - 8], 1      //将1放入a的存储空间占4个字节
   int b = 2;              mov dword ptr [ebp - 14h],2     //将2放入b的存储空间占4个字节
   int c = a + b;          mov eax, dword ptr [ebp - 8]    //将a中取出的1放入寄存器eax中
                           add eax, dword ptr [ebp - 14h]   // 将a和b的值通过寄存器相加给了eax
                           mov dword ptr [ebp - 20h], eax   // 将eax寄存器中的值a+b的结果给了c记(ebp - 20h)的内存存储空间
    

猜你喜欢

转载自blog.csdn.net/u012581760/article/details/86538003
今日推荐