C++ 内联汇编试图将 std::string 中的字符复制到寄存器中

C++ inline assembly trying to copy a char from a std::string into a register

我在 C++ 中有一个任务,将文件读入包含数字(无空格)的字符串变量,并且使用内联汇编,程序需要对字符串的数字求和。为此,我想循环直到字符串结尾(NULL),并且每次迭代都将 1 个字符(即 1 个数字)复制到寄存器中,以便我可以在其上使用比较和减法。问题是每次不是将 char 复制到寄存器,而是复制一些随机值。

我正在使用 Visual Studio 进行调试。变量 Y 是字符串,我试图将循环的每次迭代复制当前字符到寄存器 AL.

    // read from txt file
string y;
cout << "\n" << "the text is \n";
ifstream infile;
infile.open("1.txt");
getline(infile, y);
cout << y;
infile.close();

    // inline assembly
_asm
{
    mov edx, 0          // counter
    mov ebx, 0
    mov eax, 0
loop1:  
    movzx AL, y[ebx]
    cmp AL, 0x00
    jz finished
    sub AL, 48          // convert ascii to number, assuming digit
    add edx, eax        // add digit to counter
    add ebx, 1          // move pointer to the next byte
    loop loop1
finished:
    mov i, edx
}

例如假设 Y 是“123”并且它是循环的第一次迭代,EBX 是 0。我希望 y[ebx] 指向值 49 (' 1') 实际上在调试中我看到 y[ebx] 的值为 49。我想将所述值复制到寄存器中,所以当我使用指令时:

movzx AL, y[ebx]

我希望寄存器 AL 更改为 49('1'),但值更改为随机值。例如,上次调试会话更改为 192 ('À')。

ystd::string 对象的控制块。您想要访问其 C 字符串数据。

MSVC 内联 asm 语法非常糟糕,所以没有办法只在寄存器中请求指向它的指针。我认为您必须创建一个新的 C++ 变量,例如 char *ystr = y.c_str();

该 C 变量是一个 指针 ,您需要使用 mov ecx, [ystr] 将其加载到寄存器中。直接访问 ystr 的 object-representation 的字节会得到指针的字节。

此外,您当前的代码使用的是 loop 指令,该指令速度较慢,相当于 dec ecx/jnz。但是您没有初始化 ECX,并且您的循环终止条件基于零终止符,而不是您在第一次迭代之前知道的计数器。 (除非您还向 std::string 询问其长度)。

这里使用 loop 指令的理由为零。像正常人一样在循环底部放一个 test al,al / jnz loop1