寄存器(Registers)
x86
x86处理器中有8个32位的通用寄存器
– eax-累加器
– ecx-计数寄存器
– edx-数据寄存器
– ebx-基地址寄存器
– esp-堆栈指针
– ebp-基址指针
– esi-源索引寄存器
– edi-目标索引寄存器
– eip-指令寄存器
由于向后兼容原因,其中4个寄存器(eax,ebx,ecx,edx)可以拆分16位和8位寄存器
– AX-EAX的低16位
– AH-AX的高8位
– AL-AX的低8位
– BX-EBX的低16位
– BH-EBX的高8位
– BL-EBX的低8位
ECX和EDX也使用字母(C,D)和后缀(X,H或L)表示16位和8位寄存器。
x64
64位处理器使用前缀“R”扩展上述8个寄存器,RAX,RCX,RDX等。需要注意的是x86平台下的寄存器表示方式仍然可用(eax,ax,al等)。
还引入了8个新的寄存器,r8、r9、r10、r11、r12、r13、r14和r15。这些寄存器也可以分为32位、16位和8位的版本。
– r#=64位
– r#d=低32位
– r#w=低16位
– r#b=8位
不幸的是,这些新的8位扩展寄存器不能够使用像eax中的低16位的高8位
Clobber寄存器(Clobber Registers)
Clobber寄存器是一些可能在函数(如Windows API)中被覆盖修改的寄存器。在汇编代码中不应该使用这些寄存器,容易引发程序不稳定,但是如果明确知道在api函数中那些寄存器会别修改还是可以使用这些寄存器的。
在Win32 API中,EAX、ECX和EDX都Clobber寄存器,在Win64 API中,除了RBP、RBX、RDI、RSI、R12、R13、R14和R15,其他的寄存器都是Clobber寄存器。
RAX和EAX分别用于x64和x86函数的返回值。
调用约定(Calling Convention)
x86
Win32 API一般使用__stdcall调用约定,从右到左向堆栈上传递参数。
如调用函数有两个参数int x和int y的函数foo
foo(int x,int y)
在堆栈上传递为
push y
push x
x64
Win64平台下函数调用约定不同,但与Win32平台下的__fastcall相似,均使用寄存器传参,前四个参数分别使用RCX、RDX、R8和R9传递,其他多余的参数使用堆栈传递。需要注意的是,使用寄存器传参时从右到左传递参数。
如对Windows函数MessageBox的调用声明如下:
int WINAPI MessageBox(
_In_opt_  HWND hWnd,
_In_opt_  LPCTSTR lpText,
_In_opt_  LPCTSTR lpCaption,
_In_      UINT uType
);
在Win64调用预定下,参数为:
r9 = uType
r8 = lpCaption
rdx = lpText
rcx = hWnd
来源:http://www.360zhijia.com/360anquanke/204917.html
(文章今日已有 1 人访问,总访问量 8 ::>_<::)