有没有办法防止MASM更改指令?

问题描述

我正在编写一个C ++程序,并决定由于使用进位标志,因此在x86汇编中编写特定功能会更有效。在反汇编中,我注意到某些指令已更改,导致我的程序引发异常:“访问冲突读取位置”。为什么更改说明,如何防止这种情况?

这是我的代码的片段:

variable "build_name" {
  default = ["test3","new_build"]
}

反汇编程序显示如下:

Future<bool> checkIfUsernameExistsExcludingCurrentUid(
      // Todo NOT DONE
      String username,String uid) async {
    print("searching db for: $username EXCLUDING SELF");
    bool exists = true;

    QuerySnapshot result = await _firestore
        .collection(USERS_COLLECTION)
        .where(
          "username",isEqualTo: username,)
        .getDocuments();

    List _documents = result.documents;
    _documents.forEach((element) {
      if (element['uid'] == uid) {
        exists = false;
      } else {
        return true;
      }
    });

    return exists;
  }

解决方法

您在16位模式下进行了组装,而在32位模式下进行了反汇编,因此一切都与应有的相反。 MASM并不是“更改”指令,只是按照您告诉它的组装方式组装它们。

例如在16位模式下,[ECX]需要一个67地址大小覆盖前缀才能对32位寻址模式进行编码。在32位模式下解码时,该前缀会将其覆盖为16位。 (并且该位模式意味着[bx+di]; 16位寻址模式不能使用SIB字节,因此所有不同的寄存器组合都打包到ModRM字节中。[cx]是不可编码的。)


此外,如果您认为xor + mov是将DH零扩展到EBX的最有效方法,请查看movzx。在现代CPU上,这效率更高。 (请参见https://agner.org/optimize/https://uops.info/)。

通常,您要避免编写像AH这样的高8位寄存器; Haswell / Skylake在读取完整寄存器时会受到合并处罚,而AMD CPU具有虚假的依赖关系。在使用之前,请仔细阅读Why doesn't GCC use partial registers?上的信息和链接。