as_callfunc_x64_msvc_asm.asm 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. ;
  2. ; AngelCode Scripting Library
  3. ; Copyright (c) 2003-2011 Andreas Jonsson
  4. ;
  5. ; This software is provided 'as-is', without any express or implied
  6. ; warranty. In no event will the authors be held liable for any
  7. ; damages arising from the use of this software.
  8. ;
  9. ; Permission is granted to anyone to use this software for any
  10. ; purpose, including commercial applications, and to alter it and
  11. ; redistribute it freely, subject to the following restrictions:
  12. ;
  13. ; 1. The origin of this software must not be misrepresented; you
  14. ; must not claim that you wrote the original software. If you use
  15. ; this software in a product, an acknowledgment in the product
  16. ; documentation would be appreciated but is not required.
  17. ;
  18. ; 2. Altered source versions must be plainly marked as such, and
  19. ; must not be misrepresented as being the original software.
  20. ;
  21. ; 3. This notice may not be removed or altered from any source
  22. ; distribution.
  23. ;
  24. ; The original version of this library can be located at:
  25. ; http://www.angelcode.com/angelscript/
  26. ;
  27. ; Andreas Jonsson
  28. ; [email protected]
  29. ;
  30. .code
  31. PUBLIC CallX64
  32. ; asQWORD CallX64(const asQWORD *args, const asQWORD *floatArgs, int paramSize, asQWORD func)
  33. CallX64 PROC FRAME
  34. ; PROLOG
  35. ; We must save preserved registers that are used
  36. ; TODO: No need to save unused registers
  37. push rbp
  38. .pushreg rbp
  39. push rsi
  40. .pushreg rsi
  41. push r11
  42. .pushreg r11
  43. push rdi
  44. .pushreg rdi
  45. push r12
  46. .pushreg r12
  47. push r13
  48. .pushreg r13
  49. push r14
  50. .pushreg r14
  51. push r15
  52. .pushreg r15
  53. push rbx
  54. .pushreg rbx
  55. sub rsp, 050h
  56. .allocstack 050h
  57. mov rbp, rsp
  58. .setframe rbp, 0
  59. .endprolog
  60. ; Move function param to non-scratch register
  61. mov r14, r9 ; r14 = function
  62. ; Allocate space on the stack for the arguments
  63. ; Make room for at least 4 arguments even if there are less. When
  64. ; the compiler does optimizations for speed it may use these for
  65. ; temporary storage.
  66. mov rdi, r8
  67. add rdi, 32
  68. ; Make sure the stack pointer is 16byte aligned so the
  69. ; whole program optimizations will work properly
  70. ; TODO: optimize: Can this be optimized with fewer instructions?
  71. mov rsi, rsp
  72. sub rsi, rdi
  73. and rsi, 8h
  74. add rdi, rsi
  75. sub rsp, rdi
  76. ; Jump straight to calling the function if no parameters
  77. cmp r8d, 0 ; Compare paramSize with 0
  78. je callfunc ; Jump to call funtion if (paramSize == 0)
  79. ; Move params to non-scratch registers
  80. mov rsi, rcx ; rsi = pArgs
  81. mov r11, rdx ; r11 = pFloatArgs (can be NULL)
  82. mov r12d, r8d ; r12 = paramSize
  83. ; Copy arguments from script stack to application stack
  84. ; Order is (first to last):
  85. ; rcx, rdx, r8, r9 & everything else goes on stack
  86. mov rcx, qword ptr [rsi]
  87. mov rdx, qword ptr [rsi + 8]
  88. mov r8, qword ptr [rsi + 16]
  89. mov r9, qword ptr [rsi + 24]
  90. ; Negate the 4 params from the size to be copied
  91. sub r12d, 32
  92. js copyfloat ; Jump if negative result
  93. jz copyfloat ; Jump if zero result
  94. ; Now copy all remaining params onto stack allowing space for first four
  95. ; params to be flushed back to the stack if required by the callee.
  96. add rsi, 32 ; Position input pointer 4 args ahead
  97. mov r13, rsp ; Put the stack pointer into r13
  98. add r13, 32 ; Leave space for first 4 args on stack
  99. copyoverflow:
  100. mov r15, qword ptr [rsi] ; Read param from source stack into r15
  101. mov qword ptr [r13], r15 ; Copy param to real stack
  102. add r13, 8 ; Move virtual stack pointer
  103. add rsi, 8 ; Move source stack pointer
  104. sub r12d, 8 ; Decrement remaining count
  105. jnz copyoverflow ; Continue if more params
  106. copyfloat:
  107. ; Any floating point params?
  108. cmp r11, 0
  109. je callfunc
  110. movlpd xmm0, qword ptr [r11]
  111. movlpd xmm1, qword ptr [r11 + 8]
  112. movlpd xmm2, qword ptr [r11 + 16]
  113. movlpd xmm3, qword ptr [r11 + 24]
  114. callfunc:
  115. ; Call function
  116. call r14
  117. ; Restore the stack
  118. mov rsp, rbp
  119. ; EPILOG: Restore stack & preserved registers
  120. add rsp, 050h
  121. pop rbx
  122. pop r15
  123. pop r14
  124. pop r13
  125. pop r12
  126. pop rdi
  127. pop r11
  128. pop rsi
  129. pop rbp
  130. ; return value in RAX
  131. ret
  132. CallX64 ENDP
  133. PUBLIC GetReturnedFloat
  134. ; asDWORD GetReturnedFloat()
  135. GetReturnedFloat PROC FRAME
  136. ; PROLOG: Store registers and allocate stack space
  137. sub rsp, 8 ; We'll need 4 bytes for temporary storage (8 bytes with alignment)
  138. .allocstack 8
  139. .endprolog
  140. ; Move the float value from the XMM0 register to RAX register
  141. movss dword ptr [rsp], xmm0
  142. mov eax, dword ptr [rsp]
  143. ; EPILOG: Clean up
  144. add rsp, 8
  145. ret
  146. GetReturnedFloat ENDP
  147. PUBLIC GetReturnedDouble
  148. ; asDWORD GetReturnedDouble()
  149. GetReturnedDouble PROC FRAME
  150. ; PROLOG: Store registers and allocate stack space
  151. sub rsp, 8 ; We'll need 8 bytes for temporary storage
  152. .allocstack 8
  153. .endprolog
  154. ; Move the double value from the XMM0 register to the RAX register
  155. movlpd qword ptr [rsp], xmm0
  156. mov rax, qword ptr [rsp]
  157. ; EPILOG: Clean up
  158. add rsp, 8
  159. ret
  160. GetReturnedDouble ENDP
  161. END