source: trunk/src/win32k/rexx/kRxa.asm@ 10367

Last change on this file since 10367 was 3650, checked in by bird, 25 years ago

Rewrote kRx.c in assembly!

File size: 8.1 KB
Line 
1; $Id: kRxa.asm,v 1.1 2000-06-03 03:50:45 bird Exp $
2;
3; kRxa - Small rexx script interpreter.
4;
5; Assembly edition.
6;
7; Copyright (c) 2000 knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
8;
9; Project Odin Software License can be found in LICENSE.TXT
10;
11
12
13 .386p
14 .model flat
15 .stack 10000h
16
17;DEBUG EQU 1
18
19;
20; External Functions
21;
22 extrn DosWrite:PROC
23 extrn RexxStart:PROC
24
25
26;
27; Defined Constants And Macros
28;
29MAX_ARG_LENGTH EQU 1000h
30
31;
32; Structures and Typedefs
33;
34RXSTRING STRUC
35cb dd ?
36pach dd ?
37RXSTRING ENDS
38
39
40
41DATA32 segment dword public 'DATA' use32
42;
43; Global Variables
44;
45ifdef DEBUG
46 ;Debug stuff
47szMsgDebug1 db "Debug1",13,10,0
48szMsgDebug2 db "Debug2",13,10,0
49szMsgDebug3 db "Debug3",13,10,0
50endif
51
52 ;Error messages.
53szMsgScriptnameTooLong db "Fatal error: The scriptname is too long.",13,10,0
54szMsgArgumentsTooLong db "Fatal error: The arguments are too long.",13,10,0
55szMsgRexxStartFailed db "Fatal error: RexxStart failed.",13,10,0
56
57 ;Rexx argument string
58rxstrArgs RXSTRING <0, offset szArgs>
59
60 ;Command env. name - RexxStart param - dont't know what it is used for...
61szEnv db "hmm", 0
62
63 ;Some uninitialized buffers
64szScriptname db 260d dup (?)
65szArgs db MAX_ARG_LENGTH dup (?)
66
67DATA32 ends
68
69
70
71CODE32 segment dword public 'CODE' use32
72
73;;
74; Exe Entry Point.
75; @returns
76; @param eax = eax = ebx = ecx = esi = edi = ebp = 0
77; @param [esp + 00h] Return address. (32-bit flat)
78; @param [esp + 04h] Module handle for program module.
79; @param [esp + 08h] Reserved
80; @param [esp + 0ch] Environment data object address.
81; @param [esp + 10h] Command line linear address in environemnt data object.
82; @uses
83; @equiv
84; @time
85; @sketch
86; @status
87; @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
88; @remark
89main PROC NEAR
90hModule EQU [ebp + 08h]
91pEnvironment EQU [ebp + 10h]
92pCommandline EQU [ebp + 14h]
93 LOCAL sRexxRc:word
94 LOCAL cbActual:dword
95
96 ;
97 ; Find the arguments
98 ;
99 mov eax, pCommandline
100 call strlen
101 add eax, pCommandline
102
103 ;
104 ; The script name is the first argument to this program
105 ; The script arguments are following, so we'll have to find them..
106 ;
107
108
109 ;
110 ; Copy the script name.
111 ;
112 mov ecx, 260 ; Max length.
113 xchg esi, eax ; esi <- Pointer to the arguments (script name) (-1).
114 mov edi, offset szScriptname ; edi <- Target string buffer for the script name.
115
116 mov ah, ' ' ; terminator is ' ' or '\0'
117 skiploop1: ; skip spaces
118 inc esi ; next char (initially at terminator of exe name).
119 mov al, byte ptr [esi] ; Get first char to determin terminator type.
120 cmp al, ah
121 jz skiploop1
122
123 cmp al, '"' ; if not '"' then goto copy loop.
124 jne loop1
125
126 mov al, '"' ; terminator is '"' or '\0'
127 inc eax ; skip '"'.
128
129
130loop1:
131 or al, al ; zero terminator?
132 jz endloop1
133
134 cmp al, ah ; the other terminator?
135 jz endloop1
136
137 stosb ; copy the byte
138
139
140 ; next char
141 inc esi ; next
142 dec ecx ; check that we haven't reached the max length.
143 jz Scriptname_Too_Long
144
145 mov al, byte ptr [esi] ; read (next) byte
146 jmp loop1
147
148endloop1:
149 mov byte ptr [edi], 0 ; terminate scriptname.
150
151 ; more arguments?
152 or al, al ; stopped at null terminator, then no more args.
153 jz callrexx
154 inc esi ; skip terminator.
155
156 ;
157 ; skip spaces between the scriptname and the first argument.
158loop2:
159 mov al, byte ptr [esi]
160 cmp al, ' '
161 jne endloop2
162 inc esi
163 jmp loop2
164endloop2:
165
166 ;
167 ; Copy arguments, we'll copy till '\0'
168 ;
169 mov eax, esi
170 call strlen ; get argument length
171 mov ecx, eax ; ecx <- number of bytes to copy (argument length).
172 mov rxstrArgs.cb, ecx ; Set length of rexx argument string.
173 cmp ecx, MAX_ARG_LENGTH
174 jae Arguments_Too_Long ; Overflow detected.
175 mov edi, offset szArgs ; edi <- Target argument buffer.
176 repnz movsb ; memcpy(edi, esi, ecx);
177 ; Not sure if it copies the '\0', but that
178 ; don't matter while the memory is initialized
179 ; to zero by the OS!
180
181callrexx:
182 ; init return string.
183 xor ebx, ebx ; ebx <- 0
184
185 push ebx ; NULL - Rexx program return string.
186 lea eax, sRexxRc
187 push eax ; Rexx program return code.
188 push ebx ; NULL - EXIT (FIXME?)
189 push ebx ; RXCOMMAND (0) - Program called as Command.
190 push offset szEnv ; Command env. name. What is this????
191 push ebx ; NULL - Pointer to INSTORE? Not used.
192 push offset szScriptname ; Name of REXX script.
193 push offset rxstrArgs ; Pointer to argument array (rexx strings) - 1 element.
194 push 1 ; Number of arguments - one.
195 call RexxStart
196 sub esp, DWORD * 9
197
198 ;Check return value from RexxStart
199 or eax, eax
200 jnz RexxStartFailed
201
202;
203; return rexx error code.
204;
205 mov ax, sRexxRc
206 ret
207
208
209;
210; errors
211;
212Scriptname_Too_Long:
213 mov eax, offset szMsgScriptnameTooLong
214 jmp PrintError
215
216Arguments_Too_Long:
217 mov eax, offset szMsgArgumentsTooLong
218 jmp PrintError
219
220RexxStartFailed:
221 mov eax, offset szMsgRexxStartFailed
222 jmp PrintError
223
224PrintError:
225 lea ebx, cbActual
226 push ebx ; cbActual - last arg for DosWrite
227 mov ebx, eax ; ebx <- string pointer
228 call strlen
229 push eax ; Bytes to write
230 push ebx ; Pointer to string.
231 push 1 ; stderr
232 call DosWrite
233 sub esp, DWORD * 4 ; clean stack.
234
235 mov eax, -10002
236 ret
237main ENDP
238
239;;
240; String length function.
241; @cproto int _Optlink strlen(const char *)
242; @returns eax = string length.
243; @param eax pointer to string.
244; @uses ecx, edx
245strlen PROC NEAR
246 push edi
247
248 xor ecx, ecx
249 dec ecx ; ecx <- 0ffffffffh
250 mov edi, eax ; esi <- string pointer
251 xor eax, eax ; scan until null terminator is found.
252
253 repnz scasb ; the actual scan.
254 neg ecx ; ecx is ffffffffh - string length
255 ; negate it to get the string length.
256 mov eax, ecx ; mov string length into eax (return value)
257 sub eax, 2 ; addjust it.
258
259 pop edi
260 ret
261strlen ENDP
262
263
264ifdef DEBUG
265;;
266; Write debug string to stdout.
267;
268; @param eax Pointer to string.
269; @uses
270; @equiv
271; @time
272; @sketch
273; @status
274; @author knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
275; @remark
276debugwrite PROC NEAR
277 LOCAL cbActual:dword
278 push ebx
279 push esi
280 push edi
281
282 ;
283 ; Write the arguments to stdout.
284 ;
285 push ebx
286 lea ebx, cbActual
287 push ebx ; cbActual - last arg for DosWrite
288 mov ebx, eax
289 call strlen
290 push eax ; Bytes to write
291 push ebx ; Pointer to string.
292 push 1 ; stdout
293 call DosWrite
294 sub esp, DWORD * 4 ; clean stack.
295
296 pop edi
297 pop esi
298 pop ebx
299 ret
300debugwrite ENDP
301
302endif
303
304
305CODE32 ENDS
306
307END main
Note: See TracBrowser for help on using the repository browser.