assembly - 将 nasm 与 __vectorcall 约定一起使用
问题描述
我刚刚开始使用 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 dissasembly 我已经看到了他们push/pop rdi
,所以我已经添加了。而不是sub/add
to rsp
(这导致了无人区的崩溃),我只是直接减去rsp
.
本文涵盖了流行的调用约定,并提到__vectorcall
类似于__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
解决方案
所以主要问题是使用@@4
字节大小。出于某种原因,它需要@@8
。也许是因为返回值?
另外,我搞砸了 64/32 位调用。这是最终的工作版本:
; float sin_f(float)
global sin_f@@8
section .text
sin_f@@8:
sub rsp, 24 ; red-zone
movss [rsp], xmm0 ; mov float arg onto stack
fld dword [rsp] ; push argument on float stack
fsin ; do sin in radians
fstp dword [rsp] ; pop float stack
movss xmm0, [rsp] ; move back to xmm0
add rsp, 24 ; red-zone
ret
推荐阅读
- c++ - boost::filesystem:path 检测到两个路径共享同一个物理驱动器
- javascript - 选择框选项禁用/启用在 jQuery 中不起作用
- javascript - 当取 5 个大数的根时,在 js 中给出了错误的答案
- c - linux内核恐慌消息在哪里?
- functional-programming - 如何在函数式编程语言中生成具有重复的列表的所有排列?
- reactjs - 无法读取未定义的属性“问题”
- python - 在 Plotly 图例中停用数据时隐藏轴刻度标签
- c++ - 迭代器有默认值吗?
- angular - lamejs 不适用于 angular 8 - 未捕获的 ReferenceError: Lame 未定义
- java - 从 java 返回字符串时,Api 网关“格式错误的 lambda 代理响应”