本文介绍了我如何获得另一个计数器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试比较 C++ 和 MASM 之间的冒泡排序.我让 C++ 正常工作.然而,对于 MASM,我需要在 loopSwap 中使用另一个计数器,但我不知道如何去做.

I'm trying to compare bubble sort between C++ and MASM. I've got the C++ working without issue. With MASM, however, I need another counter in loopSwap, but I don't know how to go about it.

我知道如果我压入一个寄存器,它必须在比较之前,但如果遇到比较跳转,我将无法弹出同一个寄存器.

I know that if I push a register, it would have to be before the comparison but if the comparison jump is met, I wouldn't be able to pop the same register.

感谢任何帮助!

C++ 代码:

#include <iostream>
#include <cmath>
#include <ctime>

using namespace std;

int deepBlueDecend(int* num, int size);
int deepBlueAscend(int* num, int size);
//int setArray(int* num, int size);

extern"C"
{
    int KasparovAscend(int *, int);
    int KasparovDecend(int *, int);
}

int main()
{
    int ascOrDec = 2, size = 0;
    cout << "How big do you want the array to be sorted? ";
    cin >> size;

    int* myArray = 0;
    myArray = new int[size];
    int* asmArray = 0;
    asmArray = new int[size];

    srand((unsigned)time(0));                       // gets actually random numbers somehow
    for (int i = 0; i < size; i++)                  //populates the arrays with random numbers
    {
        myArray[i] = rand();
        asmArray[i] = myArray[i];
    }

    for (int i = 0; i < size; i++) cout << asmArray[i] << " "; //displays asmArray[]
    cout << endl;

    while (ascOrDec < 0 || ascOrDec > 1)            //test if ascending or decending has been chosen
    {
        cout << "Ascending (0) or decending(1)? ";
        cin >> ascOrDec;
        if (ascOrDec == 0 || ascOrDec == 1)
            break;
    }

    cout << endl;
    if (ascOrDec == 0)
    {
        KasparovAscend(asmArray, size);

        for (int i = 0; i < size; i++) cout << asmArray[i] << " "; //to see if anything changed in the assembly sort
        cout << endl;

        clock_t startTime = clock();
        deepBlueAscend(myArray, size);
        clock_t endTime = clock();
        clock_t clockTicksTaken = endTime - startTime;
        double timeInSeconds = clockTicksTaken / (double)CLOCKS_PER_SEC;


        for (int i = 0; i < size; i++) cout << myArray[i] << " "; //to see if anything changed in the C++ sort
        cout << "
Time Taken for c++: " << clockTicksTaken << endl;
    }
    else
    {
        clock_t startTime = clock();
        deepBlueDecend(myArray, size);
        clock_t endTime = clock();
        clock_t clockTicksTaken = endTime - startTime;
        double timeInSeconds = clockTicksTaken / (double)CLOCKS_PER_SEC;
        cout << "
Time Taken for c++: " << clockTicksTaken << endl;
    }

    system("pause");
    return 0;
}

int deepBlueAscend(int* arr, int size)
{
    int i, j, flag = 1;    // set flag to 1 to start first pass
    int temp;             // holding variable

    for (i = 1; (i <= size) && flag; i++)
    {
        flag = 0;
        for (j = 0; j < (size - 1); j++)
        {
            if (arr[j + 1] < arr[j])      // ascending order <
            {
                temp = arr[j];             // swap elements
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
                flag = 1;               // indicates that a swap occurred.
            }
        }
    }
    return 0;
}

int deepBlueDecend(int* arr, int size)
{
    int i, j, flag = 1;    // set flag to 1 to start first pass
    int temp;             // holding variable

    for (i = 1; (i <= size) && flag == 1; i++)
    {
        flag = 0;
        for (j = 0; j < (size - 1); j++)
        {
            if (arr[j + 1] > arr[j])      // decending order  >
            {
                temp = arr[j];             // swap elements
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
                flag = 1;               // indicates that a swap occurred.
            }
        }
    }
    return 0;
}

和 MASM 代码:

.686
.model flat
.code

_help PROC ; named _test because C automaticedxly prepends an underscode, it is needed to interoperate
    push ebp
    mov ebp,esp ; stack pointer to ebp

    mov ebx, [ebp+8] ; address of first array element
    mov ecx, [ebp+12] ; number of elements in array
    mov ebp, ecx
    mov edx, 0
    mov eax, 0
    push edi    ;save this
    push ebx    ;save this

    mov edi, ebx    ;make a copy of first element in array
    add edi, 4      ;move 4 to find second element

    mov edx, [ebx]  ;move first element into edx
    mov eax, [edi]  ;move second element into eax


LoopTraverse:
    dec ecx
    cmp ecx, 0
    je AllDone

                    ;set counter in loopSwap to be 0 when first entered

    LoopSwap:
        inc ebp             ;increment
        cmp ecx, eax        ;compares counter to number of elements
        je LoopTraverse

        cmp edx, eax        ;comparing the two values
        jg NextElements

        push ecx            ;stores eax so it can be used for later
        push edx            ;stores edx so it can be used later

        xchg ebx, edi           ;trade the two elements
        mov ecx, edi
        mov edx, ebx
        xchg [ebp+eax], edx
        xchg [ebp], ecx

        pop edx
        pop ecx

NextElements:
        add edi, 4              ;finds next
        add ebx, 4              ;finds second element
        mov eax, [edi]
        mov edx, [ebx]



allDone:

    mov eax, ebp
    pop edi
    pop edx
    pop ebp;
    ret
_help ENDP

END

推荐答案

  1. 不要使用 ebp 作为变量.
  2. mov ebp,esp 之后执行 sub esp, 4 以在堆栈中为一个循环计数器腾出空间.
  3. [ebp-4] 中解决您的新循环计数器.
  4. 由于不允许将 ebp 用作变量,因此您将需要多一个堆栈变量;所以,而不是 sub esp, 4sub esp, 8 并且你的第二个堆栈变量位于 [ebp-8].
  1. Do not use ebp as a variable.
  2. After mov ebp,esp do sub esp, 4 to make room in the stack for one more loop counter.
  3. Address your new loop counter at [ebp-4].
  4. Since you are not allowed to use ebp as a variable, you are going to need one more stack variable; so, instead of sub esp, 4 do sub esp, 8 and your second stack variable is at [ebp-8].

请参阅 维基教科书 - x86 反汇编/函数和堆栈框架

这篇关于我如何获得另一个计数器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-09 07:34