MILC logo

IndexVorigeVolgendeLeeg

Vermenigvuldigen in ML
Genic Clubguide, 00-00-00


    
               VERMENIGVULDIGEN IN MACHINETAAL

Onlangs kregen wij van  een  inventieve  lezer  een  routine
toegestuurd om te  vermenigvuldigen  in  machinetaal.  Niets
bijzonders zult U zeggen. Dat is het  ook  niet  echt,  maar
omdat er in machinetaal geen instrukties voor  zijn  is  het
toch wel handig. Bovendien schept  het  de  mogelijkheid  om
eens iets meer over machinetaal uit de doeken te doen.

Bij de Z80 werken we met binaire getallen,  uitsluitend  met
nullen en enen dus. Laten we eerst eens kijken hoe we binair
kunnen vermenigvuldigen:

Vb. 15 * 3 = ?     =>      00000011 (3)
                           00001111 (15)  *
                           ----------------
                           00000011 (3)     3 * 2 tot de 0e
                           00000110 (6)     3 * 2 tot de 1e
                           00001100 (12)    3 * 2 tot de 2e
                           00011000 (24)    3 * 2 tot de 3e
                           ----------------
                             101101 (45)

We  laten  dit  binair  zien  omdat  zo  in  de  Z80   wordt
vermenigvuldigd. Allereerst zetten we een programma op.  Wat
moet er allemaal gebeuren in het  programma,  hieronder  een
eerste opzet:

- De getallen waarmee gerekend gaat  worden,  moeten  worden
  ingelezen.
- Er moet gekeken worden of  het  getal  waar  we  mee  gaan
  vermenigvuldigen een 0 of een 1 is.
  - Is het een 0 dan kunnen we het geheel opschuiven.
  - Is het een 1 dan moeten we vermenigvuldigen.
- We moeten zorgen dat het programma 8 keer  vermenigvuldigd
  en dan terug keert naar BASIC.

Lijkt simpel, het valt ook best wel mee. Wat we niet  moeten
vergeten is dat er elke keer als we het volgende getal nemen
het 10 * zoveel is en er dus een 0 achter het antwoord  moet
komen.

Vb.  4                            1
    22 *                         11 *
    --                           --
     8                            1
    80  ( Met een 0 erachter )   10  ( Met een 0 erachter )
    -- +                         -- +
    88                           11

Dus we zullen elke keer als we het volgende getal  nemen  om
mee te vermenigvuldigen een extra nul moeten toevoegen.

Nu we ongeveer het programma in het hoofd hebben,  moet  het
natuurlijk nog wel in machinetaal komen te  staan.  Alvorens
dat te  doen  kiezen  we  voor  een  tweede  tussenfase.  We
proberen de routine nu  voor  zover  mogelijk  in  BASIC  te
plaatsen. We gaan uit van A*B=O waarbij A  op  adres  &HA000
staat, B op adres &HA001 staat en O op &Ha002 en &Ha003 komt
te staan.

10  B=PEEK (&HA000)
20  AFTEL=8
30  A=PEEK (&HA001)
40  D=0
50  O=0
60  REM Routine A **************
70  C$=MID$(BIN$(B),AFTEL,1):C=VAL(C$)
80  IF C=0 THEN GOTO 100
90  O=O+A
100 REM Routine B **************
110 A$=BIN$(A)+"0":A=VAL(A$)
120 AFTEL=AFTEL-1
130 IF AFTEL<>0 THEN 60
140 ' In machinetaal wordt nu d.m.v. een soort poke de
      oplossing (O) op &HA002 en &HA003 gezet.
150 end

In regel 70  wordt  gekeken  of  het  eerst  volgende  getal
waarmee we gaan vermenigvuldigen 0 of 1  is.

In regel 110 wordt er een 0 achter  getal  A  geplaatst.  In
machinetaal is dit echter zo eenvoudig niet. Hier werkt  men
in getallen-paren van 8 bits. Dus daar moet het  getal  naar
links worden opgeschoven, de overgeblevene bewaardt,  en  er
een 0 achter geplaatst.

Vb.00000000 10111011  => Naar links schuiven
   00000000 0111011   => 0 erbij
   00000000 01110110  => Overgeblevene bit in volgend byte.
   00000001 01110110  =>

Voor het maken  van  het  machinetaal  programma  moeten  we
alleen nog de juiste instrukties weten. Laten we er een paar
bespreken:

SRL < variabele > ( In machinetaal:register )

Stel we  geven  de  opdracht  SRL  D,  dan  gebeurt  er  het
volgende. Net  als  hierboven  beschreven  wordt  het  getal
verschoven, alleen nu naar rechts , het overgeblevene  getal
komt in de Carry-flag te staan (Ook een soort variabele)

Vb.  D=10111011  => SRL D =>   D=01011101
     Carry=0     =>       =>   Carry=1

SLA < variabele > ( In machinetaal:register )

Zelfde als de vorige instruktie alleen dan naar links.

Vb.  D=10111011  => SLA D =>   D=01110110
     Carry=0     =>       =>   Carry=1

RL < variabele > ( In machinetaal:register )

Zelfde als SLA, alleen komt nu de inhoud van de  carry  flag
er vooraan bij.

Vb.  D=10111011  => RL D  =>   D=01110110
     Carry=0     =>       =>   Carry=1

Vb.  D=00111011  => RL D  =>   D=01110111
     Carry=1     =>       =>   Carry=0

Verder is ADD optellen in machinetaal, DEC is  aftrekken  en
ld is poke. Bij dit laatste moeten we nog wat opmerken:

Vb. ld BC,(0A000H) - H=Hexadecimaal
                     B=0 en C=PEEK(A000)

Dan volgt nu  het  machinetaal  programma  in  de  assembler
listing :

1 ld BC,(0A00H)   'Zet getal B in register C
2 ld B,08H        'Zet 8 in register B
3 ld DE,(0A001H)  'Zet getal A in register E
4 ld D,00H        'Zet 0 in register D
5 ld HL,00H       'Maak Carry-flag 0
6 label A:srl C   'Schuif bit in carry
7 jr NC,label B   'If not carry then label B
8 add hl,de       'HL=HL+A
9 label B:sla E   'Schuif A naar links
10 rl D           'Bewaar uitgeschoven bit in D
11 dec B          'Aftel=Aftel-1
12 jr nz,label A  'If aftel<>0 then label A
13 ld (0A002H),HL 'Zet antwoord in &HA002 en &HA003
14 ret            'Terug naar BASIC
15 end

Dit programma kan alleen getallen tot 256 (8 bits) optellen.
Het staat op diskette als VERMENIG.MSX (Te laden vanuit  het
softwaremenu of via FILER.SYS).

Experimenteer er nog maar eens wat  mee,  dit  programma  is
niet echt voor beginners. Ik zal  misschien  volgende  keer,
als er  behoefte  aan  is,  de  cursus  wat  meer  op  echte
beginners richten.

Vragen en/of opmerkingen,

Ronald Egas
De Blauwe Wereld 53
1398 EP Muiden
Tel.02942-3813 (s'avonds + weekends)

    

Index

Vorige

Volgende