example3

advertisement
CS344-321 Assembly Language Programming
example 3 page
1
CS344-321 Assembly Language Programming
example 3 page
2
CS344-321 Assembly Language Programming
example 3 page
3
CS344-321 Assembly Language Programming
example 3 page
4
CS344-321 Assembly Language Programming
example 3 page
5
CS344-321 Assembly Language Programming
example 3 page
6
CS344-321 Assembly Language Programming
7
example 3 page
Figure 3-2.
GETENV.ASM, a procedure that returns a pointer to the
value portion of the specified environment string.
title
GETENV.ASM --- Get Environment String
page 55,132
; GETENV.ASM --- Return address and length of variable
;
portion of environment string.
CS344-321 Assembly Language Programming
example 3 page
;
; Copyright (c) 1989 Ray Duncan
;
; Call with: DS:SI = ASCIIZ name of environment variable
;
ES
= segment of program segment prefix
(PSP)
;
; Returns: ES:DI = address of value of environment
variable
;
AX
= length (0 = not found)
;
; Destroys: Nothing
psp_ptr equ
002ch
; offset of
environment
; pointer within PSP
_TEXT
segment word public 'CODE'
assume
cs:_TEXT
public
getenv
getenv
proc near
push cx
push si
; save registers
8
CS344-321 Assembly Language Programming
9
example 3 page
mov es,es:[psp_ptr]
; get pointer to environment
mov cx,8000h
; assume max env. = 32 KB
xor
di,di
; initial env. offset
xor
ax,ax
; default length result
get1: cmp byte ptr es:[di],0 ; check for end of
environment
je
get4
; end reached, return AX = 0
pop si
; initialize address of target
push si
; variable to be found
repe cmpsb
; compare target and
env. strings
cmp byte ptr [si-1],0
jne
get2
; jump if incomplete match
cmp byte ptr es:[di-1],'='
je
get3
get2:
; jump if match was complete
; match was incomplete
repne scasb
; scan for end of env.
string
jmp get1
; and try again to match
CS344-321 Assembly Language Programming
example 3 page
get3: push di
repne scasb
; save address after = sign
; look for end of this
string
pop ax
; get back starting address
xchg di,ax
; find string length
sub ax,di
dec ax
get4:
; don't include null byte
; common exit point
pop si
; restore registers
pop cx
ret
; return to caller
getenv
endp
_TEXT
ends
end
10
CS344-321 Assembly Language Programming
example 3 page
11
CS344-321 Assembly Language Programming
example 3 page
12
CS344-321 Assembly Language Programming
example 3 page
13
CS344-321 Assembly Language Programming
example 3 page
14
CS344-321 Assembly Language Programming
15
example 3 page
Figure 3-3.
PUTENV.ASM, a procedure that modifies an existing
environment variable in the environment block or adds a
new environment varible.
title
PUTENV.ASM --- Modify Environment Variable
page 55,132
;
; PUTENV.ASM --- Add or modify MS-DOS environment
variable.
;
; Copyright (C) 1989 Ray Duncan
;
; Call with: DS:SI = new ASCIIZ environment variable
CS344-321 Assembly Language Programming
16
example 3 page
;
in the form name=value
;
ES
= segment of program segment prefix
(PSP)
;
; Returns: AX
;
= 0 if successful
= -1 if failed
;
; Destroys: ES
psp_ptr equ
002ch
; offset of
environment
; pointer within PSP
DGROUP group_DATA
_TEXT
segment word public 'CODE'
assume
cs:_TEXT
extrn getenv:near
; names for working storage
oldenv
equ [bp-2]
; segment of old
environment
envlen
equ [bp-4]
environment
; length of old
CS344-321 Assembly Language Programming
example 3 page
newenv
equ [bp-6]
; segment of new
environment
pspseg
equ [bp-8]
; segment of program
segment prefix
oldlen
equ [bp-10]
; length of existing
equ [bp-12]
; length of new env.
variable
newlen
variable
newname equ
[bp-14]
; offset of new name
portion
newvar
equ [bp-16]
; offset of new param.
portion
public
putenv
putenv
proc near
push bp
; set up stack frame for
mov bp,sp
; working storage
sub sp,16
mov newname,si
; save offset of new
variable
mov pspseg,es
; save PSP segment
mov es,es:[psp_ptr]
; pick up segment of old
mov oldenv,es
; environment and save it
17
CS344-321 Assembly Language Programming
18
example 3 page
push cx
; save other registers
push si
push di
; find old environment length
mov cx,8000h
; assume max = 32 KBytes
xor
di,di
; ES:DI = environment base
xor
al,al
put1: repne scasb
; scan for double null
(can't use
scasb
; SCASW since might
be on odd addr)
jne
put1
mov envlen,di
; save length of old
environment
mov di,si
; find length of new env.
variable
mov ax,ds
; ES:DI = addr of new variable
mov es,ax
mov cx,-1
xor
al,al
repne scasb
null byte
; scan for terminating
CS344-321 Assembly Language Programming
19
example 3 page
not
cx
; now CX = length including
null
mov newlen,cx
; save length of new variable
; attempt to allocate memory
; block for new environment...
mov bx,cx
; length of old environment
add bx,envlen
; + length of new variable
mov cl,4
; divide by 16 and round
shr
bx,cl
; up to find paragraphs to
inc
bx
; allocate for new environment
mov ah,48h
; Fxn 48h=allocate
memory block
int
21h
; transfer to MS-DOS
jnc
put2
; jump if allocation succeeded
mov ax,-1
; otherwise, return error flag
jmp put6
put2: mov newenv,ax
; save new environment
segment
mov di,offset envar
; copy name portion of new
; variable to local storage
CS344-321 Assembly Language Programming
20
example 3 page
put3: movsb
; copy characters up to
'='
cmp byte ptr [si],'='
jne
put3
; loop until end of name found
xor
al,al
; append null byte to name
si
; save address of param.
stosb
inc
mov newvar,si
; portion of new variable
mov si,offset envar
; check if new environment
mov es,pspseg
; variable has a previous
value
call
getenv
; in old environment
mov oldlen,ax
; save length of value, if any
or
ax,ax
; was it present in old block?
jnz
put4
; yes, PUTENV the hard way
push ds
; no just copy existing
environment
; and add the new variable
mov ds,oldenv
; DS:SI = old env. block
mov es,newenv
; ES:DI = new env. block
CS344-321 Assembly Language Programming
21
example 3 page
mov cx,envlen
; CX = length of old
environment
dec cx
xor
si,si
xor
di,di
; less the extra null byte
rep movsb
; copy the old stuff
pop ds
; DS:SI = address of new
variable
mov si,newname
; ES:DI = end of new
environment
mov cx,newlen
; CX = length of new variable
rep movsb
; append the new variable
xor
; and the extra null byte
al,al
stosb
; marking end of environment
jmp put5
; go update PSP env. pointer
put4:
; come here on the messy
case,
; env. variable already exists
; ES:DI = offset+1 of '=' in
; old variable from 'getenv'
push ds
; copy old environment to new
mov ax,es
; up through the '=' of the
mov ds,ax
; variable we are changing
CS344-321 Assembly Language Programming
22
example 3 page
mov cx,di
; DS:SI = old environment
mov es,newenv
; ES:DI = new environment
xor
si,si
; CX = offset+1 of '='
xor
di,di
;
in old variable
rep movsb
pop ds
; now let DS:SI = offset+1
push si
; of '=' in new variable
mov si,newvar
; and CX = length of portion
mov cx,newname
; following the '='
add cx,newlen
sub cx,newvar
; copy the new parameter
portion
rep movsb
; to the new environment
pop si
; skip over parameter portion
add si,oldlen
; of the old variable
inc
; and its null byte
si
push ds
; now copy remainder of
mov ds,oldenv
; old environment to new one
mov cx,envlen
; total length less portion
sub cx,si
; already copied and length
rep movsb
; of old environment variable
pop ds
CS344-321 Assembly Language Programming
23
example 3 page
put5:
; PUTENV function
successful,
mov es,oldenv
; release old environment
block
mov ah,49h
int
21h
; transfer to MS-DOS
mov es,pspseg
; update pointer to new
mov ax,newenv
; environment in caller's PSP
mov es:[psp_ptr],ax
xor
ax,ax
put6: pop di
; return success code
; restore registers
pop si
pop cx
mov sp,bp
; discard stack frame
pop bp
ret
; back to caller
putenv
endp
_TEXT
ends
_DATA
segment word public 'DATA'
CS344-321 Assembly Language Programming
example 3 page
envar db
80 dup (0)
; name of new environment
var.
; for call to 'getenv'
_DATA
end
ends
24
CS344-321 Assembly Language Programming
example 3 page
25
CS344-321 Assembly Language Programming
example 3 page
26
CS344-321 Assembly Language Programming
example 3 page
27
CS344-321 Assembly Language Programming
example 3 page
28
CS344-321 Assembly Language Programming
example 3 page
29
CS344-321 Assembly Language Programming
30
example 3 page
Program TRYENV.ASM
------------------------------------------------------------------------------title
TRYENV.ASM --- Demo of PUTENV.ASM
and GETENV.ASM
page 55,132
;
; TRYENV.ASM --- Interactive Demo of PUTENV.ASM and
GETENV.ASM Modules
;
; Copyright (C) 1989 Ray Duncan
;
; To build: MAKE TRYENV
stdin equ 0
stdout
equ 1
stderrequ 2
; standard input handle
; standard output handle
; standard error handle
CS344-321 Assembly Language Programming
31
example 3 page
cr
equ 0dh
; ASCII carriage return
lf
equ 0ah
; ASCII line feed
stksize equ 128
DGROUP group_DATA,STACK
_TEXT
segment word public 'CODE'
assume
cs:_TEXT,ds:DGROUP,ss:STACK
extrn getenv:near
extrn putenv:near
main proc far
mov ax,DGROUP
; make our data
segment
mov ds,ax
; addressable
; now give back extra
memory...
mov ax,es
; AX = segment of PSP base
mov bx,ss
; BX = segment of stack base
sub bx,ax
; reserve seg stack - seg psp
CS344-321 Assembly Language Programming
32
example 3 page
add bx,stksize/16
; plus paragraphs of
stack
inc
bx
; round up for safety
mov ah,4ah
; fxn 4ah = modify
memory block
int
21h
jc
main2
mov pspseg,es
main1:
; transfer to MS-DOS
; exit if resize failed
; save segment of PSP
mov ax,DGROUP
; make our data
segment
mov ds,ax
; addressable again...
; prompt user 'Enter name:'...
mov dx,offset msg1
; message address
mov cx,msg1_len
; message length
call
pmsg
; go display message
; get name of env. variable
mov dx,offset buff1
mov cx,buff1_len
mov bx,stdin
mov ah,3fh
int
21h
; address of input buffer
; length of buffer
; standard input handle
; func. 3fh = read
; transfer to MS-DOS
CS344-321 Assembly Language Programming
33
example 3 page
sub ax,2
; ignore CR-LF characters
or
ax,ax
; anything entered?
jnz
main3
; yes, proceed
mov ax,4c00h
; final exit to MS-DOS
main2:
int
main3:
21h
; with return code = 0
mov bx,ax
; append null to user's
mov byte ptr [bx+buff1],0
; input string...
mov si,offset buff1
; address of ASCIIZ string
call
strupr
; fold lower case to upper
mov es,pspseg
; segment address of PSP
case
call
getenv
; search environment for
match
or
ax,ax
jz
main4
; find anything?
; no, display error
message
push ds
; save data segment
push ax
; save length of value
push di
; save offset of value
; display 'The value is:' ...
CS344-321 Assembly Language Programming
34
example 3 page
mov dx,offset msg2
; address of message
mov cx,msg2_len
; length of message
call
pmsg
; go display message
push es
; display current value
pop ds
; of environment variable
pop dx
; address of string
pop cx
; length of string
call
; go display message
pmsg
pop ds
; restore segment of
DGROUP
mov dx,offset msg6
; extra blank line
mov cx,msg6_len
call
pmsg
main4:
; prompt user 'Enter
value:'...
mov dx,offset msg3
; message address
mov cx,msg3_len
; message length
call
pmsg
; go display message
; get value for env. variable...
mov dx,offset buff2
mov cx,buff2_len
mov bx,stdin
; address of input buffer
; length of buffer
; standard input handle
CS344-321 Assembly Language Programming
35
example 3 page
mov ah,3fh
int
21h
; func. 3fh = read
; transfer to MS-DOS
sub ax,1
; ignore CR-LF characters
mov bx,ax
; append null to user's input...
mov byte ptr [bx+buff2-1],0 ; and include null in
length
push ds
; let ES = DGROUP too
pop es
mov di,offset buff1
; scan to end of name
mov cx,-1
; of environment variable
xor
al,al
repne scasb
mov byte ptr [di-1],'=' ; replace null with equal sign
mov si,offset buff2
; then append new value and
mov cx,bx
; terminating null
rep movsb
mov si,offset buff1
; store new value in
environment
mov es,pspseg
; using our PUTENV routine
call
putenv
or
ax,ax
; was environment modified?
jnz
main5
; no, display error
message
CS344-321 Assembly Language Programming
36
example 3 page
mov dx,offset msg4
; display 'Environment
mov cx,msg4_len
; now contains:'
block
call
pmsg
mov es,pspseg
; let ES = segment of
environment
mov es,es:[002ch]
call
dumpenv
jmp main1
main5:
; dump environment strings
; go prompt user again
; environment can't be
modified
mov dx,offset msg7
; address of error
message
mov cx,msg7_len
; length of error
message
call
pmsg
jmp main1
main endp
;
; go display message
; go prompt user again
CS344-321 Assembly Language Programming
37
example 3 page
; DUMPENV
Dump entire environment block to stdout
;
; Call with: ES = segment base address of environment
;
; Returns: Nothing
;
; Destroys: AX, BX, CX, DX, DI, DS
;
dumpenv proc
xor
dump1:
near
di,di
; initialize env. offset
cmp byte ptr es:[di],0 ; reached end of
environment?
je
dump2
; yes, exit
mov dx,offset msg6
; no, move to new line
mov cx,msg6_len
; by sending carriage
call
pmsg
; return/line feed
mov dx,di
; save address of next
mov cx,-1
; environment variable
xor
; and find its length
al,al
repne scasb
null
not
cx
; scan for terminating
CS344-321 Assembly Language Programming
38
example 3 page
dec cx
; now CX = length
push ds
; save our data segment
mov ax,es
; let DS:DX = address
mov ds,ax
; of environment variable
call
; and display it
pmsg
pop ds
; restore our data segment
jmp dump1
dump2:
; get next env. variable
mov dx,offset msg6
; display extra
blank line
mov cx,msg6_len
call
pmsg
ret
; back to caller
dumpenv endp
;
; STRUPR --- Fold ASCIIZ string to upper case
;
; Call with: DS:SI = address of ASCIIZ string
;
; Returns: Nothing
;
; Destroys: AX
CS344-321 Assembly Language Programming
example 3 page
;
struprproc near
push si
; save string address
strup1: lodsb
; get next character
or
al,al
; found end (null byte) ?
jz
strup2
cmp al,'a'
jb
; yes, jump
; test if in range 'a'-'z'
strup1
; skip it if not >= a
cmp al,'z'
ja
strup1
; skip it if not <= z
sub byte ptr [si-1],'a'-'A' ; fold to upper case
jmp strup1
strup2: pop si
ret
; get another char
; restore original string
; address and return
struprendp
;
; PMSG --- Display message on standard output
;
; Call with: DS:DX = message address
;
;
CX
= message length
39
CS344-321 Assembly Language Programming
example 3 page
; Returns: Nothing
;
; Destroys: AX, BX
;
pmsg proc near
mov bx,stdout
; standard output handle
mov ah,40h
int
21h
; func. 40h = write
; transfer to MS-DOS
ret
; return to caller
pmsg endp
_TEXT
ends
_DATA
segment word public 'DATA'
pspseg
dw
?
; segment of program
segment prefix
msg1 db
cr,lf,'Enter name of environment variable: '
msg1_len equ $-msg1
msg2 db
cr,lf,'Current value is: '
msg2_len equ $-msg2
40
CS344-321 Assembly Language Programming
41
example 3 page
msg3 db
cr,lf,'Enter new value: '
msg3_len equ $-msg3
msg4 db
cr,lf,'Environment block now contains: '
msg4_len equ $-msg4
msg6 db
cr,lf
; carriage return/line feed
msg6_len equ $-msg6
msg7 db
cr,lf,'Cannot modify environment!',cr,lf
msg7_len equ $-msg7
buff1 db
80 dup (?)
buff1_len equ $-buff1
buff2 db
80 dup (?)
buff2_len equ $-buff2
; input buffer for name of
; environment variable
; input buffer for value of
; environment variable
_DATA
ends
STACK
segment para stack 'STACK'
db
stksize dup (?)
CS344-321 Assembly Language Programming
example 3 page
STACK
ends
end main
Make file for TRYENV.EXE
getenv.obj : getenv.asm
masm /Zi getenv;
putenv.obj : putenv.asm
masm /Zi putenv;
tryenv.obj : tryenv.asm
masm /Zi tryenv;
tryenv.exe : tryenv.obj putenv.obj getenv.obj
LINK /CODEVIEW tryenv+putenv+getenv;
42
CS344-321 Assembly Language Programming
example 3 page
43
Download