2.2.1 MSVC-x86-64

让我们来试试64-bit的MSVC:

  1. $SG2989 DB 'hello, world', 00H
  2. main PROC
  3. sub rsp, 40
  4. lea rcx, OFFSET FLAT:$SG2923
  5. call printf
  6. xor eax, eax
  7. add rsp, 40
  8. ret 0
  9. main ENDP

在x86-64里,所有被扩展到64位的寄存器都有R-前缀。并且尽量不用栈来传递函数的参数了,大量使用寄存器来传递参数,非常类似于fastcall。

在win64里,RCX,RDX,R8,R9寄存器被用来传递函数参数,如果还有更多就使用栈,在这里我们可以看到printf()函数的参数没用通过栈来传递,而是使用了rcx。 让我们针对64位来看,作为64位寄存器会有R-前缀,并且这些寄存器向下兼容,32位的部分使用E-前缀。

如下图所示,这是RAX/EAX/AX/AL在64位x86兼容cpu里的情况 2.2.1 MSVC-x86-64 - 图1

在main()函数会返回一个int类型的值,在64位的程序里为了兼容和移植性,还是用32位的,所以可以看到EAX(寄存器的低32位部分)在函数最后替代RAX被清空成0。