Posts Tagged ‘programowanie’

PostHeaderIcon Liczby Armstronga

Liczbą Armstronga (inaczej narcystyczną) nazywamy n-cyfrową liczbę naturalną, która jest sumą swoich cyfr podniesionych do potęgi n. Udowodniono, że takich liczb jest 88, przy czym najwyższa z nich ma 39 cyfr. Oczywiście algorytm do obliczania tak dużych liczb nie może operować na powszechnie znanych typach danych – przykładowo liczba typu int w języku C może być maksymalnie równa w przybliżeniu 4 miliardy. Aby poradzić sobie z tym problemem musimy stworzyć własny typ danych i zdefiniować dla niego podstawowe operacje (dla naszych celów przydadzą się jedynie operacje dodawania i mnożenia).

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

#define MAX_DIGTS 40
#define MAX_DIGTS2 (MAX_DIGTS+1)*(MAX_DIGTS+1)


uint_fast32_t powtabl[10*MAX_DIGTS2];
uint_fast32_t tmp[MAX_DIGTS];
uint_fast32_t maxnumber[MAX_DIGTS];
uint_fast32_t liczba[MAX_DIGTS];
uint_fast32_t digt;
uint_fast32_t ifrom[10], ilosc[10];
uint_fast32_t minnumber[11*MAX_DIGTS];
uint_fast32_t tmpx;
uint_fast32_t digtscnt[10];
uint_fast32_t flag = 1;
uint_fast32_t iend;
uint_fast32_t found = 0;
uint_fast32_t w;


// aa < bb
inline
//static
void addl(uint_fast32_t* c, const uint_fast32_t* a, const uint_fast32_t* b)
{
    uint_fast32_t i;

    for (i = 1; i <= *a; i++)
        c[i] = a[i] + b[i];

    for (i = *a+1; i <= *b; i++)
        c[i] = b[i];

    for (i = 1; i < *a; i++)
        if (c[i] > 9)
        {
            c[i] += -10;
            ++c[i+1];
        }

    for (i = *a; i < *b; i++)
    {
        if (c[i] > 9)
        {
            c[i] += -10;
            ++c[i+1];
        }
        else
        {
            *c = *b;
            return;
        }
    }

    if (c[*b] > 9)
    {
        c[*b] += -10;
        *c = *b+1;
        c[*c] = 1;
        return;
    }
    *c = *b;
}

inline
//static
void muli(uint_fast32_t *c, const uint_fast32_t *b, const uint_fast32_t a)
{
    uint_fast32_t i, tmpc;

    for (i = 1; i <= *b; i++)
        c[i] = b[i] * a;

    i = 0;
    while (++i < *b)
        if (c[i] > 9)
        {
            tmpc = 0.1*c[i];
            c[i+1] += tmpc;
            c[i] += -(tmpc << 3);
            c[i] += -(tmpc << 1);
        }

    if (c[i] > 9)
    {
        c[i+1] = 0.1*c[i];
        c[i] += -(c[i+1] << 3);
        c[i] += -(c[i+1] << 1);
        if (c[++i] > 9)
        {
            c[i+1] = 0.1*c[i];
            c[i] += -(c[i+1] << 3);
            c[i] += -(c[i+1] << 1);    // dwa zera z przodu
        }
    }

    *c = i;
}


//inline
static
uint_fast32_t *powll(uint_fast32_t a, uint_fast32_t b)
{
    uint_fast32_t tmp[MAX_DIGTS], i, *xx;

    if (powtabl[a*MAX_DIGTS2+b*(MAX_DIGTS)] == 0)
    {
        xx = powll(a,b-1);
        for (i = 0; i < MAX_DIGTS; i++)
            *(tmp+i) = *(xx+i);
           
        while (tmp[*tmp] == 0 && *tmp >= 2)
            (*tmp)--;
           
        muli(tmp, tmp, a);
       
        for (i = 0; i < MAX_DIGTS; i++)
            powtabl[a*MAX_DIGTS2+b*(MAX_DIGTS+1)+i] = tmp[i];
           
        while (powtabl[a*MAX_DIGTS2+b*(MAX_DIGTS+1)+powtabl[a*MAX_DIGTS2+b*(MAX_DIGTS+1)]] == 0 &&
                powtabl[a*MAX_DIGTS2+b*(MAX_DIGTS+1)] >= 2)
            powtabl[a*MAX_DIGTS2+b*(MAX_DIGTS+1)]--;
    }
    return powtabl+a*MAX_DIGTS2+b*(MAX_DIGTS+1);
}


int main()
{
    int_fast32_t i, ito[10], it[10];
    uint_fast32_t n, j;

    memset(powtabl, 0, 10*MAX_DIGTS2*sizeof(uint_fast32_t));

    for (i = 9; i >= 0; i--)
    {
        //liczymy pierwsza i zerowa potege
        powtabl[i*MAX_DIGTS2] = 1;
        powtabl[i*MAX_DIGTS2+1] = 1;
        powtabl[i*MAX_DIGTS2+MAX_DIGTS+1] = 1;
        powtabl[i*MAX_DIGTS2+MAX_DIGTS+2] = i;
        ito[i] = 0;
    }
   
    //liczymy pozostale potegi (1 do 39)
    for (i = 1; i < 10; i++)
        powll(i,MAX_DIGTS-1);

    minnumber[10*(MAX_DIGTS+1)] = 1;
    minnumber[10*(MAX_DIGTS+2)] = 0;

    for (n = 1; n <= MAX_DIGTS; n++)
    {
        digt = 9;
        ifrom[9] = it[9] = n;

        while (digt < 10)
            if (it[digt] >= ito[digt])
            {
                if (digt == 1)
                {
                    liczba[0] = liczba[1] = 1;

                    muli(liczba, liczba, *(it+1));
                    if (*liczba >= *(minnumber+2*(MAX_DIGTS+1)))
                        addl(tmp, minnumber+2*(MAX_DIGTS+1), liczba);
                    else
                        addl(tmp, liczba, minnumber+2*(MAX_DIGTS+1));
                    memcpy(liczba, tmp, (n+1)*sizeof(uint_fast32_t));
                    while (liczba[*liczba] == 0 && *liczba > 1)
                    {
                        (*liczba)--;
                    }

                    if (*liczba == n)
                    {
                        //memset(ilosc, 0, 10*sizeof(int_fast32_t));
                        for (i = 9; i >= 0; i--)
                            *(ilosc+i) = 0;
                        for (i = *liczba; i > 0; i--)
                            ilosc[liczba[i]]++;
                        if (((ilosc[1] - it[1]) | (ilosc[2] - it[2]) | (ilosc[3] - it[3]) | (ilosc[4] - it[4]) | (ilosc[5] - it[5]) | (ilosc[6] - it[6]) | (ilosc[7] - it[7]) | (ilosc[8] - it[8]) | (ilosc[9] - it[9])) == 0)
                        {
                            printf("%d/89: ", ++found);
                            for (i = *liczba; i > 0; i--) printf("%d", liczba[i]);
                            printf(" (%d)\n", n);
                        }
                    }
                    it[digt]--;
                    continue;
                }

                else if (digt != 9)
                {
                    muli(tmp, powtabl+digt*MAX_DIGTS2+n*(MAX_DIGTS+1), it[digt]);
                    if (*(minnumber+(MAX_DIGTS+1)*(digt+1)) >= *tmp)
                        addl(minnumber+(MAX_DIGTS+1)*digt, tmp, minnumber+(MAX_DIGTS+1)*(digt+1));
                    else addl(minnumber+(MAX_DIGTS+1)*digt, minnumber+(MAX_DIGTS+1)*(digt+1), tmp);
                }

                else muli(minnumber+(MAX_DIGTS+1)*9, powtabl+9*MAX_DIGTS2+n*(MAX_DIGTS+1), it[9]);

                ifrom[digt-1] = ifrom[digt]-it[digt];
                muli(maxnumber, powtabl+(digt-1)*MAX_DIGTS2+n*(MAX_DIGTS+1), ifrom[digt-1]);

                tmpx = (MAX_DIGTS+1)*digt;
                if (*maxnumber < *(minnumber+tmpx))
                    addl(maxnumber, maxnumber, minnumber+tmpx);
                else
                    addl(maxnumber, minnumber+tmpx, maxnumber);

                // ilosc najbardziej znaczacych, wspolnych cyfr
                if (*maxnumber < n)
                {
                    --it[++digt];
                }
                else if (minnumber[tmpx] > n)
                    --it[digt];
                else
                {
                    j = n;
                    while (minnumber[tmpx+j] == maxnumber[j] && j > 0)
                    {
                        --j;
                    }
                    iend = minnumber[tmpx];

                    for (i = 9; i >= 0; i--)
                        digtscnt[i] = 0;

                    for (i = n-j; i > 0; i--)
                        ++digtscnt[minnumber[tmpx+i+iend-n+j]];
                       
                    for (i = 9; i >= digt; i--)
                        flag = flag & (digtscnt[i] <= it[i]);

                    for (i = digt-1; i > 0; i--)
                        ito[i] = digtscnt[i];

                    if (flag != 1)
                    {
                        --it[digt];
                        flag = 1;
                    }
                    else
                    {
                        --digt;
                        it[digt] = ifrom[digt];
                    }
                }
            }
            else
            {
                --it[++digt];
            }
    }

    return 0;
}

Kod zapisujemy pod nazwą big-number.c i kompilujemy pod Linuksem poleceniem:

gcc -Wall -O2 -ffast-math -funroll-loops -fomit-frame-pointer big-number.c -o numb

Możemy oczywiście stworzyć plik Makefile, aby zaoszczędzić sobie wpisywania lub pamiętania wszystkich flag przy następnych kompilacjach. Ma on postać:

numb: big-number.c
gcc -Wall -O2 -ffast-math -funroll-loops -fomit-frame-pointer big-number.c -o numb

PostHeaderIcon Witam na stronie

Kliknij w interesujący Cię temat.

PostHeaderIcon Assembler

Proste programy napisane w assemblerze MASM

PostHeaderIcon Operacje na macierzach

Program realizujący jednocześnie dodawanie i mnożenie dwóch macierzy. Dane – czyli dwie macierze – znajduja się w pliku wejściowym o nazwie podanej przy wywołaniu. Wynik działania programu jest umieszczany automatycznie w pliku wyjściowym o nazwie również podanej przy wywołaniu.
Liczby występujące w macierzach powinny być z zakresu: 0-100
Ogólna postać macierzy dla m kolumn i n wierszy:

m n
A11 A12 A13 …… A1m
A21 A22 A23 …… A2m
A31 A32 A33 …… A3m
… … … …… …
An1 An2 An3 …… Anm

Przykłady zapisu macierzy:

3 4
1 3 4
4 5 2
1 1 1
8 9 9

5 5
01 22 33 12 43
92 23 43 21 12
22 22 22 22 22
66 66 66 66 66
13 56 56 21 32

Przykład wywołania Programu:

program2 dane1.wej dane1.wyj

; by Pawel Konieczny
; ver 1.0
.186
;................. Segment danych .................
dane1 segment
f_in    db    10 dup (?),'0'     ; nazwa pliku wejsciowego
f_out    db    10 dup (?),'0'     ; nazwa pliku wyjsciowego
buf_in    db    1000 dup ('$')
buf_out    db    1000 dup ('$')
error_1   db    'Niewlasciwy parametr$'
error_2   db    'Nie mozna czytac z pliku wejsciowego$'
error_3   db    'Nie mozna zamknac pliku$'
error_4   db    'Nie mozna znalezc pliku wejsciowego$'
error_5   db    'Nie mozna stworzyc pliku wyjsciowego$'
error_6   db    'Nie mozna zapisac do pliku wyjsciowego$'
kom_1     db    'Nie mozna dodac macierzy. $'
kom_2     db    'Dodawanie macierzy ...$'
kom_3    db    'Nie mozna pomnozyc macierzy. $'
kom_4     db      'Mnozenie macierzy ...$'
uchwyt    dw    ?    ; wskaznij do pliku wejsciowego
uchwyt2   dw    ?    ; wskaznik do pliku wyjsciowego
x1        dw    ?    ; pierwsza wspolrzedna pierwszej macierzy
x2        dw    ?    ; druga wspolrzedna pierwszej macierzy
x3        dw    ?    ; pierwsza wspolrzedna drugiej macierzy
x4        dw    ?    ; druga wspolrzedna drugiej macierzy
sk        dw    ?       ; skok do danych o wspolrzednych w drugiej macierzy
sk1    dw    ?    ; skok do nastepnego rzedu w macierzy 1
sk2    dw    ?       ; skok do nastepnej liczby w kolumnie w macierzy 2
w1        dw    ?       ; wskazuje na elementy pierwszej macierzy
w2    dw    ?       ; wskazuje na elementy drugiej macierzy
norma1    dw    ?
norma2    dw    ?
ok2    dw    ?
licz1     dw    ?
licz2     dw    ?
licz3    dw    ?
dane1 ends
;..................................................

ASSUME cs:code1, ds:dane1, ss:stos1

;................. Segment kodu ...................
code1 segment
start:
mov ax,seg dane1
mov ds,ax

; Na poczatku zapisujemy rozmiary pierwszej macierzy do zmiennych x1, x2.
; Dalej, na podstawie znajomosci tych danych wykonywany jest skok do
; miejsca w pliku, gdzie przechowywane sa rozmiary drugiej macierzy x3, x4

call CzyParam
inc bx                  ; przechodzimy przez spacje
xor di,di
call CzytPar1
next1:
cmp di,0
je Komunikat5         ; gdy nie ma pierwszego parametru
xor di,di
call CzytPar2
next2:
cmp di,0
je Komunikat6         ; gdy nie ma drugiego parametru
call OtwPlikWej
call CzytPlikWej
call StwPlikWyj
call OtwPlikWyj

; wczytywanie zmiennych

mov di,0           ; di = 0 wskazuje na pierwsza pozycje w pliku
call Czytaj        ; pierwsza pozycje z pliku ...
mov [x1],ax          ; ... zapisz do x1

add di,3           ; di = 3 wskazuje na czwarta pozycje w pliku, ...
call Czytaj        ; ... ktora zpisujemy ...
mov [x2],ax          ; ... do x2

call Skok          ; obliczamy, gdzie znajduja sie w pliku dane drugiej macierzy

mov di,[sk]
call Czytaj        ; pierwsza wspolrzedna 2. macierzy ...
mov [x3],ax          ; ... zapisz do x3 ...

add di,3           ; ... druga, odlegla o 3 bajty od pierwszej ...
call Czytaj        ; ... odczytaj ...
mov [x4],ax          ; ... i zapisz do x4

; sprawdzanie poprawnosci romiaru macierzy w przypadku ich dodawania

mov ax,[x1]
cmp ax,[x3]
jne Kom1     ; gdy x1 != x3 skocz do mnozenia
mov ax,[x2]
cmp ax,[x4]
jne Kom1     ; gdy x2 != x4 skocz do mnozenia

; dodawanie macierzy

call Kom2
mov [w1],7           ; zaczynamy wczytywanie od siodmego bajtu, ...
mov ax,[x2]          ; ... bo tu jest pierwsza wspolrzedna
mov [licz2],ax       ; licz2 = x2

; -------------------------------
for1:
mov ax,[x1]
mov [licz1],ax      ; licz1 = x1
for2:
mov di,[w1]
call Czytaj        ; czytaj pierwszy skladnik z miejsca 'di' i umiesc w ax
push ax            ; poloz na stosie pierwszy skladnik

add di,[sk]          ; di = w1 + sk
call Czytaj        ; czytaj drugi skladnik z miejsca 'di' i umiesc w ax

pop bx             ; sciagnij ze stosu pierwszy skladnik
add ax,bx          ; dodaj do drugiego
call Zapisz        ; czytaj liczbe z ax i zapisz ja do pliku
call Spacja

add [w1],3         ; w1 = w1 + 3, przejscie przez spacje
dec [licz1]
cmp [licz1],0
jne for2
call Nwln

inc [w1]            ; przejscie do nowej linii
dec [licz2]
cmp [licz2],0
jne for1
; -------------------------------
call Nwln

; sprawdzanie poprawnosci romiaru macierzy w przypadku ich mnozenia

mnozenie:
mov ax,[x1]
cmp ax,[x4]
jne Kom3     ; gdy x1 != x4 wyjdz z programu

; mnozenie macierzy

call Kom4
call Skok1
call Skok2

mov ax,[x1]          ;         .....
mov [licz1],ax       ;      licz1 = x1
mov ax,[x2]          ;         ....
mov [licz2],ax       ;         ....
mov ax,[x3]
mov [licz3],ax       ;   licz3 = licz2 = x2

mov [w1],7           ; zaczynamy wczytywanie od siodmego bajtu, bo tu jest pierwsza wspolrzedna
mov [norma1],7       ; norma1 = w1 = 7
mov ax,[sk]
add ax,7
mov [w2],ax          ; w2 = sk + 7
mov [norma2],ax
mov [ok2],ax         ; ok2 = norma2 = w2 = sk + 7
xor cx,cx

; -------------------------------
for4:                ; jedno przejscie w1 x1 razy
mov di,[w1]
call Czytaj        ; czytaj pierwszy skladnik z miejsca 'di' i umiesc w ax
push ax            ; poloz na stosie pierwszy skladnik
mov di,[w2]        ;
call Czytaj        ; czytaj drugi skladnik z miejsca 'di' i umiesc w ax
pop bx             ; sciagnij ze stosu pierwszy skladnik
mul bx             ; pomnoz ax przez bx
add cx,ax          ; dodaj do sumy 'cx'
add [w1],3           ; zwieksz w1 o 3, przejscie przez spacje
mov ax,[sk2]
add [w2],ax          ; zwieksz w2 o 'sk2'
dec [licz1]
cmp [licz1],0
jne for4             ; powtarzaj x1 razy
mov ax,cx
call Zapisz        ; zapisz liczbe
call Spacja        ; wstaw spacje
xor cx,cx          ; zerowanie sumy
mov ax,[norma1]
mov [w1],ax          ; wroc do poczatku linii
add [norma2],3       ; przejdz przez spacje do kolejnego rzedu drugiej macierzy
mov ax,[norma2]      ;      .......
mov [w2],ax          ;    w2 = norma2
mov ax,[x1]          ;       .....
mov [licz1],ax       ;    licz1 = x1
dec [licz3]
cmp [licz3],0
jne for4
call Nwln
xor cx,cx            ; zerowanie sumy
mov ax,[sk1]
add [norma1],ax      ; przejscie do nowej linii
mov ax,[norma1]      ;       ......
mov [w1],ax          ;     w1 = norma1
mov ax,[ok2]         ; wroc do pierwszego rzedu macierzy drugiej
mov [norma2],ax      ;      .......
mov [w2],ax          ;     w2 = norma2 = ok2
mov ax,[x1]          ;         ....
mov [licz1],ax       ;      licz2 = x2
mov ax,[x3]
mov [licz3],ax
dec [licz2]
cmp [licz2],0
jne for4
; ---------------------------------

call ZamkPlikWej
call ZamkPlikWyj
call Koniec

; =========================   Procedury   ===============================

CzyParam PROC               ; sprawdzenie czy sa parametry
mov bx,80h           ; sprawdzamy czy istnieje ...
mov cl,byte ptr es:[bx]       ; ... jakikolwiek parametr
cmp cl,0             ; jesli nie ma zadnego parametru, to ...
je Komunikat1        ; ... wypisz blad
ret
CzyParam ENDP

CzytPar1 PROC               ; czytanie pierwszego parametru
inc bx               ; parametry zaczynaja sie od 82h
mov dl,byte ptr es:[bx]       ; wczytujemy znak do dl
cmp dl,' '
je next1
mov f_in[di],dl      ; a nastepnie do bufora, ktory bedzie nazwa pliku
inc di
jmp CzytPar1
ret
CzytPar1 ENDP

CzytPar2 PROC               ; czytanie drugiego parametru
inc bx
mov dl,byte ptr es:[bx]       ; wczytujemy go do dl
cmp dl,0dh
je next2
mov f_out[di],dl     ; a nastepnie do bufora ,ktory bedzie nazwa pliku
inc di
jmp CzytPar2
ret
CzytPar2 ENDP

OtwPlikWej PROC             ; otwieranie pliku wejsciowego
mov ax,3d00h         ; otwieramy plik do odczytu
lea dx,[f_in]
int 21h
jc Komunikat4
mov [uchwyt],ax
ret
OtwPlikWej ENDP

CzytPlikWej PROC            ; czytanie z pliku wejsciowego do 'buf_in'
mov ax,3f00h
mov bx,[uchwyt]
mov cx,300         ; czytamy po 1 bajcie
lea dx,[buf_in]       ; do bufora
int 21h
jc Komunikat2
ret
CzytPlikWej ENDP

StwPlikWyj PROC             ; utworzenie pliku wyjsciowego
mov ax,3c00h        ; numer funkcji - utworzenie
xor cx,cx
lea dx,[f_out]    ; adres nazwy pliku
int 21h
jc Komunikat5
ret
StwPlikWyj ENDP

OtwPlikWyj PROC             ; otwieranie pliku wyjsciowego
mov ax,3d02h         ; otwieramy plik do zapisu
lea dx,[f_out]
int 21h
jc Komunikat4
mov [uchwyt2],ax
ret
OtwPlikWyj ENDP

Czytaj PROC                 ; czytanie z 'buf_in' i zapisywanie do 'ax'
mov al,[buf_in+di]  ; adres zmiennej ze stringiem
xor ah,ah
sub al,30h            ; ascii -&gt; cyfra
mov bx,ax
shl ax,3                ; mnozenie przez 10
shl bx,1
add ax,bx             ; tu juz jest liczba
push ax
mov al,[buf_in+di+1]
xor ah,ah
sub al,30h
pop bx
add bx,ax
mov ax,bx
ret
Czytaj ENDP

Skok PROC                   ; obliczanie skoku do danych drugiej macierzy
mov ax,[x1]
add ax,[x1]
add ax,[x1]
inc ax
mul [x2]
add ax,9             ; ax = (3 * x1 + 1) * x2 + 9
mov [sk],ax            ; dlugosc skoku
ret
Skok ENDP

Skok1 PROC                  ; obliczanie skoku do nowej linii w pierwszej macierzy
mov ax,[x1]
add ax,[x1]
add ax,[x1]
inc ax                   ; ax = (3 * x1 + 1)
mov [sk1],ax               ; dlugosc skoku
ret
Skok1 ENDP

Skok2 PROC                  ; obliczanie skoku do kolejnej liczby w kolumnie w drugiej macierzy
mov ax,[x3]
add ax,[x3]
add ax,[x3]
inc ax                   ; ax = (3 * x3 + 1)
mov [sk2],ax               ; dlugosc skoku
ret
Skok2 ENDP

Zapisz PROC                 ; zapisz liczbe do 'buf_out', pozniej do pliku
mov bl,10
div bl               ; al = al / 10

mov ch,ah
xor ah,ah
div bl               ; al = al / 10    -    pierwsza cyfra
mov cl,ah            ; w 'cl' jest druga cyfra

add al,'0'
mov [buf_out],al

add cl,'0'
mov [buf_out+1],cl

add ch,'0'
mov [buf_out+2],ch

mov ax,4000h
mov bx,[uchwyt2]
mov cx,3
lea dx,[buf_out]
int 21h
jc Komunikat6
ret
Zapisz ENDP

Spacja PROC                 ; umieszcza znak spacji w pliku
mov [buf_out],' '
mov ax,4000h
mov bx,[uchwyt2]
mov cx,1
lea dx,[buf_out]
int 21h
jc Komunikat6
ret
Spacja ENDP

Nwln PROC                   ; umieszcza znak przejscia do nowej linii w pliku
mov buf_out[0],13
mov buf_out[1],10
mov ax,4000h
mov bx,[uchwyt2]
mov cx,2
lea dx,[buf_out]
int 21h
jc Komunikat6
ret
Nwln ENDP

ZamkPlikWej PROC            ; zamykanie pliku wejsciowego
mov ax,3e00h
mov bx,[uchwyt]
int 21h
jc Komunikat4
ret
ZamkPlikWej ENDP

ZamkPlikWyj PROC            ; zamykanie pliku wyjsciowego
mov ax,3e00h
mov bx,[uchwyt2]
int 21h
jc Komunikat2
ret
ZamkPlikWyj ENDP

Koniec PROC                 ; powrot do systemu
mov ax,4C01h
int 21h
Koniec ENDP

Komunikat1:
lea dx,error_1         ; mov dx,offset error
call sh_err

Komunikat2:
lea dx,error_2         ; mov dx,offset error
call sh_err

Komunikat3:
lea dx,error_3         ; mov dx,offset error
call sh_err

Komunikat4:
lea dx,error_4         ; mov dx,offset error
call sh_err

Komunikat5:
lea dx,error_5         ; mov dx,offset error
call sh_err

Komunikat6:
lea dx,error_6         ; mov dx,offset error
call sh_err

Kom1:
lea dx,kom_1         ; mov dx,offset error
mov ah,9h
int 21h
jmp mnozenie

Kom2:
lea dx,kom_2         ; mov dx,offset error
mov ah,9h
int 21h
ret

Kom3:
lea dx,kom_3         ; mov dx,offset error
mov ah,9h
int 21h
call Koniec

Kom4:
lea dx,kom_4         ; mov dx,offset error
mov ah,9h
int 21h
ret

sh_err:                   ; wypisuje na ekran bledy
mov ah,9h
int 21h
call Koniec

code1 ends
;..................................................

;................ Segment stosu ...................
stos1 segment STACK
dw 3000 dup(?)
stos1 ends
;..................................................

END start