📄 deskcalc.s
字号:
ADD SP,46: POP BX POP CX RET! From here we get the routines which push and pop variables on the stack! The input commands calls those routines from the dispatch table.! The first routine supplies the address of a variable from its name in DXgetvar: CALL getcbuf ! Read variable name (between A and Z) MOV AX,DX CMP AX,90 JG 9f SUB AX,65 JL 9f SHL AX,1 SHL AX,1 SHL AX,1 ADD AX,varbuf MOV DI,AX RET9: MOV DI,8*26 PUSH varmes PUSH (_printf) SYS ADD SP,4 RETstore: CALL getvar ! Store top of nstack in indicated variable MOV SI,BX CALL cpsd ADD BX,8 RETrecall: CALL getvar ! Load top of nstack from indicated variable SUB BX,8 MOV SI,BX CALL cpds RETsxchg: MOV DI,oper1 ! Exchange top two values of nstack MOV SI,BX CALL cpsd MOV DI,BX ADD DI,8 CALL cpds MOV SI,oper1 CALL cpsd RETspop: CMP BX,stkend ! Pop top of nstack and discard the value JGE topstck ADD BX,8 RETtopstck: PUSH stlg ! Print end of nstack message PUSH (_printf) SYS ADD SP,4 RETsneg: NOT 6(BX) ! negate value at top of nstack NOT 4(BX) NOT 2(BX) NOT (BX) ADD (BX),1 ADC 2(BX),0 ADC 4(BX),0 ADC 6(BX),0 RETsmin: CALL sneg ! Subtraction is negation followed by addition CALL splus RETsplus: MOV SI,BX ! Add top two members on the nstack ADD BX,8 MOV DI,BX CALL addsd RETsmul: XOR DX,DX ! Multiply top two members of the nstack MOV SI,BX CMP 6(BX),0 JGE 1f NOT DX ! Multiplication is done on positive values, sign is CALL sneg ! saved and used later. So if negative negate.1: ADD BX,8 MOV DI,BX CMP 6(BX),0 JGE 1f NOT DX ! Here we process the sign of the other operand CALL sneg1: CALL mulsd CMP DX,0 JE 1f CALL sneg1: RETsdivi: XOR DX,DX ! Divide the second value of the nstack by the top MOV SI,BX CMP 6(BX),0 JGE 1f CALL sneg ! Again save the sign and process positive integers NOT DX1: CALL dup ADD BX,16 MOV DI,BX CMP 6(BX),0 JGE 1f CALL sneg NOT DX1: CALL divsd ! Call of the division operation. MOV SI,oper1 SUB DI,8 CALL cpsd MOV SI,oper3 MOV DI,BX CALL cpsd CMP DX,0 JE 1f ADD (DI),1 ADC 2(DI),0 ADC 4(DI),0 ADC 6(DI),0 CALL sneg SUB BX,8 CALL sneg SUB BX,8 CALL splus ADD BX,81: RETsrest: CALL sdivi ! Determine the remainder by division. SUB BX,8 CALL sxchg ADD BX,8 RETsprint: PUSH BX ! Prints all values on the nstack on a single line. MOVB (nlcr),' '1: CMP BX,stkend JGE 1f CALL snlcr ADD BX,8 JMP 1b1: MOVB (nlcr),'\n' PUSH stckm PUSH (_printf) SYS ADD SP,4 POP BX RETsepar: snop: RET ! no op at white spacesnlcr: PUSH DX ! Print top of nstack MOV DI,oper4 MOV SI,BX CALL cpsd MOV SI,oper5 CALL clrs MOV (SI),TEN XOR DX,DX CMP 6(BX),0 JGE 1f NOT DX XCHG BX,DI CALL sneg XCHG DI,BX1: PUSH BX MOV BX,wrtln+510 MOV AX,(nlcr) MOV (BX),AX2: CALL divsd ! Divide number by ten convert the remainder MOV SI,oper1 DEC BX MOVB AL,(SI) ADDB AL,'0' ! to an ascii symbol and put it in a buffer MOVB (BX),AL MOV SI,oper3 CALL cpsd MOV SI,oper5 CMP 6(DI),0 JNE 2b CMP 4(DI),0 JNE 2b CMP 2(DI),0 JNE 2b CMP (DI),0 JNE 2b CMP DX,0 JE 1f DEC BX MOVB (BX),'-'1: PUSH BX ! Print the buffer PUSH (_printf) SYS ADD SP,4 POP BX POP DX RETdup: MOV SI,BX ! Duplicate top of nstack SUB BX,8 MOV DI,BX CALL cpsd RETcmpds: ! Compares 8-byte integers in (SI) and (DI). Result is 1 if (DI)>(SI); ! 0 if (DI)=(SI); and -1 if (SI)>(DI); return value is put in AX. PUSH CX MOV AX,6(SI) MOV CX,6(DI) CMP CX,AX JL 6f JG 7f MOV AX,4(SI) CMP 4(DI),AX JB 6f JA 7f MOV AX,2(SI) CMP 2(DI),AX JB 6f JA 7f MOV AX,(SI) CMP (DI),AX JB 6f JA 7f MOV AX,0 POP CX RET6: MOV AX,-1 POP CX RET7: MOV AX,1 POP CX RETsnum: MOV SI,oper2 ! Digit encountered in input. Assemble entire MOV DI,oper1 ! integer from the input buffer and push it CALL clrd ! onto the nstack AND DX,15 MOV (DI),DX1: CMP (nxtbuf),48 JL 8f CMP (nxtbuf),57 JG 8f CALL cpds CALL dlshift CALL dlshift CALL addsd CALL dlshift CALL clrs CALL getcbuf AND DX,15 MOV (SI),DX CALL addsd JMP 1b8: CALL pushd RET.SECT .DATAnull: .WORD 0_getchar: .WORD 117_printf: .WORD 127_putchar: .WORD 122one: _exit: .WORD 1_open: .WORD 5_read: .WORD 3_eof: .WORD 0Xffffcurbuf: .WORD 0 ! Current value of input buffer as word variablenxtbuf: .WORD 0 ! Next value of input buffer as word variablepinbuf: .WORD 0 ! Next position in input buffer to be put in nxtbuf! Next we get the 128 byte dispatch table which is used to jump to the! indicated routines on a byte from the input buffer.DTABLE: .WORD squit, snop, snop, snop, squit, snop, snop, snop ! cntrl-0 cntrl-A cntrl-B cntrl-C cntrl-D cntrl-E cntrl-F bell .WORD snop, separ, separ, separ, separ, separ, snop, snop ! back hortab newline vertab newpag carret shout shin .WORD snop, snop, snop, snop, snop, snop, snop, snop .WORD snop, snop, snop, snop, snop, snop, snop, snop .WORD separ, snop, snop, snop, snop, srest, snop, snop ! space ! " # $ % & ' .WORD snop, snop, smul, splus, snop, smin, snop, snop ! ( ) * + , - . / .WORD snum, snum, snum, snum, snum, snum, snum, snum ! 0 1 2 3 4 5 6 7 .WORD snum, snum, sdivi, snop, snop, snop, snop, snop ! 8 9 : ; < = > ? .WORD snop, snop, snop, snop, snop, snop, snop, snop ! @ A B C D E F G .WORD snop, snop, snop, snop, snop, snop, snop, snop ! H I J K L M N O .WORD snop, snop, snop, snop, snop, snop, snop, snop ! P Q R S T U V W .WORD snop, snop, snop, snop, snop, snop, sprint, snop ! X Y Z [ \ ] ^ - .WORD snop, snop, snop, snop, dup, snop, snop, snop ! ` a b c d e f G .WORD snop, snop, snop, snop, snop, snop, snop, snop ! h i j k l m n O .WORD spop, squit, recall, store, snop, snop, snop, snop ! p q r s t u v W .WORD sxchg, snop, snop, snop, snop, snop, sneg, snop ! x y z { | } ~ deletenlcr: .ASCIZ "\n"shfterr: .ASCIZ "Overflow in shift. Number loaded is too large.\n"eofmes: .ASCIZ "Getchar reads end of file.\n"symerro: .ASCIZ "Error encountered in input line.\n"varmes: .ASCIZ "Variable not defined.\n"nulmes: .ASCIZ "Division by zero is refused.\n"stckm: .ASCIZ "Stack\n"stlg: .ASCIZ "Stack underflow encountered.\n".SECT .BSSnstack: .SPACE 8192 ! This is the main 8-byte integer stackstkend: wrtln: .SPACE 512 ! End of nstack, and start of write bufferoper1: .SPACE 8 ! Five scratch variables for multiplicationoper2: .SPACE 16 ! and division oper3: .SPACE 8oper4: .SPACE 8oper5: .SPACE 8varbuf: .SPACE 216 ! Space reserved for variables A-Zinputb: .SPACE 512 ! The main input buffer
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -