Primzahlen



  • Hallo, ich bins wieder und ich habe jetzt versucht ein Programm in Assembler zu schreiben, das die Primzahlen von 1 bis 9 ermittelt. Doch leider erscheint diese Ausgabe:

    Primzahl gefunden: 3
    Primzahl gefunden: 7
    Primzahl gefunden: 9
    

    Hier mein Code:

    include \masm32\include\masm32rt.inc
    
        .data
            zahl db 1
            strzahl db 2 dup(0)
    
        .code
    
    start:
    
    ; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    
        call main
        exit
    
    ; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    
    main proc
    
        xor eax,eax
        xor ecx,ecx
        xor ebx,ebx
        xor edx,edx
    
        mov cx,9
    
        teste_zahl:
    
            mov al,zahl
    
            push ecx            ; Schleifenzähler sichern
            mov bl,2
    
                teilen:
    
                    div bl
    
                    cmp ah,0
                    je keine_primzahl
    
                    inc bl
    
                    cmp zahl,bl
                    je primzahl
    
                loop teilen
    
            primzahl:
    
                print "Primzahl gefunden: "
                mov al,zahl  ;Zahl die von print_zahl ausgegeben wird
                call print_zahl
    
            keine_primzahl:
    
            pop ecx ; Schleifenzähler zurückholen
            inc zahl
    
        loop teste_zahl
    
        ret
    
    main endp
    
    ; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    
    print_zahl proc
    
        push ecx ; sichern,weil es sonst von print verändert wird
        mov strzahl,al
        add strzahl,48  ;48 addieren, damit Zahl zu Buchstabe wird (48 = Ascii von '0')
        print ADDR strzahl,13,10
        pop ecx
    
        ret
    
    print_zahl endp
    
    ; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    
    end start
    


  • gfenz schrieb:

    Hallo, ich bins wieder und ich habe jetzt versucht ein Programm in Assembler zu schreiben, das die Primzahlen von 1 bis 9 ermittelt

    1. DIV ist ein gemeiner Befehl. In Deinem Fall bezieht er sich auf AX (nicht auf AL) und verändert AH und AL, also das gesamte AX.

    Lösche Zeile 29 und füge in Zeile 35 ein:

    35 movzx ax,zahl
    

    (Zeilennummer weglassen)

    1. "loop teilen" soll wohl immer maximal 9 Mal geschehen. Durch "loop teste_zahl" wird aber ECX immer kleiner. Du brauchst diesen Loop aber nicht:
    43 cmp zahl,bl
    44 jbe primzahl      ; statt je primzahl
    
    46 jmp teilen        ; statt loop teilen
    

    (Zeilennummer weglassen)

    viele grüße
    ralph



  • Danke, aber leider hab ichs immer noch nicht geschafft 😞 ,iregendwas läuft da schief.



  • gfenz schrieb:

    Danke, aber leider hab ichs immer noch nicht geschafft 😞 ,iregendwas läuft da schief.

    Ich hab meine Ratschläge bei mir geprüft. Poste mal den Code, der bei Dir Probleme macht.

    viele grüße
    ralph



  • gfenz schrieb:

    iregendwas läuft da schief.

    OllyDbg 💡



  • Wozu soll eigentlich der Code hier noch gut sein?

    43 cmp zahl,bl
    44 je primzahl
    

    Und die 2 auszufiltern? Die kann man auch direkt vergleichen:

    cmp zahl,2
    

    Alle ungeraden Zahlen haben übrigens eine 1 am binären Ende.
    Multiplikationen bereits gefundener Zahlen braucht man auch nicht mitzuzählen.
    Und statt inc bl vielleicht

    add bl, 2
    

    ? 😉

    @rkhb
    Wenn man mit 8Bit Zahlen mit Div dividiert, gilt hier analog zum Registerpärchen DX:AX das Registerpärchen AH:AL. Bei 8Bit Zahlen landet der Divisionsrest in AH.

    AX=000C  BX=0009  CX=0000  DX=0000  SP=E08F  BP=0000  SI=0000  DI=0000
    DS=1E60  ES=1E60  SS=1E60  CS=1E60  IP=0100   NV UP EI PL NZ NA PO NC
    1E60:0100 0000           ADD    [BX+SI],AL                         DS:0009=F2
    -a
    1E60:0100 div bl
    1E60:0102
    -t
    AX=0301  BX=0009  CX=0000  DX=0000  SP=E08F  BP=0000  SI=0000  DI=0000
    DS=1E60  ES=1E60  SS=1E60  CS=1E60  IP=0102   NV UP EI PL NZ NA PO NC
    1E60:0102 0000           ADD    [BX+SI],AL
    


  • @rkhb : kannst du mir bitte deinen Code posten, bei mir ist im ah Register nach der Division immer 0?



  • gfenz schrieb:

    @rkhb : kannst du mir bitte deinen Code posten, bei mir ist im ah Register nach der Division immer 0?

    Es ist exakt Dein Code - geändert nach meinen Ratschlägen:

    include \masm32\include\masm32rt.inc
    
    .DATA
    	zahl db 1
    	strzahl db 2 dup(0)
    
    .CODE
    
    start:
    	call main
    	exit
    
    main proc
    
    	xor eax,eax
    	xor ecx,ecx
    	xor ebx,ebx
    	xor edx,edx
    
    	mov cx,9
    
    teste_zahl:
    
    	push ecx
    	mov bl,2
    
    	teilen:
    
    		movzx ax,zahl
    		div bl
    
    		cmp ah,0
    		je keine_primzahl
    
    		inc bl
    
    		cmp zahl,bl
    		jbe primzahl
    
    		jmp teilen
    
    primzahl:
    
    	print "Primzahl gefunden: "
    	mov al,zahl
    	call print_zahl
    
    keine_primzahl:
    
    	pop ecx
    	inc zahl
    
    	loop teste_zahl
    
    	ret
    
    main ENDP
    
    print_zahl PROC
    	push ecx
    	mov strzahl,al
    	add strzahl,48
    	print ADDR strzahl,13,10
    	pop ecx
    	ret
    print_zahl ENDP
    
    END start
    

    viele grüße
    ralph



  • Funktioniert dieser Code bei dir? Bei mir wird gar nichts ausgegeben??



  • Ja, er funktioniert. Beliebter Fehler, wenn man Qeditor benutzt: Nicht "Build All" (bzw. "Assemble & Link"), sondern "Console Build All" (bzw. "Console Assemble & Link") benutzen. Ansonsten müsstest Du genauestens schildern, wie Du vorgehst und wie der Computer reagiert (Fehler- und andere Meldungen).

    viele grüße
    ralph



  • Oh genau das war der Fehler 🙄 , vielen Dank für deine Unterstützung!


Anmelden zum Antworten