【问题标题】:C++ inline assembly trying to copy a char from a string into a registerC ++内联汇编试图将字符从字符串复制到寄存器中
【发布时间】:2019-10-11 17:17:52
【问题描述】:

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

我正在使用 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('À')。

【问题讨论】:

  • std::string 是非 pod 类类型。它与 char* (您似乎在您的汇编代码中假设)有很大不同。
  • 我明白了,我想我明白了,谢谢。但是调试器确实显示 y[ebx] value 49 type char,所以我想可能有某种方法可以访问程序集中的字符串的各个字符?
  • “所以我想可能有某种方法可以访问汇编中字符串的各个字符” 只能使用像 c_str()operator[] 这样的函数调用。无论如何,我不明白在这种情况下使用内联汇编的目的。您很少会提供编译器所做的更好的优化。
  • std::string 中的原始数据存储在哪里,由实现定义。堆上可能分配了内存。在某些情况下,打包字节可能用于在内部存储原始数据(对于非常短的原始数据)。但是,std::string::c_str() 提供了一个指向原始数据的可靠指针(以及std::string::size() 它的长度)。这是恕我直言,您应该使用它来访问 ASM 中的数据。
  • 请记住,49 可以代表任何含义。它可能是 char 1 的表示形式,也可能是 (int)49 的最小字节。恕我直言,在内存中某处找到数字 49 并不意味着不知道它的用途。

标签: c++ string assembly char inline-assembly


【解决方案1】:

ystd::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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-25
    • 2022-01-02
    • 1970-01-01
    • 1970-01-01
    • 2014-01-10
    • 2013-04-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多