-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSETARGV.INC
132 lines (117 loc) · 3.03 KB
/
SETARGV.INC
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
;--- read the commandline at ES:SI
;--- and create an argc/argv structure on the stack.
;--- in: ES:SI=cmdline, DS=DGROUP, SS=DGROUP
;--- out: _argc (=[bp-2])
;--- _argv (=[bp-4])
;--- all std registers modified (including SP)
?DUMMYFN equ 1
?QUOTES equ 1
_setargv proc
mov bp, sp
sub sp, 256 ; just make enough room for argc/argv
xor di, di ; init argc
xor dx, dx ; init size of mem block
; mov si, 81H
push es
pop ds
; assume ds:nothing ; no need for assumes, since no global vars are accessed
jmp scanarg
;--- DI = argc
;--- DX = block size (not including null terminators)
nextarg:
push bx ; save argument size
scanarg:
@@:
lodsb
cmp al, ' '
je @B
cmp al, 9
je @B
cmp al, 13
jz doneargs ; exit if eol
inc di ; another argument
xor bx, bx ; init argument size
if ?QUOTES
cmp al, '"'
jz handle_quote
endif
dec si ; back up to reload character
push si ; save argument ofs
@@:
lodsb
cmp al, ' ' ; end argument?
je nextarg
cmp al, 9
je nextarg ; white space terminates argument
cmp al, 13
jz doneargs2 ; exit if eol
inc bx
inc dx
jmp @B
if ?QUOTES
handle_quote:
push si
@@:
lodsb
cmp al, 13
jz quoteerr
cmp al, '"'
jz @F
inc dx
inc bx
jmp @B
quoteerr:
dec si ; "unread" the CR
@@:
jmp nextarg
endif
doneargs2:
push bx ; last argument's size
doneargs:
;--- address & size of arguments are pushed
mov cx, di
add dx, di ; DX=size arguments + terminator bytes
inc di ; add one for NULL pointer
if ?DUMMYFN
inc di ; add one for filename
endif
shl di, 1 ; each ofs needs 2 bytes
add dx, di ; DX=size args + size argv
and dx, -2 ; ensure stack remains word aligned
mov ax, [bp]
sub bp, dx ; alloc the really needed space for argc/argv
mov [bp-6], ax ; store return address
_argc equ <bp-2>
_argv equ <bp-4>
mov [_argv], bp
mov [_argc], cx
add di, bp ; di -> behind vector table (strings)
xor ax, ax
lea bx, [di-2]
mov ss:[bx], ax ; terminating 0000 _argv[x]
sub bx, 2
jcxz noargs
push ss
pop es
;--- copy the arguments from PSP onto the stack
mov dx, cx
@@:
pop cx ; size
pop si ; address
mov ss:[bx], di ; store _argv[x]
sub bx, 2
rep movsb
stosb ; AL still 0
dec dx
jnz @B
noargs:
push ss
pop ds
; assume ds:DGROUP
if ?DUMMYFN
mov [bx], ax ; store 0 as dummy filename
inc word ptr [_argc]
endif
lea sp, [bp-6]
ret
_setargv endp