2016-04-28 9 views
0

Ich arbeite derzeit an der Erstellung eines Assembly-Programms mit NASM elf64 x64, die zeigen wird, ob ein eingegebenes Jahr ein Schaltjahr ist oder nicht. Zur Zeit habe ich das Jahr als 1986 fest programmiert, aber in der endgültigen Version sollte es ein Befehlszeilenargument enthalten.Schaltjahr NASM Assembly Programm

Jedoch. Ich bekomme immer einen Gleitkommafehler, von dem ich nicht weiß, woher er kommt.

global main 
    extern puts 
    section .text 

main: 
    mov rax, year 
    cwd 
    mov rcx, 400 
    div rcx 
    test rdx, rdx 
    jz _is_leap 

    mov rax, year 
    cwd 
    mov rcx, 100 
    div rcx 
    test rdx, rdx 
    jz _no_leap 

    mov rax, year 
    test rax, 3 
    jz _is_leap 

year 
    dq  1986, 10, 0  


_no_leap: 
    db  "This is NOT a leap year", 10, 0   ;print out is not a leap year 
    jmp _after 

_is_leap: 
    db  "This is a leap year", 10, 0   ;print is a leap year 
    jmp _after 

_after: 
    ret 

Vielen Dank im Voraus

+0

Nur aus Neugier was ist das ", 10, 0" nach dem Jahr für? –

+1

'cwd' tut nicht, was Sie denken, dass es tut. Sie sollten stattdessen einfach "rdx" auf Null setzen. Und wie Matti sagte, spring nicht in Daten :) – Jester

+0

@MattiVirkkunen War unter dem Eindruck, die notwendig waren, um eine "db" Anweisung abzuschließen – Jeremy

Antwort

0

Ein Gleitkomma-Fehler in einem Programm, das in ganzen Zahlen nur Angebote in der Regel durch eine falsche Teilung verursacht wird. In Ihrem Fall sieht es nicht wie eine Division durch Null aus, also wäre es ein Divisionsüberlauf, wie Michael Petch in den Kommentaren darauf hingewiesen hat.

Ein größeres Problem besteht jedoch darin, dass Sie zu einem Speicherort springen, der keinen gültigen Code enthält. Zum Beispiel enthält Ihr Standort _no_leap die Bytes, die den String "Dies ist KEIN Schaltjahr \ n \ 0" darstellen, und Sie sagen dem System, das als Code zu interpretieren. Das wird einfach nicht funktionieren.

Durch einfaches Ausführen von Daten wird der Computer nicht gedruckt. Sie müssen einen Systemaufruf durchführen, um eine Zeichenfolge auszudrucken. Der Weg dazu ist plattformabhängig.

+0

verschieben. Es gibt zwei allgemeine Gründe für einen ganzzahligen Teilungsfehler mit dem DIV-Befehl. Div durch Null und Divisionsüberlauf, wobei der Quotient nicht im Zielregister dargestellt werden kann. Dies ist normalerweise der Fall, wenn Personen DIV ausführen und DX/EDX/RDX-Register nicht auf Null setzen. In diesem Fall wäre 'xor edx, edx' für nicht unterzeichnete Division gerechtfertigt. –

+1

Oh, ich wusste nicht, dass der Überlauf den gleichen Fehler verursacht. Dann wäre es die Teilung, die das Problem ist. Wenn das behoben ist, stürzt es sofort ab, indem versucht wird, Daten auszuführen. –