【问题标题】:How to read and write a double array created on C++ from Inline Assembler?如何从 Inline Assembler 读取和写入在 C++ 上创建的双精度数组?
【发布时间】:2019-12-18 02:31:50
【问题描述】:

我想通过内联汇编器操作在 C++ 上创建的数组,当我尝试使用一维数组时它可以正常工作,但是当我使用多维数组时,我总是得到一个零。

我正在使用 Visual Studio 2019。

#include <iostream>
using namespace std;

int main()
{
    double matrix[2][2] = { {10, 20},{30, 40} };//I always get a Zero
    //double matrix[2] = { 50, 60 };//It works

    double temp = 987;

    _asm {
        mov esi, 0

        finit
        ; fld[matrix]
        fld matrix[esi]
        fstp temp
        fwait
    }

    cout << "temp: " << temp << endl;
    return 0;
}

我应该怎么做才能获得 30?

非常感谢您!

【问题讨论】:

  • 你的数组如果是 8 字节 (QWORD) 的 DOUBLE。您需要使用 QWORD 覆盖加载或fld 尝试将其读取为 4 字节 FLOAT。 fld qword ptr matrix[esi]。如果你想要二维数组的第三个元素,你可以加载值为 16 的 ESI。第一个元素 (DOUBLE) 为 0,第二个元素为 8,第三个元素为 16,第四个元素为 24 等。每个元素为 8 个字节在大小上,您需要传递元素的 BYTE 偏移量。您也可以使用fld qwiord ptr matrix[16] 来获取第三个元素,即值 30.0
  • 谢谢!!,我会用你的解决方案编辑问题。
  • 不,不要用解决方案编辑问题。创建一个实际的答案并将解决方案放在那里。允许并鼓励您为自己的问题写下答案。
  • 现在是 2019 年,你真的需要使用 legacy x87 来兼容 Pentium 4 / AMD K8 之前的 CPU 吗? movsd xmm0, [mem] 更简单、更高效。通常只使用 x87 来利用对 80 位 FP 的硬件支持。
  • 感谢您的评论,我刚从 asm 开始,我试图在阅读一本严肃的书之前解决非常简单的问题。

标签: arrays visual-c++ x86 inline-assembly


【解决方案1】:

按照@michael-petch 评论,解决方案是:

#include <iostream>
using namespace std;

int main()
{
    double matrix[2][2] = { {10, 20},{30, 40} };
    double temp[2][2];
    double val = 5;

    _asm {
        mov esi, 0
        mov ecx, 4
        finit
        for1:
            fld val
            fld qword ptr matrix[esi]
            fadd
            fstp qword ptr temp[esi]
            add esi,8
        loop for1
        fwait
    }

    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 2; j++) {
            cout << temp[i][j]<<" ";
        }
        cout << endl;
    }

    return 0;
}

【讨论】:

  • 你不需要finit,FPU 已经在程序入口初始化。 (除非 MSVC 废话已将内部精度降低为 double 或 float 而不是 80 位总/64 位有效位。)randomascii.wordpress.com/2012/03/21/…。无论如何,val 是一个常量,因此您可以在循环外加载它。这也将避免不平衡 x87 堆栈(您目前使用两个 fld 但在 fstp 中只有一个弹出)。因此,如果计数 > 8,您的循环将失败。您也不需要 fwait;我认为这是自 286 年以来的 NOP。
  • 使用movaps xmm0, xmm1(复制您之前加载的val)会更简单; addsd xmm0, matrix[esi] ; movsd temp[esi], xmm0 - 不用担心不平衡 FP 堆栈。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-13
  • 1970-01-01
  • 1970-01-01
  • 2019-07-13
  • 2011-02-06
相关资源
最近更新 更多