-1

我的程序是用 C++ 编写的,其中嵌入了一些 x86 汇编语言。我有 2 个必须经过的汇编语言嵌套 for 循环。然而,当我编译我的程序时,我得到了一个无限循环。C++ 中的等效程序如下所示:

#include<iostream>
using namespace std;
int main()
{
    int a[4] = {3,6,4,7};

    for(int k = 0 ; k < 4;k++)
    {
        for(int l = 0 ; l < a[k];l++)
        {
            cout<<'*';
        }
        cout<<endl;
    }

    system("pause");
    return 0;
}

 /*

  *** 
  ******
  ****
  *******
  Press any key to continue . . .
  */

这是同样的事情,但通过混合组装完成。

#include<iostream>
using namespace std;
void output(); //function for making an '*'
void makeSpace(); //function for making a space

int main()
{
    int a[4]={3,6,4,7};

    int counter = 0; //counter that will be used for first forloop
    int counter2 = 0; // counter to be used for second forloop

_asm{

    mov ebx,0 // this is to move from element 0,1,2,3,4, through the array
    mov ecx,0 // ecx will get the data from the array, only to be used as a
              // counter in forloop2 though.

     for1:

    cmp counter,4 //begins for firloop

    je starts 
    mov ecx,[a+ebx] // move the 0th element from array to ecx
    add ebx,4// ebx = ebx+4, I'm doing this to advance the array position (int)
    inc counter// increment counter by one

      for2:
    cmp counter2,ecx //begin forloop2, 
    je starts2
    call output
    inc counter2 //increment counter2 by one

    jmp for2 
      starts2:

    call makeSpace
    jmp for1
      starts:
}

    return 0;
}

void output()
{
    cout<<'*';
    }

void makeSpace()
{
    cout<<endl;
}

为什么这会导致无限循环?

4

2 回答 2

2

您至少需要解决两件事:

  • 当您output()只调用以下寄存器时,保证不会被丢弃:

    • edi, esi,ebxebp

    特别是,您正在使用ecx,该功能被允许丢弃。

  • 您永远不会重置counter2为 0,因此内部循环不等同于您的 C 代码。

于 2012-09-21T17:51:34.243 回答
0

我相信这里的答案是,在调用函数OutputMakeSpace. 标准函数头不保证代码中使用的ecxorebx寄存器的任何内容。asm

于 2012-09-21T17:52:53.310 回答