| 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 | ;
|
|---|
| 29 | MAX_ARG_LENGTH EQU 1000h
|
|---|
| 30 |
|
|---|
| 31 | ;
|
|---|
| 32 | ; Structures and Typedefs
|
|---|
| 33 | ;
|
|---|
| 34 | RXSTRING STRUC
|
|---|
| 35 | cb dd ?
|
|---|
| 36 | pach dd ?
|
|---|
| 37 | RXSTRING ENDS
|
|---|
| 38 |
|
|---|
| 39 |
|
|---|
| 40 |
|
|---|
| 41 | DATA32 segment dword public 'DATA' use32
|
|---|
| 42 | ;
|
|---|
| 43 | ; Global Variables
|
|---|
| 44 | ;
|
|---|
| 45 | ifdef DEBUG
|
|---|
| 46 | ;Debug stuff
|
|---|
| 47 | szMsgDebug1 db "Debug1",13,10,0
|
|---|
| 48 | szMsgDebug2 db "Debug2",13,10,0
|
|---|
| 49 | szMsgDebug3 db "Debug3",13,10,0
|
|---|
| 50 | endif
|
|---|
| 51 |
|
|---|
| 52 | ;Error messages.
|
|---|
| 53 | szMsgScriptnameTooLong db "Fatal error: The scriptname is too long.",13,10,0
|
|---|
| 54 | szMsgArgumentsTooLong db "Fatal error: The arguments are too long.",13,10,0
|
|---|
| 55 | szMsgRexxStartFailed db "Fatal error: RexxStart failed.",13,10,0
|
|---|
| 56 |
|
|---|
| 57 | ;Rexx argument string
|
|---|
| 58 | rxstrArgs RXSTRING <0, offset szArgs>
|
|---|
| 59 |
|
|---|
| 60 | ;Command env. name - RexxStart param - dont't know what it is used for...
|
|---|
| 61 | szEnv db "hmm", 0
|
|---|
| 62 |
|
|---|
| 63 | ;Some uninitialized buffers
|
|---|
| 64 | szScriptname db 260d dup (?)
|
|---|
| 65 | szArgs db MAX_ARG_LENGTH dup (?)
|
|---|
| 66 |
|
|---|
| 67 | DATA32 ends
|
|---|
| 68 |
|
|---|
| 69 |
|
|---|
| 70 |
|
|---|
| 71 | CODE32 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
|
|---|
| 89 | main PROC NEAR
|
|---|
| 90 | hModule EQU [ebp + 08h]
|
|---|
| 91 | pEnvironment EQU [ebp + 10h]
|
|---|
| 92 | pCommandline 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 |
|
|---|
| 130 | loop1:
|
|---|
| 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 |
|
|---|
| 148 | endloop1:
|
|---|
| 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.
|
|---|
| 158 | loop2:
|
|---|
| 159 | mov al, byte ptr [esi]
|
|---|
| 160 | cmp al, ' '
|
|---|
| 161 | jne endloop2
|
|---|
| 162 | inc esi
|
|---|
| 163 | jmp loop2
|
|---|
| 164 | endloop2:
|
|---|
| 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 |
|
|---|
| 181 | callrexx:
|
|---|
| 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 | ;
|
|---|
| 212 | Scriptname_Too_Long:
|
|---|
| 213 | mov eax, offset szMsgScriptnameTooLong
|
|---|
| 214 | jmp PrintError
|
|---|
| 215 |
|
|---|
| 216 | Arguments_Too_Long:
|
|---|
| 217 | mov eax, offset szMsgArgumentsTooLong
|
|---|
| 218 | jmp PrintError
|
|---|
| 219 |
|
|---|
| 220 | RexxStartFailed:
|
|---|
| 221 | mov eax, offset szMsgRexxStartFailed
|
|---|
| 222 | jmp PrintError
|
|---|
| 223 |
|
|---|
| 224 | PrintError:
|
|---|
| 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
|
|---|
| 237 | main 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
|
|---|
| 245 | strlen 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
|
|---|
| 261 | strlen ENDP
|
|---|
| 262 |
|
|---|
| 263 |
|
|---|
| 264 | ifdef 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
|
|---|
| 276 | debugwrite 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
|
|---|
| 300 | debugwrite ENDP
|
|---|
| 301 |
|
|---|
| 302 | endif
|
|---|
| 303 |
|
|---|
| 304 |
|
|---|
| 305 | CODE32 ENDS
|
|---|
| 306 |
|
|---|
| 307 | END main
|
|---|