我在计算机体系结构和汇编语言类中有一个作业,我收到了以下C++代码,并被要求将其中的一部分转换为MASM汇编代码:
#include <iostream>
#include <ctime>
using namespace std;
#define MAXIMUM 1000000
int Factors[MAXIMUM];
int properFactors(int, int[], int&);
int main()
{
int q;
int numFactors;
int pairCount = 0;
clock_t startClock = clock();
for (int p = 1; p <= MAXIMUM; p++)
{
q = properFactors(p, Factors, numFactors);
if (q > p)
{
if (properFactors(q, Factors, numFactors) == p)
{
cout << "Amicable Pair: " << p << ", " << q;
cout << "(" << q << " has " << numFactors << " factors : ";
cout << Factors[0];
for (int i = 1; i < numFactors; i++)
cout << ", " << Factors[i];
cout << ")" << endl;
pairCount++;
}
}
}
double totalTime = (double)(clock() - startClock) / CLOCKS_PER_SEC;
cout << "Number of amicable pairs found = " << pairCount << endl;
cout << "Time = " << totalTime << " seconds" << endl;
}
int properFactors(int n, int factors[], int& numFactors)
{
int i, k, sum, factor2;
i = 1;
k = 2;
sum = 1;
factors[0] = 1;
while (k * k <= n) {
if (n % k == 0) {
sum = sum + k;
factors[i] = k;
i++;
factor2 = n / k;
if (factor2 != k) {
sum = sum + factor2;
factors[i] = factor2;
i++;
}
}
k++;
}
numFactors = i;
return sum;
}
我必须转换为组件的部分是来自适当因子函数的以下部分:
i = 1;
k = 2;
sum = 1;
factors[0] = 1;
while (k * k <= n) {
if (n % k == 0) {
sum = sum + k;
factors[i] = k;
i++;
factor2 = n / k;
if (factor2 != k) {
sum = sum + factor2;
factors[i] = factor2;
i++;
}
}
k++;
}
我已经编写了以下汇编代码来替换上面的代码部分,但由于某种原因,每当我试图运行该问题时,程序都不会输出任何内容:
__asm {
mov eax, 1 ; i = 1;
mov i, eax
mov eax, i
mov ebx, 2 ; k = 2;
mov k, ebx
mov ebx, 1 ; sum = 1;
mov sum, ebx
mov ebx, factors
mov esi, 0
mov [ebx + 4 * esi], 1 ; factors[0] = 1;
while_1: ; while (k * k <= n) {
mov ecx, k
imul ecx, k
cmp ecx, n
jle while_1_begin
jmp while_1_end
while_1_begin:
if_1: ; if (n % k == 0) {
mov edx, n
cdq
idiv k
cmp edx, 0
je if_1_begin
jmp if_1_end
if_1_begin:
mov esi, sum ; sum = sum + k;
add esi, k
mov sum, esi
mov esi, k
mov [ebx+4*eax], esi ; factors[i] = k;
inc i ; i++;
mov eax, i
mov esi, n
cdq
idiv k
mov factor2, esi ; factor2 = n / k;
mov esi, k
if_2: ; if (factor2 != k) {
cmp factor2, esi
jne if_2_begin
jmp if_2_end
if_2_begin:
mov edi, sum ; sum = sum + factor2;
add edi, factor2
mov sum, edi
mov edi, factor2
mov eax, i
mov [ebx+4*eax], edi ; factors[i] = factor2;
inc i ; i++;
mov eax, i
jmp if_2_end
if_2_end: ; }
jmp if_1_end
if_1_end: ; }
inc k ; k++;
jmp while_1
while_1_end: ; }
mov i, eax
}
有人能帮我弄清楚为什么我的程序不能正常工作吗?
您似乎期望除法idiv
对EDX:ESI
进行运算,将其商留在ESI
中,余数留在EDX
中。这是错误的除法idiv
将EDX:EAX
除以其操作数,商留在EAX
中,余数留在EDX
中。
在下面的重写中,我在应用更改的地方使用了大写字母。把我写的和你写的比较一下,试着理解为什么会发生变化。
我做了一些更正和优化,比如删除多余的指令。请查看使用相反条件后如何轻松减少条件跳转的次数。
__asm {
mov EAX, 2 ; k = 2;
mov k, EAX
DEC EAX ; i = 1;
mov i, eax
mov sum, EAX ; sum = 1;
mov ebx, factors
mov [EBX], EAX ; factors[0] = 1;
while_1: ; while (k * k <= n) {
mov ecx, k
imul ecx, ECX
cmp ecx, n
JG while_1_end
if_1: ; if (n % k == 0) {
mov EAX, n
cdq
idiv k
TEST EDX, EDX
JNZ if_1_end
mov esi, sum ; sum = sum + k;
add esi, k
mov sum, esi
MOV EAX, i
mov esi, k
mov [ebx+4*eax], esi ; factors[i] = k;
inc i ; i++;
mov EAX, n
cdq
idiv k
mov factor2, EAX ; factor2 = n / k;
if_2: ; if (factor2 != k) {
cmp EAX, K
JE if_2_end
ADD sum, EAX ; sum = sum + factor2;
mov ESI, i ; factors[i] = factor2;
mov [ebx+4*ESI], EAX
inc i ; i++;
if_2_end: ; }
if_1_end: ; }
inc k ; k++;
jmp while_1
while_1_end: ; }
mov i, eax
}