2017-04-17 7 views
0

Die ersten zwei Zeilen des ersten Monats werden abgeschnitten und ich weiß nicht warum. Es spielt keine Rolle, wenn Sie die Reihenfolge des Drucks ändern oder April löschen; Der Mai wird auch abgeschnitten, wenn Sie das tun. Ich binDrucken von Monaten im Kalenderformat in Assembler (tasm mit Dosbox). Mein erster Monat wird immer abgeschnitten

.model tiny 
.data 

Apr   db "   April 2017  ",13,10 
       db "Sun Mon Tue Wed Thu Fri Sat",13,10 
       db "       1 ",13,10 
       db " 2 3 4 5 6 7 8 ",13,10 
       db " 9 10 11 12 13 14 15 ",13,10 
       db "16 17 18 19 20 21 22 ",13,10 
       db "23 24 25 26 27 28 29 ",13,10 
       db "30     ",13,10,0 

    May  db "   May 2017   ",13,10 
       db "Sun Mon Tue Wed Thu Fri Sat ",13,10 
       db "  1 2 3 4 5 6 ",13,10 
       db " 7 8 9 10 11 12 13 ",13,10 
       db " 14 15 16 17 18 19 20 ",13,10 
       db " 21 22 23 24 25 26 27 ",13,10 
       db " 28 29 30 31    " 


.code 
    org 100h 

    print : 
     mov ah,9 
     int 21h 
     ret 
      end print 

    start: 
    lea dx,Apr 
    call print 

    lea dx,May 
    call print 

    mov ah, 4ch 
    int 21h 

end start 
+1

Wie in der Dokumentation zu 'int 21h/ah = 9' angegeben, sollte der String mit' '$ '' abgeschlossen werden. – Michael

+0

'.model tiny',' org 100h' (.COM-Programm) und '.data',' .code '(.EXE-Programm) stimmen nicht überein. Erstellen Sie ein .COM-Programm oder ein .EXE-Programm? Zeigen Sie die Befehlszeilen an, mit denen Sie das Programm erstellen. – rkhb

+0

Das Hinzufügen von $ hilft auch nicht. Es macht es tatsächlich schlimmer, weil nur eine Zeile gedruckt wird: 16 17 18 19 20. – ajstc

Antwort

1

ich Ihren Code einige Änderungen haben, jetzt tut es, was es sollte:

1) winziges .model hat Daten und Code im gleichen Segment, und Sie brauchen einen Sprung über die Daten Teil zu Ihrer Startadresse. da Sie haben bereits 2 segements, zu .model small verändern und dadurch die .org festen Entfernen (dies die Notwendigkeit der Initialisierung Datensegment DS enthält)

2) DOS Int 21/9 druckt Everthing es bis zu einem „$“ findet . so dass nur ein Druck benötigt wurde

3) DOS int 21/4c kehrt AL als Fehlercode, da kein Fehler war, besser zurückgeben 0

.model small 
.data 

    Cal  db "   April 2017  ",13,10 
       db "Sun Mon Tue Wed Thu Fri Sat",13,10 
       db "       1 ",13,10 
       db " 2 3 4 5 6 7 8 ",13,10 
       db " 9 10 11 12 13 14 15 ",13,10 
       db "16 17 18 19 20 21 22 ",13,10 
       db "23 24 25 26 27 28 29 ",13,10 
       db "30     ",13,10,0 

    May  db "   May 2017   ",13,10 
       db "Sun Mon Tue Wed Thu Fri Sat ",13,10 
       db "  1 2 3 4 5 6 ",13,10 
       db " 7 8 9 10 11 12 13 ",13,10 
       db " 14 15 16 17 18 19 20 ",13,10 
       db " 21 22 23 24 25 26 27 ",13,10 
       db " 28 29 30 31    " 

    EndStr db "$" ; tell DOS to stop printing here 


.code 

start: 
    mov ax,@data  ; initialize data segment 
    mov ds,ax 

    mov dx,offset Cal ; print Calender 
    mov ah,9 
    int 21h 

    mov ax, 4c00h  ; return to DOS 
    int 21h 

end start 
3

Sie haben eine frühe END Richtlinie.
Vom TASM 5 manual:

Die End-Direktive
Verwenden Sie die END Richtlinie die Ende der Quelldatei markieren. Die Syntax sieht wie folgt aus:

END [ startaddress ] 

startaddress ist ein optionales Symbol oder Ausdruck, der die Adresse in Ihrem Programm gibt an, wo Sie die Ausführung beginnen soll.

Die erste end print endet damit die Quelle

mov ah, 09h 
int 21h 
ret 

das Programm zur Reduzierung Wie Sie mit Turbo-Debugger

Turbo debugger showing missing pieces of code

Dies bewirkt, dass das beobachtete Verhalten sehen.

Als Hinweis können Sie Prozeduren mit einem PROC/ENDP Paar definieren, aber das ist nicht obligatorisch - es ist normalerweise eine gute Übung, die Direktiven in Großbuchstaben zu schreiben, damit sie beim Lesen der Quelle hervorstechen.


die end print Entfernen ist nicht genug, um Ihr Programm zu beheben.
Neben der Tatsache, dass INT21h/AH=9 erfordert die Zeichenfolge mit einem $ (beide) beendet werden, wenn Sie kommen, um die Objektdatei verknüpfen TLINK wird beschweren.

Fatal: Daten unter dem ursprünglichen CS: Kann nicht COM-Datei generiert IP definiert

Dies ist zu erwarten, da das COM-Dateiformat ist rein, Roh-Code ohne Metadaten überhaupt.
Der Eingangspunkt ist als Offset 100h definiert und kann nicht mit der Vollversion der END-Direktive, die [startaddress] benötigt, an eine andere Adresse erzwungen werden.

Sie müssen die print Prozedur nach unten verschieben.

.model tiny 
.data 

Apr   db "   April 2017  ",13,10 
       db "Sun Mon Tue Wed Thu Fri Sat",13,10 
       db "       1 ",13,10 
       db " 2 3 4 5 6 7 8 ",13,10 
       db " 9 10 11 12 13 14 15 ",13,10 
       db "16 17 18 19 20 21 22 ",13,10 
       db "23 24 25 26 27 28 29 ",13,10 
       db "30     ",13,10,24h 

    May  db "   May 2017   ",13,10 
       db "Sun Mon Tue Wed Thu Fri Sat ",13,10 
       db "  1 2 3 4 5 6 ",13,10 
       db " 7 8 9 10 11 12 13 ",13,10 
       db " 14 15 16 17 18 19 20 ",13,10 
       db " 21 22 23 24 25 26 27 ",13,10 
       db " 28 29 30 31    ", 24h 


.code 

org 100h 




    start: 

    lea dx,Apr 
    call print 

    lea dx,May 
    call print 

    mov ah, 4ch 
    int 21h 

print : 
     mov ah,9 
     int 21h 
     ret 
+0

Vielen Dank für Ihre Hilfe. Danke, dass Sie sich ausführlich über meine Fehler informiert haben. Ich bin neu in der Assemblersprache und das war sehr hilfreich. – ajstc