 <p>There is no such thing as "Abi64". Since you tagged the question MASM, we can guess that you're using the Windows platform, and clearly the "64" means that this is 64-bit code, so that does narrow down the possibilities tremendously. However, there are still two common calling conventions for 64-bit code on Windows. One of them is <code>__vectorcall</code> and the other is the Microsoft x64 calling convention (the one that was originally invented to make all other calling conventions obsolete but&hellip;didn't).</p> <p>Since the Microsoft x64 calling convention is the most common, and in this particular case, using <code>__vectorcall</code> wouldn't change anything, I'll assume it's the one that you're using. And then the code required becomes absolutely trivial. All you need to do is jump from <code>f1</code> to <code>f2</code>, since the stack will be set up identically. <code>f1</code>'s first two parameters are the two parameters that should be passed to <code>f2</code>, and the return value of <code>f2</code> is the return value of <code>f1</code>. Therefore:</p> <pre><code>f1: rex_jmp r8 ; third parameter (pointer to f2) is passed in r8 </code></pre> <p>This is not only trivial to write, but it is the most optimal implementation for both size and speed.<br> You can even modify the <code>v1</code> or <code>v2</code> parameters beforehand if you want, e.g.:</p> <pre><code>f1: inc ecx ; increment v1 (passed in ecx) ; multiply v2 (xmm1) by v1 (ecx) movd xmm0, ecx cvtdq2ps xmm0, xmm0 mulss xmm1, xmm0 rex_jmp r8 ; third parameter (pointer to f2) is passed in r8 </code></pre> <p>In case you wanted to do something more complicated, here's how it would work:</p> <pre><code>f1: sub rsp, 40 ; allocate the required space on the stack call r8 ; call f2 through the pointer, passed in r8 add rsp, 40 ; clean up the stack ret </code></pre> <p>Note that you do not need the prologue/epilogue code that you've shown in the question, though it won't hurt anything if you choose to include it.</p> <p>However, the shuffling of parameters that you were doing in the example code shown in the question is <em>wrong</em>! In the Microsoft x64 calling convention, the first up-to-four integer arguments are passed in registers, from left to right, in RCX, RDX, R8, and R9. All other integer arguments are passed on the stack. The first up-to-four floating-point values are also passed in registers, from left to right, in XMM0, XMM1, XMM2, and XMM3. The rest are passed on the stack, along with structs too large for registers.</p> <p>The weird thing, though, is that the slots are "fixed", so only 4 total register args can be used, even when you have a mix of integer and fp args. Thus:</p> <pre><code>╔═══════════╦══════════════════════════╗ ║ ║ TYPE ║ ║ PARAMETER ╠═════════╦════════════════╣ ║ ║ Integer ║ Floating-Point ║ ╠═══════════╬═════════╬════════════════╣ ║ First ║ RCX ║ XMM0 ║ ╠═══════════╬═════════╬════════════════╣ ║ Second ║ RDX ║ XMM1 ║ ╠═══════════╬═════════╬════════════════╣ ║ Third ║ R8 ║ XMM2 ║ ╠═══════════╬═════════╬════════════════╣ ║ Fourth ║ R9 ║ XMM3 ║ ╠═══════════╬═════════╩════════════════╣ ║ (rest) ║ on stack ║ ╚═══════════╩══════════════════════════╝ </code></pre> <p>It doesn't matter that the second parameter is the first floating-point value that is being passed. It doesn't go in XMM0 because it's the first floating-point value, it goes in XMM1 because it's the second parameter and therefore in the second "slot". (This is different from <a href="https://en.wikipedia.org/wiki/X86_calling_conventions#System_V_AMD64_ABI" rel="nofollow noreferrer">the x86-64 System V ABI</a>, where the first 6 integer args go in registers, whether or not there are FP args).</p> <p>More detailed documentation on Windows parameter passing is available <a href="https://msdn.microsoft.com/en-us/library/zthk2dkh.aspx" rel="nofollow noreferrer">here</a>, including examples.</p>