| 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
 | 
|---|