223 lines
4.9 KiB
NASM
223 lines
4.9 KiB
NASM
prog START 0
|
|
|
|
.-------------------------------------------
|
|
. MAIN LOOP
|
|
.
|
|
. Psevdo:
|
|
. sp = 0
|
|
. while true:
|
|
. n = readFA()
|
|
. if n == 0: halt
|
|
. acc = 1
|
|
. fact() ; rekurzivno: acc = n!
|
|
. printStdout(acc)
|
|
.-------------------------------------------
|
|
CLEAR A
|
|
STA sp
|
|
|
|
loop JSUB readFA
|
|
COMP #0
|
|
JEQ halt
|
|
|
|
STA n
|
|
LDA #1
|
|
STA acc
|
|
|
|
JSUB fact
|
|
LDA acc
|
|
JSUB printStdout
|
|
|
|
J loop
|
|
|
|
halt J halt
|
|
|
|
.-------------------------------------------
|
|
. readFA
|
|
.
|
|
. Psevdo:
|
|
. B = 0
|
|
. while true:
|
|
. ch = RD(FA)
|
|
. if ch == CR or ch == LF: break
|
|
. digit = ch - '0'
|
|
. B = B * 10 + digit
|
|
. return B
|
|
.-------------------------------------------
|
|
readFA CLEAR B
|
|
LDS #10
|
|
|
|
rd_loopFA RD #0xFA
|
|
COMP #0x0D . CR?
|
|
JEQ rd_doneCR_FA
|
|
COMP #0x0A . LF?
|
|
JEQ rd_doneFA
|
|
|
|
SUB #0x30
|
|
MULR S,B . B = B * 10
|
|
ADDR A,B . B = B + digit
|
|
J rd_loopFA
|
|
|
|
rd_doneCR_FA RD #0xFA . pogoltni LF po CR
|
|
rd_doneFA CLEAR A
|
|
RMO B,A
|
|
RSUB
|
|
|
|
.-------------------------------------------
|
|
. fact
|
|
.
|
|
. Psevdo (globalni n, acc, sklad L):
|
|
. fact():
|
|
. push(L)
|
|
. if n <= 1:
|
|
. pop(L); return
|
|
. acc = acc * n
|
|
. n = n - 1
|
|
. fact()
|
|
. pop(L); return
|
|
.-------------------------------------------
|
|
fact . push L
|
|
LDA sp
|
|
ADD #3
|
|
STA sp
|
|
LDX sp
|
|
STL stackL,X
|
|
|
|
LDA n
|
|
COMP #1
|
|
JGT fact_rec
|
|
|
|
. base case: n <= 1
|
|
LDX sp
|
|
LDL stackL,X
|
|
LDA sp
|
|
SUB #3
|
|
STA sp
|
|
RSUB
|
|
|
|
fact_rec . recursive case: acc *= n; n--; fact()
|
|
|
|
LDB acc
|
|
LDS n
|
|
MULR S,B
|
|
STB acc
|
|
|
|
LDA n
|
|
SUB #1
|
|
STA n
|
|
|
|
JSUB fact
|
|
|
|
. pop L in return to caller
|
|
LDX sp
|
|
LDL stackL,X
|
|
LDA sp
|
|
SUB #3
|
|
STA sp
|
|
RSUB
|
|
|
|
.-------------------------------------------
|
|
. printStdout
|
|
.
|
|
. Psevdo:
|
|
. if A == 0:
|
|
. print "0\n"
|
|
. return
|
|
. ps_val = A
|
|
. ps_len = 0
|
|
. while ps_val > 0:
|
|
. q = ps_val / 10
|
|
. r = ps_val % 10
|
|
. buf[ps_len] = '0' + r
|
|
. ps_len++
|
|
. ps_val = q
|
|
. for i = ps_len-1 .. 0:
|
|
. print buf[i]
|
|
. print "\r\n"
|
|
.-------------------------------------------
|
|
printStdout COMP #0
|
|
JEQ ps_zero
|
|
|
|
STA ps_val
|
|
LDA #0
|
|
STA ps_len
|
|
LDS #10
|
|
LDT #0x30 . '0'
|
|
|
|
ps_div LDA ps_val
|
|
COMP #0
|
|
JEQ ps_divdone
|
|
|
|
RMO A,B
|
|
DIVR S,B . kvocient v B
|
|
RMO B,X . X = kvocient
|
|
|
|
MULR S,B
|
|
SUBR B,A . A = ostanek
|
|
ADDR T,A . A = '0' + ostanek
|
|
STA psdigit
|
|
|
|
LDA ps_len
|
|
STA ps_idx
|
|
LDA #psbuf
|
|
ADD ps_idx
|
|
STA ps_ptr
|
|
LDA psdigit
|
|
STCH @ps_ptr
|
|
|
|
LDA ps_len
|
|
ADD #1
|
|
STA ps_len
|
|
|
|
RMO X,A
|
|
STA ps_val
|
|
J ps_div
|
|
|
|
ps_divdone LDA ps_len
|
|
SUB #1
|
|
STA ps_idx
|
|
|
|
ps_print LDA ps_idx
|
|
COMP #0
|
|
JLT ps_end
|
|
|
|
LDA #psbuf
|
|
ADD ps_idx
|
|
STA ps_ptr
|
|
LDCH @ps_ptr
|
|
WD #1
|
|
|
|
LDA ps_idx
|
|
SUB #1
|
|
STA ps_idx
|
|
J ps_print
|
|
|
|
ps_end LDA #0x0D . CR
|
|
WD #1
|
|
LDA #0x0A . LF
|
|
WD #1
|
|
RSUB
|
|
|
|
ps_zero LDA #0x30 . "0"
|
|
WD #1
|
|
LDA #0x0D
|
|
WD #1
|
|
LDA #0x0A
|
|
WD #1
|
|
RSUB
|
|
|
|
.data
|
|
. rekurzija faktoriala
|
|
sp WORD 0 . stack pointer
|
|
n WORD 0
|
|
acc WORD 0 . akumulator za faktorial
|
|
stackL RESB 60
|
|
|
|
. printStdout
|
|
ps_val WORD 0
|
|
ps_len WORD 0
|
|
ps_idx WORD 0
|
|
psdigit WORD 0
|
|
ps_ptr WORD 0
|
|
psbuf RESB 12
|
|
|
|
END prog
|