Windows X64汇编入门(1)

讲重点:
1.MS的64位编译器使用fastcall约定调用,即最前面的四个参数,rcx,rdx,r8,r9,(不是参数是寄存器,函数的是参数)传递四个最开头的参数,从左至右依次排,多余4个参数,四个寄存器显然没法放,就要放到栈中,依然从左至右,栈地址增加排列,前4个参数的栈空间保留。(fastcall在各个编译器设定不同,这个是ml64)
2.呼叫函数前必须申请栈,这个特性在Win32中还不太明显,因为stdcall也好还是cdecl也好,呼叫函数前都会push参数,没有参数就不push,push指令在更改esp相当于申请栈空间,而64位的fastcall则不同小于5个参数的话,不用push,但是仍然保留20H的栈空间,这个空间可能会在调用的函数会使用,若不保留此空间,可能会引发访问内存越权,其实这个类似push。
所以写个Helloworld时,直接将四个参数弄到rcx,rdx,r8,r9即可:
代码:
extrn MessageBoxA: proc
sub rsp,28H
xor rcx,rcx
lea rdx,szTxt ;; 字符
lea r8,szTxt   ;; 字符
mov r9,40H
call MessageBoxA
add rsp,28H
3.64位寄存器,都是宽度发生变化,原来的32位的eax等,16位的ax,al等都可访问,添加8个新的寄存器r8到r15,这8个也是普通的寄存器,若访问这些寄存器的地位,如32位的话,即r8d,d就是double-word的意思,16位即r8w,8位即r8b,分别w指word,b指byte。
看了一下64的浮点寄存器组要复杂了一些。
4.在Win32程序中通常须保存的寄存器有ebx,ebp,esi,edi,64位中分别拓展成rbx,rbp,rdi,rsi,除此之外还有r12,r13,r14,r15。
5.64位还有个重要特性,可以访问rip,在32位中这个做法是禁止的,比如:
代码:
mov al,BYTE PTR [rip]
nop
在64位中就可或取rip的下个指令的第一个数值90H。
MASM不支持这种写法,不过有的编译器可以,MASM只能通过间接寄存器间接寻址。

我写的一个64位窗口程序(代码): 

你可能感兴趣的:(Windows X64汇编入门(1))