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