Article View: comp.lang.asm.x86
Article #121Re: Frustrating
From: David Lindauer
Date: Thu, 29 Oct 1998 00:00
Date: Thu, 29 Oct 1998 00:00
313 lines
9676 bytes
9676 bytes
--------------D848763A36575765A4DDCF79
Content-type: text/plain; charset="us-ascii"
hi,
find attached an example for TASM that will BOTH uppercase strings,
AND do additions/subtractions. You can find more working demos on my
web site, but, they are probably mostly more advanced than you are ready for
at this point. Have you checked out the 'snippets' collection (see FAQ). I
have never looked at it but it is supposed to have lots of example code...
--
---------------------------------------------------------------
David Lindauer mailto:camille@bluegrass.net ICQ: 8699592
http://www.ladsoft.com (computer page)
http://www.geocities.com/Area51/Station/5196/index.html (home page)
http://www.geocities.com/Area51/Station/5196/ttc.html (tao te ching)
--------------D848763A36575765A4DDCF79
Content-type: text/plain; charset="us-ascii"; name="Q.asm"
Content-transfer-encoding: 7bit
Content-Disposition: inline; filename="Q.asm"
;
; example program
;
; (public domain)
;
; David Lindauer, LADSoft, October 1998
;
; it prompts you for input
; if the first character is a letter, it will convert the string to uppercase
; and display it
;
; otherwise it will prompt for a second number,
; then it will multiply the two numbers and add them and show the
; results
;
; when you want to exit the program, just hit return without typing anything
; on the line
;
; note you CAN do the input and output with DOS calls 0ah and 09h, I just
; never use them because I always find it easier to just roll my own I/O
; than try to remember the strange protocols DOS uses.
;
.model small
.stack
.data
banner db "My test program" ; always have a banner
crlf db 13,10,0 ; this is BOTH part of the banner
; AND a seperate thing to move to
; the next line on the screen
prompt2 db "2" ; this is the second prompt
; since it doesn't have a terminator
; this string is prefixed to the next
; one during displays
prompt db "-> ",0 ; the main prompt
.data?
inputbuffer db 256 DUP (?) ; an input buffer. We make it big
; so the odds are they won't overrun
; it, although they can if they want
; in which case the program will
; crash. A good program would
; check and not allow this to happen.
outputbuffer db 256 DUP (?) ; output buffer. Must be as big as
; the input buffer.
.code
;
; routine to conver an ASCII string to uppercase
; A-Z = 041h -05Ah whereas a-z = 061h -07ah
; in: SI points to (null terminated) string
; di points to a new buffer
; out: string is copied, with the case change
;
uppercase PROC
push di ; save regs
push si
ucl:
lodsb ; get a character
or al,al ; bail out when we hit the
; null terminator
jz ucx ;
cmp al,'a' ; see if it is a lowercase character
jc ucnone
cmp al,'z'
ja ucnone
and al,not 20h ; yes, make it uppercase
ucnone:
stosb ; save the new character
jmp ucl ; and loop
ucx:
stosb ; exit point, store the null
; terminator
pop si ; and restore regs
pop di
ret
uppercase ENDP
;
; reads a number from a buffer, returns it in AX
;
; in: si points at the buffer
; out: ax = value
;
getnum PROC
push bx ; save regs
push cx
push dx
push si
sub cx,cx ; CX = answer = 0
mov bx,10 ; base 10
gnl:
lodsb ; get char
sub ah,ah ; AH=0 for the later add
sub al,'0' ; is it a digit
jc gnx ; no, bail out with the answer
cmp al,10 ; is it a digit?
jae gnx ; no bail out with the answer
xchg ax,cx ; else AX = old result, cx = new result
mul bx ; multiply old result *10
add cx,ax ; and add new result
jmp gnl ; ghen go get another char
gnx:
mov ax,cx ; move result to AX
pop si ; then pop regs and return
pop dx
pop cx
pop bx
ret
getnum ENDP
;
; puts the number in AX into the buffer at DI, with a null terminator
;
; in: ax = number
; di = buffer
;
putnum PROC
push dx ; save regs. Note we are NOT
push cx ; saving DI to make it easy
push bx ; toconcatenate two answers together
mov bx,10 ; BX = base
sub cx,cx ; CX = number of digits = 0
pnl1:
sub dx,dx ; for a DIV we must clear the MSW
div bx ; divide by 10
add dl,'0' ; remainder in DL, make it ASCII
push dx ; and save it on the stack
inc cx ; update the digit count
or ax,ax ; is the quotient 0?
jnz pnl1 ; no, get another digit
; now we have all digits on the stack
; in such a way that they will be
; popped in left-to-right order
pnl2:
pop ax ; get a digit
stosb ; save it in output buffer
loop pnl2 ; loop till done
sub al,al ; store a null terminator
stosb
pop bx ; pop registers
pop cx
pop dx
ret
putnum ENDP
;
; readstring
;
; in DI = buffer.
; out: buffer holds null-terminated string
;
readstring PROC
push di ; save regs
push bx
mov bx,di ; bx = start of buffer so that
; when we do a backspace we
; won't go past the beginning
rsl:
sub ah,ah ; BIOS function to wait for a key
int 16h ; and do it
cmp al,13 ; is it CR?
jz rsx ; yes, exit
cmp al,8 ; else is it one of the backspace
; variants?
jz bkspc ; yes- do it
cmp al,07fh ; the other?
jz bkspc ; yes- do it
stosb ; else save the char
; this is where we would check for
; overrun of the inputbuffer
mov dl,al ; and use dos function 2 to echo it
mov ah,2
int 21h
jmp rsl ; loop for next char
; backspace routine
bkspc:
cmp di,bx ; at the beginning of text?
jz rsl ; if so no backspace
dec di ; else discard the last input char
mov ah,2 ; and print the sequence
mov dl,8 ;backspace
int 21h
mov ah,2
mov dl,' ' ;space
int 21h
mov ah,2
mov dl,8 ;backspace
int 21h ; in order to discard the character
jmp rsl ; from the screen and move the cursor
; back
rsx:
sub al,al ; end of input, so store a null
stosb ; terminator
pop bx ; restore regs
pop di
ret
readstring ENDP
;
; in: SI = null-terminated buffer
; out: buffer placed on screen
;
writestring PROC
push si ; save regs
wsl:
lodsb ; get a char
or al,al ; null terminator?
jz wsx ; yes, exit
mov dl,al ; else put the char out
mov ah,2 ; with DOS function 2
int 21h
jmp wsl ; loop to next char
wsx:
pop si ; restore regs
ret
writestring ENDP
;
; main program
;
start PROC
mov ax,DGROUP ; necessary EXE initialization
mov ds,ax
mov es,ax
mov si,offset banner ;tell them we are here
call writestring
; program main loop starts here
sl:
mov si,offset prompt ; issue a prompt
call writestring
mov di,offset inputbuffer ; now read input
call readstring
mov si,offset crlf ; then advance to the next line
call writestring
xchg si,di ; now si = pointer to input string
test byte ptr [si],-1 ; see if first char is null terminator
jnz nox ; if not continue
mov ax,4c00h ; if so bail to DOS
int 21h
nox:
cmp byte ptr [si],'9' ; now see if the first char is possibly
; a number
ja touc ; greater than a number, go uppercase it
call getnum ; else get the number (si = buf ptr)
push ax ; save the number on the stack
mov si,offset prompt2 ; prompt for another number
call writestring
mov di,offset inputbuffer ; read it in
call readstring
mov si,offset crlf ; advance to next line
call writestring
xchg si,di ; si = input buffer
call getnum ; read the second number
mov bx,ax ; put it in bx
pop ax ; restore the first number
push ax ; but we are about to wipe it, save it again
mul bx ; now multiply the two numbers
mov di,offset outputbuffer ; and stick the result in the output buffer
call putnum ;
dec di ; we are going to append the easy way,
; by overriting the null terminator
; for the first number
mov al,"," ; so store a comma
stosb
pop ax ; restore the first number
add ax,bx ; add them
call putnum ; and append the result
mov si,offset outputbuffer ; now write it to the screen
call writestring
mov si,offset crlf ; advance to the next line
call writestring
jmp sl ; and go get more input
;
; come here to uppercase a string
;
touc:
mov di,offset outputbuffer ; load up output buffer,
; si already = input buffer
call uppercase ; convert to uppercase
xchg si,di ; si = output buffer
call writestring ; write the result
mov si,offset crlf ; advance to the next line
call writestring
jmp sl ; and go get more input.
start ENDP
end start
--------------D848763A36575765A4DDCF79--
Technical Details
Message-ID:
<71aqss$lrk$1@autumn.news.rcn.net>Path:
arc1-ca.pugleaf.net!unknown!not-for-mailReferences:
<7177gc$ms7$1@autumn.news.rcn.net>Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: feaef,9649ddaf83649d3e X-Google-Attributes: gidfeaef,public X-Google-Thread: 114917,9649ddaf83649d3e X-Google-Attributes: gid114917,public From: David Lindauer <camille@bluegrass.net> Subject: Re: Frustrating Date: 1998/10/29 Message-ID: <71aqss$lrk$1@autumn.news.rcn.net> X-Deja-AN: 406468235 Cache-Post-Path: news.bluegrass.net!unknown@dial28.pm3.bluegrass.net Approved: <johnfine@erols.com> References: <7177gc$ms7$1@autumn.news.rcn.net> Content-Type: multipart/mixed; boundary="------------D848763A36575765A4DDCF79" X-Mozilla-Status: 0801 X-Complaints-To: abuse@rcn.com X-Trace: ze8P0BsDpkcUUDVmmyhs1RVR2HDj19bDl/vGypaLRXw= Organization: Bluegrass Net X-Cache: nntpcache 2.3.2 (see http://www.nntpcache.org/) Mime-Version: 1.0 NNTP-Posting-Date: 29 Oct 1998 22:40:28 GMT Newsgroups: comp.lang.asm.x86,borland.public.tasm