如何求一个数的因数?

问题描述 投票:0回答:1

给你一个非负整数n。在 [2, n-1] 范围内求出这个数的除数个数。
输入:不超过1000的整数非负数n。
输出:整数非负数

我试了一下代码,但我不能总是得到正确的结果。

%include"io.inc"
section .text
global CMAIN
CMAIN:
    ;write your code here
    GET_UDEC 4, eax
    mov ebx, 2
    mov ecx, 0
 cycle:
    cmp eax, ebx
    jbe end;
    xor edx, edx
    div ebx
    mul eax, ebx
    inc ebx
    cmp edx, 0
    jne cycle;
    inc ecx;
    jmp cycle;
 end:
    PRINT_UDEC 4, ecx
    NEWLINE
    
    xor eax, eax
    ret

我的代码有问题吗?请帮我指出来

assembly x86 nasm factors
1个回答
0
投票

...我总不能得到正确的结果

原因是,随着循环的每次迭代,您都会更改股息,而股息应该保持不变。我看到您添加了一条

mul eax, ebx
指令,试图将股息恢复到其原始值,但遗憾的是,该指令可能看起来像双操作数乘法,实际上它是变相的通常的单操作数
mul ebx
!它使用 EAX 是隐含的,它将修改 EDX 寄存器(这意味着除法的余数消失了)。会起作用的是
imul eax, ebx
后跟
add eax, edx
(1),但首选的解决方案是在每个除法之前重新加载红利。使用
push eax
pop eax
(2),或者从用输入数字 (3) 初始化的备用寄存器加载 EAX。

  • 解决方案 1

       GET_UDEC 4, eax
       mov  ebx, 2
       mov  ecx, 0
      cycle:
       cmp  eax, ebx
       jbe  end
       xor  edx, edx
       div  ebx
       IMUL EAX, EBX    <<<< Does not destroy the remainder in EDX
       ADD  EAX, EDX    <<<<
       inc  ebx
       cmp  edx, 0
       jne  cycle
       inc  ecx
       jmp  cycle
      end:
    
  • 解决方案 2

       GET_UDEC 4, eax
       mov  ebx, 2
       mov  ecx, 0
      cycle:
       cmp  eax, ebx
       jbe  end
       xor  edx, edx
       PUSH EAX         <<<<
       div  ebx
       POP  EAX         <<<<
       inc  ebx
       cmp  edx, 0
       jne  cycle
       inc  ecx
       jmp  cycle
      end:
    
  • 解决方案 3

       GET_UDEC 4, eax
       MOV  ESI, EAX    <<<<
       mov  ebx, 2
       mov  ecx, 0
      cycle:
       cmp  eax, ebx
       jbe  end
       xor  edx, edx
       div  ebx
       MOV  EAX, ESI    <<<<
       inc  ebx
       cmp  edx, 0
       jne  cycle
       inc  ecx
       jmp  cycle
      end:
    

你可以更早地停止循环

输入为不超过1000的非负数N。
在 [2, N-1] 范围内求出这个数的除数个数。

考虑 N=1000。您当前的代码会将 1000 除以 [2,999] 范围内的每个数字。一共998个师!现在看看当您开始将 1000 除以 [501,999] 范围内的数字时会发生什么:余数永远不会为零,因此代码永远不会再增加 ECX。简而言之,您可以在 N/2 以上的 EBX 处停止循环。

     GET_UDEC 4, eax
     MOV  EDI, EAX    <<<<
     SHR  EDI, 1      <<<< EDI is now N/2
     MOV  ESI, EAX    <<<<
     XOR  ECX, ECX    <<<<
     mov  ebx, 2
    cycle:
     CMP  EBX, EDI    <<<< Exits on EBX > N/2, and also exits on N < 4
     JA   end         <<<<
     xor  edx, edx
     div  ebx
     MOV  EAX, ESI    <<<<
     inc  ebx
     TEST EDX, EDX    <<<<
     JNZ  cycle       <<<<
     inc  ecx
     jmp  cycle
    end:
© www.soinside.com 2019 - 2024. All rights reserved.