x64汇编笔记


x64汇编笔记记录

0x0 前言

笔记学习会持续更新

0x1 学习(1)

对32位寄存器的写操作(包括运算结果),对相应的64位寄存器的高32位清0

立即数的使用,优先使用32位扩展,64位立即数指令较少

内存优先使用相对偏移寻址,直接寻址指令较少

0x2 调用约定

__cdecl的特点

__cdecl 是 C Declaration 的缩写,表示 C 和 C++ 默认的函数调用约定。是C/C++和MFCX的默认调用约定。

按从右至左的顺序压参数入栈。
由调用者把参数弹出栈。切记:对于传送参数的内存栈是由调用者来维护的,返回值在EAX中。因此对于像printf这样可变参数的函数必须用这种约定。
编译器在编译的时候对这种调用规则的函数生成修饰名的时候,在输出函数名前加上一个下划线前缀,格式为_function。如函数int add(int a, int b)的修饰名是_add

__stdcall的特点

__stdcall是Standard Call的缩写,是C++的标准调用方式

按从右至左的顺序压参数入栈。
由被调用者把参数弹出栈。切记:函数自己在退出时清空堆栈,返回值在EAX中。
__stdcall调用约定在输出函数名前加上一个下划线前缀,后面加上一个“@”符号和其参数的字节数,格式为_function@number。如函数int sub(int a, int b)的修饰名是_sub@8

__fastcall的特点

__fastcall调用的主要特点就是快,因为它是通过寄存器来传送参数的。

实际上__fastcall用ECX和EDX传送前两个DWORD或更小的参数,剩下的参数仍自右向左压栈传送,被调用的函数在返回前清理传送参数的内存栈。
__fastcall调用约定在输出函数名前加上一个“@”符号,后面也是一个“@”符号和其参数的字节数,格式为@function@number,如double multi(double a, double b)的修饰名是@multi@16。
__fastcall和__stdcall很象,唯一差别就是头两个参数通过寄存器传送。注意通过寄存器传送的两个参数是从左向右的,即第1个参数进ECX,第2个进EDX,其他参数是从右向左的入栈,返回仍然通过EAX

0x3 笔记(2)

x64 只有一种调用约定,__cdecl,另外两种修饰被编译器忽略代码中也不会报错(为了兼容)

调用方分配和清理参数所用的栈空间(外平栈)

前4个参数使用 rcx,rdx,r8,r9 传递

即使是寄存器传参,也要分配参数栈空间

易变寄存器:rax,rcx,rdx,r8,r9,r10,r11

push,pop 指令仅用来保存非易变寄存器,其他栈指针操作显示写寄存器rsp实现

进入call之前rsp满足0x10字节对齐

通常不使用rbp寻址栈内存,所以rsp在函数帧中尽量保持稳定(一次性分配局部变量和参数空间)


文章作者: Blue
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Blue !
评论
  目录