home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / coders / assembler-kurs / listings / listing2f.s < prev    next >
Text File  |  1977-12-31  |  8KB  |  140 lines

  1.  
  2. ; Listing2f.s
  3.  
  4. Anfang:
  5.     lea    START,a0    ; Gib in a0 die Startadresse, d.h. gib in
  6.                 ; a0 die Adresse von START, also WO START
  7.                 ; sich befindet, nicht seinen INHALT!!
  8.     lea    THEEND,a1    ; Gib in a1 die Endadresse, also gib
  9.                 ; in THEEND das Ende der 40 Byte, denn das
  10.                 ; Label befindet sich unter den 40 Bytes
  11.             ; Nun wird ALLES, was sich zwischen den Label
  12.             ; START und THEEND befindet, gelöscht. Dafür sorgt
  13.             ; die CLELOOP: Schleife, seien es nun 40 Byte oder
  14.             ; mehr, auch wenn sich dazwischen Befehle befinden
  15.             ; würden.
  16.  
  17. CLELOOP:
  18.     clr.l    (a0)+ ; Löscht das Long, das sich in Adresse (a0) befindet,
  19.             ; danach zählt es 4 Byte zu a0 dazu (Long!!!)
  20.             ; Achtung! Das ist eine indirekte Adressierung, in
  21.             ; der nicht das Register a0 gelöscht wird, sondern den
  22.             ; Inhalt, der sich auf der enthaltenen Adresse befindet,
  23.             ; hier vier $fe pro Durchgang ($fe ist eine Zufallszahl,
  24.             ; die ich verwende, grad um sie von den Nullen zu
  25.             ; unterscheiden!) Um zu beweisen, daß ich einen Teil des
  26.             ; Speichers lösche, der mit $fe gefüllt ist;
  27.             ; Da ein + nach der Klammer steht, wird nach jedem Aufruf
  28.             ; von a0 dieses um 4 erhöht, es positioniert sich also
  29.             ; auf die nächste Zelle, die es zu löschen gilt.
  30.            ; Beim ersten Durchgang werden die ersten 4 $fe unter Start 
  31.            ; gelöscht, beim nächsten die darauffolgenden und so weiter.
  32.              ; Zu Beachten ist, daß nur a0 raufzählt, a1 bleibt stehen.
  33.     cmp.l    a0,a1    ; Ist a0 = a1, ist also a0 bei THEEND angekommen?
  34.     bne.s    CLELOOP    ; wenn nicht, zurück zu CLELOOP
  35.     rts        ; Fertig, zurück zum ASMONE
  36.  
  37. START:
  38.     dcb.b    40,$fe    ; Der Befehl DCB dient dazu, einen Teil des Speichers
  39.             ; mit einer bestimmten Anzahl von Bytes, Words oder
  40.             ; Longwords zu füllen, die alle gleich sind (Hier: $fe)
  41.             ; Er ist ähnlich dem Befehl DC.B, nur hätten wir für
  42.             ; 40 Bytes dc.b $fe, $fe, $fe, $fe ... tippen müßen!
  43.             ; Mit dem DCB.B 40,$fe geht´s einfacher: GIB AB HIER
  44.             ; 40 BYTES VOM TYP $FE IN DEN SPEICHER.
  45. THEEND:            ; Dieses Label markiert das Ende der 40 Bytes...
  46.     dcb.b    10,0    ; Aus purem Spaß hänge ich 10 Nuller an...
  47.  
  48.     end
  49.  
  50. Achtung!! Mit LEA START,a0 wird in a0 die Adresse des ersten  der  vierzig
  51. $fe-Bytes  gegeben,  es  enthält  nicht  40  Bytes!!  Die Labels sind eine
  52. Konvention, die in der Programmierung verwendet werden, um sich im Listing
  53. orientieren  zu  können,  sie  dienen  dazu,  den verschiedenen Teilen des
  54. Programmes einen Namen zu geben, seien es nun Befehle  oder  anderes,  und
  55. beim Aufruf derer beziehen wir uns GENAU AUF DEN PUNKT, IN DER SIE STEHEN,
  56. also die Adresse, auf der die Label steht. Um  Konfusionen  zu  vermeiden,
  57. stellt euch mal vor, wieso eigentlich Labels erfunden wurden: würde es sie
  58. nicht geben, müßten wir jedes Byte numerieren, also mit  Adressen  denken,
  59. also  statt  ein BNE.S CLELOOP müßten wir z.B. ein BNE.S $20398 schreiben,
  60. also die Adresse, bei der der  Loop  beginnt,  wo  sich  das  clr.l  (a0)+
  61. befindet. Genauso, statt LEA START,a0, wäre ein LEA $123456,a0 nötig, also
  62. die Adresse, von wo ab zu Löschen ist, angenommen,  die  Startadresse  sei
  63. $123456.  Stellt  euch  dann  auch  noch  vor,  wir  müßten  auch nur eine
  64. Instruktion im Loop einfügen! Jetzt wäre START nach vorne verrutscht,  und
  65. wir  hätten  statt  dem  LEA  $123456,a0 die nun gültige Adresse einsetzen
  66. müßen. Ein Ding  zum  Kinder  kriegen!!  Wenn  wir  aber  jedem  PUNKT  IM
  67. PROGRAMM,  der  uns interessiert, einen Namen geben, so wie man einem Fluß
  68. auch einen Namen gibt, dann beschreibt man damit die Adresse, bei  der  er
  69. beginnt  (und  NICHT  seinen  INHALT!!). Wenn ich LEA START,a0 mache, dann
  70. befindet sich in  a0  nicht  der  Inhalt  von  Start!!  In  der  Fase  des
  71. Assemblierens  kümmert  sich  dann  der Assembler darum, die Label mit der
  72. realen Adresse zu ersetzen, egal ob sie inzwischen verstellt  wurde  (z.B.
  73. etwas  eingefügt...).  Dieses  Programmchen  macht  Großputz  zwichen  der
  74. Adresse in a0 und der in a1: Um das zu überprüfen, assembliert mit  A  und
  75. und dann führt ein M START aus (BEVOR ihr mit J das Programm startet). Ihr
  76. werdet ab diesem Punkt die berühmt-berüchtigten $fe finden,  und  zwar  40
  77. Stück!  Als  weitere  Probe,  macht ein D Anfang, und ihr werdet in a0 die
  78. gleiche Zahl bemerken, wie sie auch neben dem ersten  LINE_F  steht,  also
  79. die  Adresse des ersten $fe, das als LINE_F vom ASMONE interpretiert wird.
  80. In a1 steht die Adresse von THEEND, wie ihr seht das Ende  der  $FEFE  und
  81. der  Anfang der 0000000. Nun startet mit J: wenn ihr ein D Anfang eingebt,
  82. werdet ihr feststellen, daß die Bytes gelöscht wurden (und nun  als  ORI.B
  83. #$0,d0 interpretiert werden). Weiters könnt ihr es mit M START überprüfen,
  84. und euch wird auch aufgefallen sein, daß die Adresse in a0 gleich  der  in
  85. a1  ist.  JETZT  WERDE  ICH  EUCH  EINE  SEHR  NETTE  UTILITY  DES  ASMONE
  86. BEIBRINGEN, DIE DAS KONTROLLIEREN EURER PROGRAMME VEREINFACHT: anstatt  A,
  87. probiert   man  AD!!!  Damit,  nach  dem  Assemblieren,  startet  ihr  den
  88. DEBUGGER!!! Nun RUHE UND KÜHLEN KOPF BEWAHREN: Euch wird  das  Listing  so
  89. erscheinen, wie ihr es erstellt habt, und auf der rechten Seite werdet ihr
  90. alle Register unter Kontrolle haben, die in einer Kolonne erscheinen:  d0,
  91. d1, d2,...,a0, a2, a3,...etc. Die erste Zeile des Listings, in diesem Fall
  92. das LEA START,a0, wird in Negativ erscheinen, also  ein  Balken  wird  sie
  93. hervorheben.  Das  zeigt  an,  auf  was  für  einer  Linie  wir uns gerade
  94. befinden. Nun könnt ihr die Ausführung  des  Programmes  Zeile  für  Zeile
  95. nachvollziehen  und  mitverfolgen,  und gleichzeitig kontrollieren, was in
  96. den Registern passiert!!!  In  der  letzten  Zeile  unten  sieht  man  die
  97. disassemblierten Befehle wie mit dem D-Befehl, einen nach dem anderen, mit
  98. seiner Adresse zu seiner linken, gefolgt von der Instruktion in BYTE-Form,
  99. gefolgt  von  der  Instruktion  als BEFEHL (z.B. CLR.L (a0)+, das in Bytes
  100. $4298 ist). Um die Befehle nacheinander "abzuspielen", um  sich  also  zum
  101. nächsten zu begeben, drückt die Pfeil-nach-Rechts-Taste. Ihr werdet sehen,
  102. wie nach der Abarbeitung des ersten Befehles in a0 die Adresse  von  START
  103. kommt,  während  nach  dem zweiten in a1 die Adresse von THEEND erscheint.
  104. Einmal in der Schleife eingetreten, werdet ihr sehen, wie sich die Adresse
  105. in   a0   jedesmal   um  4  hochschraubt,  und  wie  jedesmal  zu  CLELOOP
  106. zurückgesprungen wird, wenn a0 noch nicht gleich a1 ist (BNE.S). Einmal am
  107. RTS  angekommen,  ist  alles vorbei, oder wenn ihr wollt auch früher, wenn
  108. ihr ESC drückt. Wenn ihr mitzählt, wie  oft  das  CLR.L  (a0)+  ausgeführt
  109. wird,  werdet  ihr 10 zählen. Das stimmt, denn wenn jedesmal 4 Bytes (=ein
  110. Long) gelöscht werden, dann ist mit 4*10=40 alles  sauber.  Probiert,  das
  111. CLR.L (a0)+ mit einem CLR.W (a0)+ zu ersetzen, ihr werdet feststellen, daß
  112. 20 Durchgänge notwendig sind (2*20=40...), um ans Ende zu kommen,  und  a0
  113. wird  jedesmal  um  2  hochgezählt. Mit einem CLR.B (a0)+ werden 40 Zyklen
  114. gebraucht, und a0 wird jedesmal um eins erhöht. Um alles  noch  klarer  zu
  115. bekommen,  ladet  die  Listings, die bisher behandelt wurden, nochmal, und
  116. checkt sie mit AD durch. Bemerkung: der  DEBUGGER  kann  nicht  bei  allen
  117. Programmen   angewandt   werden,   denn  solche,  die  das  Betriebssystem
  118. abschalten, schalten auch den Debugger ab!
  119.  
  120. Um euch zu beweisen, daß wirklich alle Bytes zwischen START:  und  THEEND:
  121. gelöscht  werden,  ob  es  nun  40,  200  oder  mehr  sind,  testet  diese
  122. Abänderung:
  123.  
  124. START:
  125.     dcb.b    80,$fe    ; Gib hier 80 Bytes "$fe" in den Speicher
  126.  
  127. THEEND:            ; Dieses LAbel markiert das Ende der 80 Bytes
  128.  
  129. Wenn ihr die gleichen Durchgänge mit AD macht, werdet ihr feststellen, daß
  130. genau  doppelt soviele Durchgänge nötig sind, und daß die Distanz zwischen
  131. START: und  THEEND:  sich  auch  verdoppelt  hat.  Um  sich  das  bildlich
  132. vorzustellen,  stellt  euch  vor,  das  Programm  sei eine Straße, bei der
  133. START: die Hausnummer 10 hat, und THEEND 40 Bytes weit weg liegt, also auf
  134. Hausnummer  50  (10+40=50). Wenn nun der Bewohner von START: seinen Freund
  135. von THEEND: besuchen will, muß er 40 Schritte  machen,  jedes  einen  Byte
  136. lang.  Wenn  START: aber immer 10 darstellt, die Entfernung jetzt statt 40
  137. 80 Byte geworden ist, dann wird sich der Freund auf Adresse  90  befinden,
  138. und START: muß 80 Schritte zu einem Byte machen, um ihn zu treffen.
  139.  
  140.