【问题标题】:C++ inline Assembler help. (error c2400)C++ 内联汇编程序帮助。 (错误 c2400)
【发布时间】:2013-11-26 14:35:25
【问题描述】:

我正在使用 Visual Studio 2010。我编写了一个执行简单二进制搜索算法的程序。我正在尝试将其转换为汇编代码。我使用反汇编程序来获取汇编代码。我正在尝试将其粘贴到 _asm 中。试了很多方法,还是不行。

我试过了

_asm(" . . . .");
_asm(  );
_asm{ }    <--- -Currently going with this way for c++. seems to work well.

在网上看到有人说在每行的末尾加上“\”。这对我不起作用。

这是代码。我会评论错误在哪里。好吧,我现在有13个。有些我不会列出,因为它们与其他错误相同。一旦我修复了一两个,我应该能够修复它们。该函数的原始 c++ 代码也在其中。它已被注释掉。

bool binarySearch(int searchNum,int myArray[],int size){

        _asm{ 
     push        ebp  
     mov         ebp,esp  
     sub         esp,0F0h  
     push        ebx  
     push        esi  
     push        edi  
     lea         edi,[ebp-0F0h]  
     mov         ecx,3Ch 
     mov         eax,0CCCCCCCCh 
     rep stos    dword ptr es:[edi] 
      // 217:   int first=0,last=size-1,middle;
     mov         dword ptr [first],0  
     mov         eax,dword ptr [size]       // ERROR! Error 2   error C2400: inline assembler syntax error in 'second operand'; found ']'
     sub         eax,1  
     mov         dword ptr [last],eax  
      // 218:   bool found = false;
     mov         byte ptr [found],0  

     //  220:   while (first <= last)
     mov         eax,dword ptr [first]
     cmp         eax,dword ptr [last] 
     jg          binarySearch+80h (0B51970h)        //ERROR! Error  4   error C2400: inline assembler syntax error in 'second operand'; found '('   


      // 222:       middle = (first + last)/2;
     mov         eax,dword ptr [first] ;        //  Error   5   error C2400: inline assembler syntax error in 'opcode'; found '('   

     add         eax,dword ptr [last] ;
     cdq  
     sub         eax,edx  
     sar         eax,1  
     mov         dword ptr [middle],eax  

     //  224:       if(searchNum > myArray[middle])
     mov         eax,dword ptr [middle]  
     mov         ecx,dword ptr [myArray]  
     mov         edx,dword ptr [searchNum]  
     cmp         edx,dword ptr [ecx+eax*4]  
     jle         binarySearch+61h (0B51951h)  // Error  8   error C2400: inline assembler syntax error in 'opcode'; found '('   

     //  226:           first = middle +1;
     mov         eax,dword ptr [middle]  
     add         eax,1  
     mov         dword ptr [first],eax  
     jmp         binarySearch+7Eh (0B5196Eh)  

      // 228:       else if (searchNum < myArray[middle])
     mov         eax,dword ptr [middle]  
     mov         ecx,dword ptr [myArray]  
     mov         edx,dword ptr [searchNum]  
     cmp         edx,dword ptr [ecx+eax*4]  
     jge         binarySearch+7Ah (0B5196Ah)  

      // 230:           last = middle -1;
     mov         eax,dword ptr [middle]  
     sub         eax,1  
     mov         dword ptr [last],eax  

      // 232:       else 
     jmp         binarySearch+7Eh (0B5196Eh)    // Error    18  error C2400: inline assembler syntax error in 'second operand'; found '('

      // 233:           return true;
     mov         al,1           // Error    19  error C2400: inline assembler syntax error in 'opcode'; found '('   

     jmp         binarySearch+82h (0B51972h)  

     jmp         binarySearch+32h (0B51922h)    // Error    22  error C2400: inline assembler syntax error in 'opcode'; found '('   

      // 236:   return false;
     xor         al,al  

     pop         edi  
     pop         esi  
     pop         ebx  
     mov         esp,ebp  
     pop         ebp  
     ret  

        };

        /*
        int first=0,last=size-1,middle;
        bool found = false;

        while (first <= last)
        {
            middle = (first + last)/2;

            if(searchNum > myArray[middle])
            {
                first = middle +1;
            }
            else if (searchNum < myArray[middle])
            {
                last = middle -1;
            }
            else 
                return true;
        }

        return false;

        */
    }

【问题讨论】:

  • 您不能只复制生成的程序集并粘贴到内联 asm 块中。首先 - 很可能所有地址都不能在您的代码中使用。
  • 如果你还是要编写一个完整的函数,那么我建议使用 masm 和一个单独的源文件。您甚至不需要摆弄自定义设置,因为在 VS 2008+ 中,您可以创建一个空的 file.asm,然后使用“添加现有项目”将其导入您的项目,构建规则将自动创建。内联汇编器也有一点问题(除非他们改进它)。
  • 对于这么大的东西,我建议编写一个单独的组装单元;不要内联 C 或 C++。
  • 顺便说一句:你不需要反汇编器,你可以让编译器创建一个汇编源文件,这将解决一些你还没有注意到的问题(比如无效的堆栈偏移)你目前的做法。
  • 我为您发布了一个内联版本和一个独立版本,因此您可以看到差异。内联汇编器处理对变量的访问,因此在访问变量时不需要dword ptr[] 部分。在组装中也不是绝对必要的,但也不会导致错误。

标签: c++ visual-studio-2010 assembly x86 inline-assembly


【解决方案1】:

这是您为独立程序集发布的(几乎 1:1)工作代码。

binsearch.cpp

extern "C"
{
    bool BinSearch(int searchNum, int myArray[], int arraySize);
};

// This is the inlined version.
bool BinSearchInline(int searchNum, int myArray[], int arraySize)
{
    int middle;
    int first;
    int last;
    char found;

    _asm
    {
     push        ebx  
     push        esi  
     push        edi  

     mov         first,0  
     mov         eax, arraySize
     sub         eax,1  
     mov         last ,eax  
     mov         found,0

LocalLoop:

     mov         eax, first
     cmp         eax, last
     jg          NotFound

     mov         eax, first

     add         eax, last
     cdq  
     sub         eax,edx  
     sar         eax,1  
     mov         middle,eax  

     mov         eax,middle
     mov         ecx,myArray
     mov         edx,searchNum
     cmp         edx, dword ptr [ecx+eax*4]  
     jle         MaybeLower

     mov         eax, middle
     add         eax,1  
     mov         first, eax  
     jmp         WhileLoop

MaybeLower:
     mov         eax, middle
     mov         ecx, myArray
     mov         edx, searchNum
     cmp         edx,dword ptr [ecx+eax*4]  
     jge         Found

     mov         eax, middle
     sub         eax,1  
     mov         last, eax  

     jmp         WhileLoop

Found:
     mov         al,1
     jmp         Done

WhileLoop:
     jmp         LocalLoop

NotFound:
     xor         al,al  

Done:
     pop         edi  
     pop         esi  
     pop         ebx  
    };
}

int main(int argc, char*arg[])
{
    int testvalues[7];
    for(int i = 0; i < 7; i++)
        testvalues[i] = i;

    bool b = BinSearch(8, testvalues, 7);       // false, value not in array
    b = BinSearch(3, testvalues, 7);        // true, value is in array.

    b = BinSearchInline(8, testvalues, 7);      // false
    b = BinSearchInline(3, testvalues, 7);      // true

    return 0;
}

binsearch.asm

.486
.model flat, C
option casemap :none

.code

BinSearch PROC, searchNum:DWORD, myArray:PTR DWORD, arraySize:DWORD

    LOCAL first:DWORD
    LOCAL middle:DWORD
    LOCAL last:DWORD
    LOCAL found:BYTE

     push        ebx  
     push        esi  
     push        edi  

    ; This block is only for debugging stack errors and should be removed.
    ; lea         edi,[ebp-0F0h]  
    ; mov         ecx,3Ch 
    ; mov         eax,0CCCCCCCCh 
    ; rep stos    dword ptr es:[edi] 

     mov         dword ptr [first],0  
     mov         eax,dword ptr [arraySize]
     sub         eax,1  
     mov         dword ptr [last],eax  
     mov         byte ptr [found],0     ; not even used.

@@Loop:
     mov         eax,dword ptr [first]
     cmp         eax,dword ptr [last] 
     jg          @@NotFound

     mov         eax,dword ptr [first]

     add         eax,dword ptr [last]
     cdq  
     sub         eax,edx  
     sar         eax,1  
     mov         dword ptr [middle],eax  

     mov         eax,dword ptr [middle]  
     mov         ecx,dword ptr [myArray]  
     mov         edx,dword ptr [searchNum]  
     cmp         edx,dword ptr [ecx+eax*4]  
     jle         @@MaybeLower

     mov         eax,dword ptr [middle]  
     add         eax,1  
     mov         dword ptr [first],eax  
     jmp         @@WhileLoop

@@MaybeLower:
     mov         eax,dword ptr [middle]  
     mov         ecx,dword ptr [myArray]  
     mov         edx,dword ptr [searchNum]  
     cmp         edx,dword ptr [ecx+eax*4]  
     jge         @@Found

     mov         eax,dword ptr [middle]  
     sub         eax,1  
     mov         dword ptr [last],eax  

     jmp         @@WhileLoop

@@Found:
     mov         al,1
     jmp         @@Done

@@WhileLoop:
     jmp         @@Loop

@@NotFound:
     xor         al,al  

@@Done:
     pop         edi  
     pop         esi  
     pop         ebx  

     ret  

BinSearch ENDP

END

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-26
    • 1970-01-01
    • 1970-01-01
    • 2015-03-17
    • 1970-01-01
    • 2010-10-23
    相关资源
    最近更新 更多