当 asm 写入/读取数据距离堆栈指针太远时,Valgrind 报告错误

问题描述 投票:0回答:0

美好的一天!

我正在使用 Xbyak 在 C++ 中编写 JIT asm 生成。

问题出现在序言和结语中。 我在序言中做的最后一件事是将 Xmms 值写入堆栈。在此之后我不使用堆栈指针直到结语所以我不需要更新堆栈指针。

旧代码是这样的:

# prologue
push( regNumSteps );
push( retTemp );
for( int i = 6; i <= 15; i++ ) {
    vmovaps( ptr[rsp - 16 - ( i - 6 ) * 16], Xmm( i ) );
}

# epilogue
for( int i = 15; i >= 6; i-- ) {
    vmovaps( Xmm( i ), ptr[rsp - 16  - ( i - 6 ) * 16] );
}
pop( retTemp );
pop( regNumSteps );
leave();

这段代码运行良好。但是在 valgrind 下它会导致

  • invalid write of size 8
    在序言中存储 Xmm14 和 Xmm15 时(为什么是 8?Xmms 是 16)
  • invalid read of size 16
    在尾声中加载 Xmm15 和 Xmm14 时

我的猜测是可能是 valgrind 不喜欢在不正确移动 rsp 的情况下使用堆栈?.

之后我将序言和结语中的循环重写如下:

// prologue
for( int i = 6; i <= 15; i++ ) {
    sub( rsp, 16 ); // keep rsp up-to-date
    vmovaps( ptr[rsp], Xmm( i ) );
}
// epilogue
for( int i = 15; i >= 6; i-- ) {
    vmovaps( Xmm( i ), ptr[rsp] );
    add( rsp, 16 ); // keep rsp up-to-date
}

它通过了valgrind!

问题是为什么?我的猜测是正确的还是巧合?

我查看了 valgrind 的选项,但找不到与此相关的任何内容。谷歌搜索也没有帮助......

c++ assembly valgrind sse jit
© www.soinside.com 2019 - 2024. All rights reserved.