czwartek, kwietnia 18, 2013

Potworność ;-) czyli mnożenie w 90 liniach ;-)

Bez zbędnych ceregieli od razu kod ;-)

Q: DAT 0
A: DAT 0
B: DAT 0
Z: DAT 0
MUL: POPA
STA A
POPA
STA B
ZERO
STA R
STA Q
LDA B
LOOP LMUL2
ZERO
PUSHA
RET
LMUL2: LDA Q
INC
STA Q
LDA R
PUSHA
LDA A
PUSHA
CALL ADD
POPA
STA R
LDA Q
PUSHA
LDA B
PUSHA
CALL EQ
POPA
LOOP MULEND
INC
LOOP LMUL2
MULEND: LDA R
PUSHA
RET
X: DAT 0
Y: DAT 0
Z: DAT 0
ADD: POPA
STA X
POPA
STA Y
L1: LDA Y
LOOP L2
INC
LOOP L5
L2: ZERO
STA Z
L4: LDA Z
INC
STA Z
PUSHA
LDA X
INC
STA X
LDA Y
PUSHA
CALL EQ
POPA
LOOP L5
INC
LOOP L4
L5: LDA X
PUSHA
RET
X1: DAT 0
X2: DAT 0
EQ: POPA
STA X1
POPA
STA X2
LL1: LDA X1
INC
STA X1
LDA X2
INC
STA X2
LOOP LL1
LDA X1
LOOP NON_EQ
ZERO
INC
PUSHA
RET
NON_EQ: ZERO
PUSHA
RET

Do jego wykonania najlepiej użyć opisanej w poprzednim poście maszyny wirtualnej ;-)
UWAGA! Przed uruchomieniem dobrze jest wstawić 2 wartości na stos ;-)
Nie należy przesadzać, bo jednak to nie jest zbyt optymalna maszyna ;-) Wyniki są podawane na stosie, jest to (A*B) mod 16 ale taki już urok mojej maszyny ;-)

Jak to działa?
A prosto :-) mnożenie jest zastąpione przez serię dodawań :-)
2*3 to nic innego jak 2+2+2, a 4*2 to 4+4. Czyli w MUL mamy dodawanie pierwszego operandu tyle razy ile wynosi drugi operand.
Dodawanie działa podobnie, pierwszą liczbę zwiększamy aż wykonamy tyle tych zwiększeń ile wynosi drugi operand.
Obie funkcje korzystają z podprogramu EQ, który sprawdza czy dwie liczby są sobie równe. Robi to tak, że dodaje do obu liczb 1 i czeka aż druga z nich będzie równa 0 (czyli przekręci się licznik), wtedy sprawdza czy pierwsza też jest równa 0, jeśli tak to zwraca 1, w przeciwnym przypadku zwraca 0 :-)

Po co to wszystko? A bo można :-)


Podobne postybeta
Jak zrobić dec mając tylko inc? :-)
DEC z INC odpowiedź i mała Maszyna Wirtualna ;-)
Pomnóżmy sobie duże liczby ;-)
Chorowanie jest do bani, czyli wspomnienia z L4... które trwa ;-)
2016 będzie rokiem "nietypowym"