2016-06-01 5 views
0
INCLUDE Irvine32.inc 
.data 
org 100h ; set location counter to 100h 
.code 
main PROC 
jmp CodeStart 

DataStart: 
max dw " " 
space db " ", 0 

CodeStart: 
mov bx, 1 

call IsPrime 

cmp dx, 0 


LoopStart: 

; must be a prime 
mov ax, bx 
call print_num 

; print a space 
mov si, offset space 
call print_string 

add bx, 1 
cmp bx, max 

jle LoopStart 

ret 


IsPrime PROC 
; uses a loop to determine if number in bx is prime 
; upon return if bx not prime dx will be 0, otherwise dx > 0 

; we only have to test divisors from 2 to bx/2 

; prepare to divide dx:ax/2 
mov ax, bx 
mov dx, 0 
mov cx, 2 
div cx 

; move result into si for loop 
mov si, ax 

; assume the value is prime 
mov dx, 1 

; start loop at 2 
mov cx, 2 

PrimeLoop: 

; compare loop count(in cx) and max loop value (in si) 
cmp cx, si 

; jump out of loop if count(cx) > si 
ja StopLabel 

; divide test value (in bx) by loop count (in cx) 
mov ax, bx 
mov dx, 0 
div cx 

; check remainder (in dx), if zero then we found a divisor 
; and the number cannot be prime 
cmp dx, 0 

; if dx = 0 then we found a divisor and can stop looking 
je StopLabel 

; increment count 
add cx, 1 

jmp PrimeLoop 

StopLabel: 

ret 
IsPrime ENDP 

END IsPrime 

Ich habe Probleme mit diesem Fehler sagt es auf meiner letzten Zeile? Kann jemand etwas darüber aufklären, was das Problem sein könnte?(94): fataler Fehler A1010: nicht übereinstimmende Blockverschachtelung: Haupt

+2

Dies ist Ihre zweite Frage betrifft, sehr ähnlich wie Ihre [erste] (https://stackoverflow.com/questions/37561264/ ch03-addsub-asm45-fatal-Fehler-a1010-unmatched-block-nesting-isprime). Während wir froh sind zu helfen, denke ich, dass Sie ernsthaft beginnen müssen, einige Problemlösungsfähigkeiten zu entwickeln. Wenn Sie auf einen Fehler stoßen, den Sie nicht beheben können, entfernen Sie zunächst die Funktionsblöcke, bis sie nicht mehr funktionieren. Dann lege sie eins nach dem anderen zurück. Sobald Sie den fehlerhaften Block kennen, schreiben Sie eine neue minimale Quelle, die den Fehler reproduziert. Dies ist die [mcve] und es ist sehr gut, Fehler zu isolieren. –

+1

Beginnen Sie damit, 'IsPrime' zu ​​entfernen und sehen Sie, ob Sie Asymmetrien erkennen können. Bitte nehmen Sie sich auch etwas Zeit, um sich mit [Formatierung] (https://stackoverflow.com/editing-help) vertraut zu machen, wenn Sie denken, dass Sie weitere Fragen stellen müssen. –

+1

Warum werden Daten in den Codeabschnitt und nicht in den Datenbereich, in den sie gehören, eingefügt? Warum wird 'org 100h' in diesem Programm verwendet? – Michael

Antwort

1

Die END Direktive sollte nichts folgen. Diese Direktive gibt das Ende der gesamten Datei und nicht einen bestimmten Bereich an, sodass Sie den Bereich nicht benennen müssen.
(Obwohl Sie können optional END mit dem Namen der Einstiegspunkt Prozedur folgen, die würden main in Ihrem Fall sein, ist dies nicht notwendig ist, und selten in meiner Erfahrung gemacht.)

Hinweis, dass dies im Gegensatz zu ENDP (Endprozedur), dem der Name der Prozedur vorangestellt ist, die zu Ende geht (die mit der PROC-Anweisung begonnene Prozedur).

Die letzten drei Zeilen sollten wie folgt aussehen:

IsPrime ENDP ; end the IsPrime procedure 

END   ; end of the entire file 

Ihr Code deutlich leichter zu lesen, wenn Sie die Linien eingekerbt nach jedem Anwendungsbereich wäre. Außerdem vermute ich, dass Sie dann Ihre eigenen "unübertroffenen Blockverschachtelungsfehler" finden können.

Zum Beispiel würden Sie auch bemerken, dass es keine ENDP Richtlinie für die main Prozedur gibt!


A korrigiert (! Und schön formatiert) Version:

INCLUDE Irvine32.inc 


.data 
org 100h ; set location counter to 100h 


.code 

;;;;;;;;;;;;;;;;;;;;;;;; 
;; Main 
;;;;;;;;;;;;;;;;;;;;;;;; 

main PROC 
    jmp CodeStart 

    DataStart: 
    max dw " " 
    space db " ", 0 

    CodeStart: 
    mov bx, 1 
    call IsPrime 
    cmp dx, 0 

    LoopStart: 
    ; must be a prime 
    mov ax, bx 
    call print_num 

    ; print a space 
    mov si, offset space 
    call print_string 

    add bx, 1 
    cmp bx, max 

    jle LoopStart 

    ret 
main ENDP 

;;;;;;;;;;;;;;;;;;;;;;;; 
;; IsPrime 
;;;;;;;;;;;;;;;;;;;;;;;; 

IsPrime PROC 
    ; uses a loop to determine if number in bx is prime 
    ; upon return if bx not prime dx will be 0, otherwise dx > 0 

    ; we only have to test divisors from 2 to bx/2 

    ; prepare to divide dx:ax/2 
    mov ax, bx 
    mov dx, 0 
    mov cx, 2 
    div cx 

    ; move result into si for loop 
    mov si, ax 

    ; assume the value is prime 
    mov dx, 1 

    ; start loop at 2 
    mov cx, 2 

    PrimeLoop: 

    ; compare loop count(in cx) and max loop value (in si) 
    cmp cx, si 

    ; jump out of loop if count(cx) > si 
    ja StopLabel 

    ; divide test value (in bx) by loop count (in cx) 
    mov ax, bx 
    mov dx, 0 
    div cx 

    ; check remainder (in dx), if zero then we found a divisor 
    ; and the number cannot be prime 
    cmp dx, 0 

    ; if dx = 0 then we found a divisor and can stop looking 
    je StopLabel 

    ; increment count 
    add cx, 1 

    jmp PrimeLoop 

    StopLabel: 
    ret 
IsPrime ENDP 


END 
+0

Gemäß der [Dokumentation] (https://msdn.microsoft.com/en-us/library/wxy1fb5k.aspx) darf 'END' einen Operanden haben, der die Eintrittspunktadresse ist. Das sollte wohl nicht "IsPrime" sondern "haupt" sein. – Jester

Verwandte Themen