home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS - Coast to Coast
/
simteldosarchivecoasttocoast.iso
/
pcmag
/
vol12n05.zip
/
NUMBER.ZIP
/
NUMBER.ASM
next >
Wrap
Assembly Source File
|
1992-04-25
|
3KB
|
163 lines
cseg segment
assume cs:cseg, ds:cseg
SkipInstruction macro
db 10111001b
endm
; 10111001b is a "mov cx, immed" opcode -- it results in the following
; two bytes being moved to cx, rather than being executed as code.
; Just a way of avoiding a "jmp short Exit" instruction below (saving
; a byte each time).
org 100h
Start: cld
xor dx,dx ; initial offset
mov si,81h
call SkipWhite ; get first char. after spaces and tabs
jz DoIt ; ... if no options
cmp al,"/" ; valid switch chr?
je Option
cmp al,"-"
jne Help
Option:
lodsb
or al,00100000b ; force lower case
cmp al,"s"
je Skip
cmp al,"+"
jne Help
PlusN:
call ToNum ; get offset
jc Help ; C set if not a number
jz TooBig ; Z set if overflow occurred
cmp ax,65000
jae TooBig
mov dx,ax ; put offset in dx
or ax,ax ; decrement offset unless it is zero
jz DoIt
Skip:
dec dx ; for "SKIP", set dx = -1
DoIt:
push dx ; save offset
mov ah,3Fh ; read
xor bx,bx ; from standard input
mov dx,offset Buffer ; into Buffer
mov cx,65000 ; up to 65000 characters (should be enough!)
int 21h
mov cx,ax ; cx = # of characters read
pop ax ; ax = offset (or SkipFlag)
sub cx,2
jbe NoInput ; had to read 3 or more characters
inc ax ; Skip?
jnz AddOffset
mov si,dx ; dx & si = start of buffer
mov di,dx
add di,cx ; di = end of buffer
mov byte ptr [di],13 ; make sure we stop at the end
SkipLoop:
call SkipChkDigit ; check if next non-WhtSpc chr is a digit
jnc GetNum ; yes -- OK
mov dx,si ; else save current position
cmp si,di ; and see if we're finished
jbe SkipLoop
jmp short NoNumber
AddOffset:
dec ax
cmp ax,cx ; offset > actual number of bytes read?
jae TooBig
add dx,ax
GetNum:
mov si,dx
call ToNum
jc NoNumber ; carry = no number found
jz GrtEq250 ; zero = number bigger than 65535
cmp ax,250 ; must be <= 250
jbe Exit
GrtEq250:
mov al,250 ; greater or equal to 250
SkipInstruction
NoNumber:
mov al,254
SkipInstruction
TooBig:
mov al,253
SkipInstruction
NoInput:
mov al,252
Exit: mov ah,4Ch
int 21h
Help: mov dx,offset HelpMsg
mov ah,9
int 21h
mov al,255 ; invalid parameters
jmp Exit
SkipWhite:
lodsb
cmp al," "
je SkipWhite
cmp al,9
je SkipWhite
cmp al,13
ret
SkipChkDigit:
call SkipWhite
dec si
ChkDigit:
lodsb
sub al,"0"
jc ChkDone
cmp al,10
cmc
ChkDone:
ret
ToNum: call SkipChkDigit
jc NumExit
NumLoop:
mov bx,ax
call ChkDigit
jc NumDone
cbw
mov cx,ax
mov al,10
mul bx
jc Overflow
add ax,cx
jnc NumLoop
Overflow:
xor ax,ax ; reset C, set Z
ret
NumDone:
or al,al ; reset C, reset Z (al <> 0 here)
mov ax,bx
NumExit:
ret
Buffer equ $
HelpMsg:
db "Usage: NUMBER [/option]",13,10
db " reads a number from the keyboard (or a `pipe'), returning",13,10
db " the result in ERRORLEVEL (EL). `option' can be:",13,10
db 9,"+n (start at the nth character)",13,10
db 9,"S (search for the first number in the input)",13,10,10
db " EL = 250",9,"number was >= 250;",13,10
db " EL = 252",9,"no input;",13,10
db " EL = 253",9,"offset too big;",13,10
db " EL = 254",9,"no number found;",13,10
db " EL = 255",9,"invalid option (this message displayed).",13,10,10,"$"
cseg ends
end Start