问题
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.
Any help is appreciated!
C++ Code:
#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 << "\nTime 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 << "\nTime 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;
}
and MASM code:
.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:
- Do not use
ebp
as a variable. - After
mov ebp,esp
dosub esp, 4
to make room in the stack for one more loop counter. - Address your new loop counter at
[ebp-4]
. - Since you are not allowed to use
ebp
as a variable, you are going to need one more stack variable; so, instead ofsub esp, 4
dosub esp, 8
and your second stack variable is at[ebp-8]
.
See Wikibooks - x86 Disassembly/Functions and Stack Frames
来源:https://stackoverflow.com/questions/34146282/how-do-i-get-another-counter