Riešenia cvičných zadaní pred druhou písomkou


Zatiaľ bez najťažšieho príkladu.
V dvoch zadaniach som vlastne omylom nenapísal var, ale polia dĺžky inej než 1, 2 alebo 4 bajty sa aj vtedy prenášajú do ASM procedúr akoby boli var (v rozdaných materiáloch je to napísané len som to na prednáške nehovoril).

type tKarty = array [1..10] of byte;
function vysledokOcka(hrac1,hrac2:tKarty):byte;
// aj ked parametre nie su var ale su to polia viac nez 4-bajtove, preto sa prenasaju do asm procedury adresou
asm
       mov cx,0   // nulovanie cl a ch

  @1:  cmp byte ptr [eax],0  // scitovanie prveho hraca do cl
       je @2
       add cl,[eax]
       inc eax
       jmp @1

  @2:  cmp byte ptr [edx],0 // scitovanie druheho hraca do ch
       je @3
       add ch,[edx]
       inc edx
       jmp @2

  @3:  cmp cl,21   // ak presiahol h1, dame mu 0 (inak nemoze dosiahnut nulu)
       jbe @h1ok
       mov cl,0
  @h1ok:
       cmp ch,21   // ak presiahol h1, dame mu 0 (inak nemoze dosiahnut nulu)
       jbe @h2ok
       mov ch,0
  @h2ok:
       cmp cl,ch   // teraz staci jedno porovnanie
       je @remiza
       jb @h2
       mov al,1
       jmp @kon
  @h2: mov al,2
       jmp @kon
  @remiza:
       mov al,0
  @kon:
end;

type tPole = array [1..10] of byte;
function najpodobnejsie(var p1,p2:tPole):integer;
asm
      push ebx
      push esi
      push edi

      mov esi,1           // index do oboch poli
      mov cl,0            // maximalny pocet zhodnych
      mov edi,1           // vysledok - na zaciatku je nastaveny na 1 (ak su vsetky rozne vo vsetkych bitoch, tak toto bude vysledok)
  @1: mov bl,[eax+esi-1]
      xor bl,[edx+esi-1]  // po xor su tie bity 1 ktore boli rozne
      not bl              // po negovani su tie bity 1 ktore boli rovnake

      mov bh,0            // spocitame jednicky v bl do bh
  @2: shr bl,1
      adc bh,0
      cmp bl,0
      jne @2

      cmp bh,cl          // porovname s doterajsim maximom
      jbe @3             // ak je to menej alebo rovne, tak nic
      mov cl,bh          // ak je viac, tak si zapamatame nove maximum
      mov edi,esi        // a novy vysledok, teda index maxima

  @3: inc esi            // nepouzil som loop lebo by mi nevysli registre
      cmp esi,10
      jbe @1

      mov eax,edi        // vysledok musi byt v eax

      pop edi
      pop esi
      pop ebx
end;

type retazec = array [1..10] of char;  // pre jednoduchost som zmensil rozmer pola, aby sa lepsie testovalo
function jePalyndrom(P:retazec; N:integer):Boolean;
// aj ked parameter P nie je var ale je to pole viac nez 4-bajtove, preto sa prenasa do asm procedury adresou
// predpokladame N>=0
asm
       push esi
       push ebx

       mov ecx,edx
       shr ecx,1           // v ecx je teraz N div 2 a to je pocet opakovani testovacieho cyklu
       jecxz @ok           // ak je pocet opakovani = 0 tak je to palynfrom (teda N bolo 0 alebo 1)
       mov esi,1           // index od zaciatku
 @1:   mov bl,[eax+esi-1]  // vyber do bl prvok zo zaciatku
       cmp bl,[eax+edx-1]  // porovnaj s prvkom z konca
       jne @zle            // ak sa nerovnaju, uz to nie je palyndrom
       inc esi             // posun index od zaciatku
       dec edx             // posun koncovy index
       loop @1
 @ok:  mov al,1
       jmp @kon
 @zle: mov al,0
 @kon:
       pop ebx
       pop esi
end;