2016-03-25 31 views
-1

YENİ SORUN ise:Kontrol 120 kadar bir sayı asal

  1. : Bunu başarmak için çalışıyorum

    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 
    

    (o 2'ye bölünebilir olup olmadığını kontrol etmek çalışılıyor) 120'ye kadar giriş numarası. Buna "num" diyelim. 2,3,5,7,11 ile Buradaki sayı kalan sıfırsa

  2. , ben onun geri kalan sıfırdır her sayı ile bölünme yazdırmak gerekiyor. Aksi takdirde, bu sayı yazdırılırsa asal sayıdır.

ör

girişi: 120 çıkışı: 120 = 60/2, = 40.

giriş 120/3: 118, çıkış 118 asal.

yaptığım Ne:

  1. ben ilk 3 rakamını (ilk basamak sıfır olursa, umurumda değil) tarama ve ben 'num' inşa etmek kolay bir algoritma kullanır. Ayrıca ben numara herhangi biri tarafından bölünebilir olup olmadığını sayı daha küçük 121.

  2. olduğunu varsayalım (2,3,5,7,11) Ben aksi takdirde msj baskı atlayın msj yazdırın. numarası ile tüm geri kalan sıfırsa

  3. , ben num bir asal sayı olduğunu yazdırmak.

Bunu gerçekleştirdiğimden emin değilim çünkü DOSBox'ı çalıştırırken bazı sorunlar yaşıyorum, bunu doğru yapıp yapmadığımı belirlememe yardımcı olabilir misiniz?

ÇÖZÜM: programlamada

.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 
+3

10 Tam değerde arabellek girdisi için int 21/A işlevini de kullanabilirsiniz. Ayrıca: “11” değerini kontrol etmeniz gerekmez, çünkü “120” nin karekökünden büyüktür. –

+0

@WeatherVane Program, 0-120 –

+0

numaralı numarayı girdikten sonra sonlandırıldı. Algoritma, '0' için bir akümülatör başlatır. Daha sonra girilen her rakam için, ASCII ayarını doğru bir şekilde yapmanıza rağmen "accum = accum * 10 + digit" olmalıdır. –

cevap

2

bir kural "Kendinizi tekrarlamayın" dir. Bu nedenle, kodu her kopyaladığınızda, kendinizden kaçınılabileceğinizi kendinize sormalısınız. Bunun yerine, ayrı bir kod bloğu her asal kontrol, sen asal

num  db 118 
prims db 2,3,5,7,11   ; these pimes will be checked 

bir "dizi" kullanabilir ve daha sonra böyle bir döngü içinde bunların her kontrol edin:

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: Ayrıca sizi Bir döngü ile yaptığınız zaman, "3 basamaklı tarama" daha iyiydi, örn. Eğer uzatmak istiyorsanız bu bir 16bit int girmek için 1-5 basamak gibi 5 rakam, hatta bir değişken miktarda okumak için.
Ayrıca ben muhtemelen onları yeniden kullanmak istediğiniz (SONRA bunun kodunu, ilk olarak bir tampon içine TÜM karakter girin) gelen "bir rakamı girmek" bölümünü ayırmak "kod çözme ASCII ve bir int yapmak" parça ediyorum;

+0

Tommy, cevabınız için teşekkürler. Kodumu postada düzenledim. bakabilir misin? 60/2 = 30 basmak istiyorum ve 30 basmak istiyorum. Bu yüzden 10'a bölüyorum ve 3'ten AL ve 3'ten AH'den yazdırıyorum. hangi işe yaramıyor. kalp veya başka işaretler gibi bir ascii işareti basar, nedenini biliyor musunuz? 30 yazdırmak için –

+0

, ASCII '3' ve ASCII '0' yazdırmanız gerekir. Yazdırmadan önce rakam değerlerine '0' ekleyin (siz girdiğinizde her rakam için '0' çıkardınız, hatırlıyor musunuz? Bu aynı şeydir) – Tommylee2k

+0

Son olarak, 4 saat sonra .. ama neden ADD'ye ihtiyacım vardı? SUB değil mi ?! –