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 ('À')。
y
是 std::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
。
我在 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 ('À')。
y
是 std::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
。