检查 120 以内的数是否为质数

Check if a number upto 120 is a prime

最新问题:(尝试检查它是否可以被 2 整除)

MOV AH, 0 ;reset AH before division
    MOV AL,[myNum] ;move the inputed number to AL
    DIV two ;div 123 / 2;
    CMP AH,0
    JNE inputIsPrime

    ;If 123 % 2 = 0, output 123 / 2.
    DIV ten
    MOV DH,AH

    SUB AL,'0'
    MOV AH,2
    MOV DL, AL
    INT 21h

    MOV divisionCalc,DH

    MOV AH,2
    MOV DL,DH
    INT 21h
    JMP endProg

我正在努力做到这一点:

  1. 输入最大为 120 的数字。我们称它为“num”。

  2. 如果数字与 2,3,5,7,11 的余数为零,我需要打印每个余数为零的数字的除法。否则,如果打印 num 是质数。

e.g.

input: 120. output: 120 / 2 = 60, 120 / 3 = 40.

input: 118, output: 118 is prime.

我做了什么:

  1. 我扫描前 3 位数字(我不在乎前 3 位数字是否为零)并使用简单的算法构建 'num'。我也假设这个数字小于 121.

  2. 如果数字可以被 (2,3,5,7,11) 中的任何一个整除,我打印 msg,否则我跳过 msg 打印。

  3. 如果数字的所有余数都为零,我打印 num 是一个素数。

我不确定我是否做到了,因为我遇到了一些问题 运行 DOSBox,你能帮我确定我做对了吗?

解决方案:

.MODEL SMALL
.STACK 100h
.DATA

DisplayString DB 'Enter number up to 120:', 13,10,'$'
isPrimeNum DB 'is prime', 13,10,'$'
ResultStr DB 13,10, '    /    =   ' , 13,10,'$'
divisionCalc DB ?
myNum DB ?
two DB 2
three DB 3
five DB 5
seven DB 7
ten DB 10
eleven DB 11

    .CODE
Begin:
    MOV AX,@DATA
    MOV DS,AX
    
    MOV AH,9
    MOV DX,OFFSET DisplayString
    INT 21h
    
    MOV BL,0 ; Initialize BL to zero!
    
    ; //READ 3 DIGITS // ;
    ;read first digit for e.g. '1'
    MOV ah,1h
    INT 21h ;read into AL
    MOV CL,AL
    MOV ResultStr[2], AL
    SUB AL,'0' ; Convert the digit from ASCII to DECIMAL
    MOV myNum,AL
    
    MOV AH,1
    INT 21h
    CMP AL,13 ;is it Enter?
    JE endInput
    MOV ResultStr[3], AL
    SUB AL,'0' ;Not enter, let's save this new char
    MOV CL, AL ; we save the 2nd char to CL
    MOV AL, myNum ; lets move our first char to AL
    MUL Ten ; multiply by 10 the first char
    MOV myNum,AL ;move that to myNum
    ADD myNum,CL ; add to AL the 2nd char.
    
    MOV AH,1
    INT 21h
    
    CMP AL,13 ; is it enter?
    JE endInput
    MOV ResultStr[4], AL
    SUB AL,'0' ;Not enter, let's save this new char
    MOV CL, AL ; we save the 2nd char to CL
    MOV AL, myNum ; lets move our first char to AL
    MUL Ten ; multiply by 10 the first char
    MOV myNum,AL ;move that to myNum
    ADD myNum,CL ; add to AL the 2nd char.
    
    mov AH,1 ; if the number is 3 chars then this will be the enter now. 
    int 21h 
    
    ; // FINISH READING 3 DIGITS // ;
    endInput:
    
            ; AL = AX / two
        ; AH = AX % two
MOV AH, 0 ;reset AH before division
MOV AL,[myNum] ;move the inputed number to AL
mov CL,[myNum]
DIV two ;div 123 / 2;
CMP AH,0
JNE divThree

;If 123 % 2 = 0, output 123 / 2.

MOV ResultStr[9], '2'

DIV ten
MOV DH,AH

ADD AL,'0'
MOV ResultStr[13], AL
ADD DH,'0'
MOV ResultStr[14], DH

MOV AH,9
MOV DX,OFFSET ResultStr
INT 21h

divThree:
MOV AH, 0 ;reset AH before division
MOV AL,[myNum] ;move the inputed number to AL
DIV three ;div 123 / 3;
CMP AH,0
JNE divFive

;If 123 % 3 = 0, output 123 / 3.
MOV ResultStr[9], '3'

DIV ten
MOV DH,AH

ADD AL,'0'
MOV ResultStr[13], AL
ADD DH,'0'
MOV ResultStr[14], DH


MOV AH,9
MOV DX,OFFSET ResultStr
INT 21h

divFive:
MOV AH, 0 ;reset AH before division
MOV AL,[myNum] ;move the inputed number to AL
DIV five ;div 123 / 5;
CMP AH,0
JNE divSeven

;If 123 % 5 = 0, output 123 / 5.
MOV ResultStr[9], '5'

DIV ten
MOV DH,AH

ADD AL,'0'
MOV ResultStr[13], AL
ADD DH,'0'
MOV ResultStr[14], DH

MOV AH,9
MOV DX,OFFSET ResultStr
INT 21h

divSeven:
MOV AH, 0 ;reset AH before division
MOV AL,[myNum] ;move the inputed number to AL
DIV seven ;div 123 / 7;
CMP AH,0
JNE divEleven

;If 123 % 7 = 0, output 123 / 7.
MOV ResultStr[9], '7'

DIV ten
MOV DH,AH

ADD AL,'0'
MOV ResultStr[13], AL
ADD DH,'0'
MOV ResultStr[14], DH

MOV AH,9
MOV DX,OFFSET ResultStr
INT 21h

divEleven:
MOV AH, 0 ;reset AH before division
MOV AL,[myNum] ;move the inputed number to AL
DIV eleven ;div 123 / 11;
CMP AH,0
JE Skip1
JMP inputIsPrime

Skip1:
;If 123 % 11 = 0, output 123 / 11.
MOV ResultStr[8], '1'
MOV ResultStr[9], '1'

DIV ten
MOV DH,AH

ADD AL,'0'
MOV ResultStr[13], AL
ADD DH,'0'
MOV ResultStr[14], DH

MOV AH,9
MOV DX,OFFSET ResultStr
INT 21h

JMP endProg

inputIsPrime:
MOV AH,9
MOV DX,OFFSET isPrimeNum
INT 21h

endProg:
MOV AH,4Ch
INT 21h
END Begin

编程中的一个规则是"don't repeat yourself"。所以每次抄代码的时候,都要问问自己能不能避免。您可以使用 "array" of primes

而不是在单独的代码块中检查每个素数
num     db 118
prims   db 2,3,5,7,11           ; these pimes will be checked

然后像这样循环检查它们中的每一个:

start:  mov cx, 5               ; number of prims to check
        mov si, offset prims

checkPrime:
        xor ah, ah              ; this is faster than mov ah,0
        mov al, [num]
        div byte ptr [si]

        cmp ah,0
        jne skip

        ;...                    ; here you do whatever you want to do with non-primes
                                ; or even jump out of the loop, if all you want is to 
                                ; determine if [num] is a prime

skip:   inc si
        dec cx
        jnz checkPrime

ps:如果你用循环实现,你 "scan in 3 digits" 也更好,例如如果您想将其扩展为读取 5 位数字,甚至是可变数量,例如 1-5 位数字以输入 16 位整数。
此外,我会将 "enter a digit" 部分与 "decode ascii and make an int of it" 部分分开,(首先将所有字符输入缓冲区,然后对其进行解码)你可能想重用它们;
您还可以使用函数 int 21/A,作为完整值的缓冲输入