我用C ++分配了一个文件,将文件读入包含数字(没有空格)的字符串变量,并且使用内联汇编,程序需要对字符串的数字求和。为此,我想循环直到字符串(NULL)的结尾,并且每次迭代都将1个字符(即1位数字)复制到一个寄存器中,以便可以对其进行比较和减法。问题在于,每次不是将char复制到寄存器中,而是复制一些随机值。
我正在使用Visual Studio进行调试。变量Y是字符串,我正在尝试将当前char循环的每次迭代都复制到寄存器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('À')。
答案 0 :(得分:1)
y
是std::string
对象的控制块。您要访问其C字符串数据。
MSVC内联asm语法非常糟糕,因此无法仅在寄存器中请求指向该指针的指针。我认为您必须创建一个新的C ++变量,例如char *ystr = y.c_str();
该C变量是一个指针,您需要将其加载到mov ecx, [ystr]
的寄存器中。直接访问ystr
的对象表示形式的字节将为您提供指针的字节。
此外,您当前的代码正在使用loop
指令,该指令很慢,并且等效于dec ecx/jnz
。但是您没有初始化ECX,并且循环终止条件基于零终止符,而不是您在第一次迭代之前就知道的计数器。 (除非您还询问std::string
的长度)。
在这里使用loop
指令的原因为零。将test al,al / jnz loop1
像普通人一样放在循环的底部。