我刚开始使用NASM,我对
__vectorcall
公约。调用测试函数时(
sinf
,我从被叫方返回一个访问冲突。
; float sin_f(float)
global sin_f@@4
section .text
sin_f@@4:
push rdi
; sub rsp, 16 ; make room for xmm
movss [rsp - 16], xmm0 ; mov float arg onto stack
fld qword [rsp - 16] ; push argument on float stack
fsin ; do sin in radians
fstp qword [rsp - 16] ; pop float stack
movss xmm0, [rsp - 16] ; move back to xmm0
movq rax, xmm0
; add rsp, 16 ; reset stack
pop rdi
ret
我显然没有正确地进行清理,但到目前为止,我所有的尝试都失败了。看着一些MSVC的不安定我见过他们
push/pop rdi
,所以我加了一句。而不是
sub/add
到
rsp
(在无人区内造成撞车)我只是直接退步
相对标准偏差
.
这个
article
包括流行的呼叫约定,并提到
_矢量呼叫
类似于
__fastcall
.但是,使用
ret 4
不会改变任何东西。另外,MSVC本身不会这样做。哦,我也要搬到
rax
只是因为。
对于这些概念的任何帮助都将非常感谢。谢谢!
编辑:错误是
Exception thrown at 0x00007FF6198B2C5A in demo1.exe:
0xC0000005: Access violation reading location 0x00000000B817FA20
调用方反汇编:
; 13 : T sin(T angle) {
$LN3:
movss DWORD PTR [rsp+8], xmm0
push rdi
sub rsp, 48 ; 00000030H
mov rdi, rsp
mov ecx, 12
mov eax, -858993460 ; ccccccccH
rep stosd
; 14 : static_assert(std::is_floating_point_v<T>, "requires floating point");
; 15 : if constexpr (std::is_same_v<float, T>) {
; 16 : return detail::sin_f(angle);
movss xmm0, DWORD PTR angle$[rsp]
call sin_f@@8
; 17 : } else {
; 18 : return detail::sin_d(angle);
; 19 : }
; 20 :
; 26 : }
add rsp, 48 ; 00000030H
pop rdi
ret 0