A slight modification to macro geti. Reason: to get rid of the macro's local data and replace it with dx as the signess marker.
;GET DECIMAL STRING FROM KBOARD
;And convert to its true value
;Five digits only. Max: 65535
;Don't supply suffix 'd'
;Valid digits from '0' to '9' only
;%1 = dw
;============
%macro geti 1
;============
pusha
mov word[ds:%1],0 ;initialize variable
xor si,si ;si=0 or mov si,0. For the loop
xor di,di ;di=0 or mov di,0. For the exponent
xor dx,dx ;**
%%get:
getch ;get character from kboard (in AL)
cmp al,'-' ;if negative sign
je %%sign
cmp al,0dh ;if <ENTER>
je %%line
cmp al,39h ;if bigger than '9'
jg %%inv
sub al,30h ;convert chars to digits
xor ah,ah ;clear AH. We want AL only
push ax ;now save AX (AL=digit. AH cleared)
inc si ;Loop up
cmp si,6 ;5 digits only (for 16-bit)
je %%inv
jmp %%get ;get next char from kboard
%%sign:
test si,si ;if invalid negative form
jnz %%inv ;equals cmp si,0/je %%inv
mov dx,1 ;**
push dx ;**
jmp %%get ;get next chars
%%inv:
prtc '!'
jmp %%exit
%%line:
line ;after ENTERed
%%first:
pop ax ;Restore digit off the stack,save in AX
add word[ds:%1],ax ;add first digit, to sent var
cmp si,1 ;if single digit input
je %%done ;done
%%second: ;Second digit
inc di ;Power up
mov ax,10 ;10^1 = 10
pop bx ;restore digit off the stack,save in BX
mul bx ;AX=AX(10)* BX(digit). Answer in AX
add word[ds:%1],ax ;add up second digit, to sent var
cmp si,2 ;if two digits input
je %%done ;done
sub si,2 ;next loop is to ignore two digits
%%next:
inc di ;power up (exponent)
push di ;save exponent onto stack
mov ax,10 ;for MUL
mov bx,10 ;for MUL
%%pow:
mul bx ;Generate pow, final answer in AX
cmp di,2 ;off-by-one adjustment. If power is completed
je %%ok
dec di ;else, exponent down
jmp %%pow ;next pow for the same digit
%%ok:
pop di ;restore exponent
pop bx ;restore the digit
mul bx ;AX=AX(from pow) * BX (digit)
add word[ds:%1],ax ;add up to sent var
dec si ;loop down
test si,si ;loop check if si=0
jz %%done
jmp %%next ;process next digit
%%done:
pop dx ;**
cmp dx,1 ;**
je %%signs
jmp %%exit
%%signs:
neg word[ds:%1] ;negate it
%%exit:
popa ;restore general registers
%endmacro
Just replace the entire macro with this one above. Usage:
geti x ;get a 16-bit decimal from keyboard. Sign or unsigned
prti [x],-s ;Display sign integer (-s switch)
...
...
x dw 0