Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3675 GerdtR 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;;;;;;;;;;;;;;;;;;;;;;;;;;;; EXPRESSION PARSER ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
4
 
5
 
6
token_end       equ     1
7
token_reg       equ     2
8
token_hex       equ     3
9
token_add       equ     4
10
token_sub       equ     5
11
token_mul       equ     6
12
token_div       equ     7
13
token_lp        equ     8
14
token_rp        equ     9
15
token_err       equ     -1
16
 
17
 
18
;-----------------------------------------------------------------------------
19
;               Check if byte - some kind of instruction prefix
20
 
21
is_prefix:
22
        cmp     al, 0x64        ; fs:
23
        jz      .ret
24
        cmp     al, 0x65        ; gs:
25
        jz      .ret
26
        cmp     al, 0x66        ; use16/32
27
        jz      .ret
28
        cmp     al, 0x67        ; addr16/32
29
        jz      .ret
30
        cmp     al, 0xF0        ; lock
31
        jz      .ret
32
        cmp     al, 0xF2        ; repnz
33
        jz      .ret
34
        cmp     al, 0xF3        ; rep(z)
35
        jz      .ret
36
        cmp     al, 0x2E        ; cs:
37
        jz      .ret
38
        cmp     al, 0x36        ; ss:
39
        jz      .ret
40
        cmp     al, 0x3E        ; ds:
41
        jz      .ret
42
        cmp     al, 0x26        ; es:
43
 
44
    .ret:
45
        ret
46
 
47
;-----------------------------------------------------------------------------
48
;                   Check if byte is hex digit
49
 
50
is_hex_digit:
51
        cmp     al, '0'
52
        jb      .no
53
        cmp     al, '9'
54
        jbe     .09
55
        cmp     al, 'A'
56
        jb      .no
57
        cmp     al, 'F'
58
        jbe     .AF
59
        cmp     al, 'a'
60
        jb      .no
61
        cmp     al, 'f'
62
        jbe     .af
63
 
64
    .no:
65
        stc
66
        ret
67
 
68
    .09:
69
        sub     al, '0'
70
;       clc
71
        ret
72
 
73
    .AF:
74
        sub     al, 'A'-10
75
;       clc
76
        ret
77
 
78
    .af:
79
        sub     al, 'a'-10
80
;       clc
81
        ret
82
 
83
;-----------------------------------------------------------------------------
84
;                      Find register in the table
85
 
86
find_reg:
87
        mov     edi, reg_table
88
 
89
    .findreg:
90
        movzx   ecx, byte [edi]
91
        stc
92
        jecxz   .regnotfound
93
        inc     edi
94
        push    esi edi ecx
95
 
96
    @@:
97
        lodsb
98
        or      al, 20h
99
        scasb
100
        loopz   @b
101
        pop     ecx edi esi
102
        lea     edi, [edi+ecx+1]
103
        jnz     .findreg
104
        movzx   edi, byte [edi-1]
105
        add     esi, ecx
106
 
107
    .regnotfound:
108
        ret
109
 
110
;-----------------------------------------------------------------------------
111
;                      Tokenize expressions
112
 
113
expr_get_token:
114
        lodsb
115
        cmp     al, 0
116
        jz      .end_token
117
        cmp     al, ' '
118
        jbe     expr_get_token
119
        cmp     al, '+'
120
        jz      .add
121
        cmp     al, '-'
122
        jz      .sub
123
        cmp     al, '*'
124
        jz      .mul
125
        cmp     al, '/'
126
        jz      .div
127
        cmp     al, '('
128
        jz      .lp
129
        cmp     al, ')'
130
        jnz     .notsign
131
 
132
    .rp:
133
        mov     al, token_rp
134
        ret
135
 
136
    .div:
137
        mov     al, token_div
138
        ret
139
 
140
    .end_token:
141
        mov     al, token_end
142
        ret
143
 
144
    .add:
145
        mov     al, token_add
146
        ret
147
 
148
    .sub:
149
        mov     al, token_sub
150
        ret
151
 
152
    .mul:
153
        mov     al, token_mul
154
        ret
155
 
156
    .lp:
157
        mov     al, token_lp
158
        ret
159
 
160
    .notsign:
161
        dec     esi
162
        call    find_reg
163
        jc      .regnotfound
164
        mov     al, token_reg
165
        ret
166
 
167
    .regnotfound:
168
    ; test for symbol
169
        push    esi
170
 
171
    @@:
172
        lodsb
173
        cmp     al, ' '
174
        ja      @b
175
        push    eax
176
        mov     byte [esi], 0
177
        xchg    esi, [esp+4]
178
        call    find_symbol_name
179
        mov     edi, eax
180
        pop     eax
181
        xchg    esi, [esp]
182
        mov     byte [esi], al
183
        jc      @f
184
        add     esp, 4
185
        mov     al, token_hex
186
        ret
187
 
188
    @@:
189
        pop     esi
190
    ; test for hex number
191
        xor     ecx, ecx
192
        xor     edi, edi
193
        xor     eax, eax
194
 
195
    @@:
196
        lodsb
197
        call    is_hex_digit
198
        jc      @f
199
        shl     edi, 4
200
        or      edi, eax
201
        inc     ecx
202
        jmp     @b
203
 
204
    @@:
205
        dec     esi
206
        jecxz   .err
207
        cmp     ecx, 8
208
        ja      .err
209
        mov     al, token_hex
210
        ret
211
 
212
    .err:
213
        mov     al, token_err
214
        mov     esi, aParseError
215
        ret
216
 
217
;-----------------------------------------------------------------------------
218
 
219
expr_read2:
220
        cmp     al, token_hex
221
        jz      .hex
222
        cmp     al, token_reg
223
        jz      .reg
224
        cmp     al, token_lp
225
        jz      .lp
226
        mov     al, token_err
227
        mov     esi, aParseError
228
        ret
229
 
230
    .hex:
231
        mov     ebp, edi
232
 
233
    .ret:
234
        jmp     expr_get_token
235
 
236
    .reg:
237
        cmp     edi, 24
238
        jz      .eip
239
        sub     edi, 4
240
        jb      .8lo
241
        sub     edi, 4
242
        jb      .8hi
243
        sub     edi, 8
244
        jb      .16
245
        mov     ebp, [_eax+edi*4]
246
        jmp     .ret
247
 
248
    .16:
249
        movzx   ebp, word [_eax+(edi+8)*4]
250
        jmp     .ret
251
 
252
    .8lo:
253
        movzx   ebp, byte [_eax+(edi+4)*4]
254
        jmp     .ret
255
 
256
    .8hi:
257
        movzx   ebp, byte [_eax+(edi+4)*4+1]
258
        jmp     .ret
259
 
260
    .eip:
261
        mov     ebp, [_eip]
262
        jmp     .ret
263
 
264
    .lp:
265
        call    expr_get_token
266
        call    expr_read0
267
        cmp     al, token_err
268
        jz      @f
269
        cmp     al, token_rp
270
        jz      expr_get_token
271
        mov     al, token_err
272
        mov     esi, aParseError
273
 
274
    @@:
275
        ret
276
 
277
;-----------------------------------------------------------------------------
278
 
279
expr_read1:
280
        call    expr_read2
281
 
282
    .1:
283
        cmp     al, token_mul
284
        jz      .mul
285
        cmp     al, token_div
286
        jz      .div
287
        ret
288
 
289
    .mul:
290
        push    ebp
291
        call    expr_get_token
292
        call    expr_read2
293
        pop     edx
294
    ; ebp := edx*ebp
295
        imul    ebp, edx
296
        jmp     .1
297
 
298
    .div:
299
        push    ebp
300
        call    expr_get_token
301
        call    expr_read2
302
        pop     edx
303
    ; ebp := edx/ebp
304
        test    ebp, ebp
305
        jz      .div0
306
        push    eax
307
        xor     eax, eax
308
        xchg    eax, edx
309
        div     ebp
310
        xchg    eax, ebp
311
        pop     eax
312
        jmp     .1
313
 
314
    .div0:
315
        mov     al, token_err
316
        mov     esi, aDivByZero
317
        ret
318
 
319
;-----------------------------------------------------------------------------
320
 
321
expr_read0:
322
        xor     ebp, ebp
323
        cmp     al, token_add
324
        jz      .add
325
        cmp     al, token_sub
326
        jz      .sub
327
        call    expr_read1
328
 
329
    .1:
330
        cmp     al, token_add
331
        jz      .add
332
        cmp     al, token_sub
333
        jz      .sub
334
        ret
335
 
336
    .add:
337
        push    ebp
338
        call    expr_get_token
339
        call    expr_read1
340
        pop     edx
341
    ; ebp := edx+ebp
342
        add     ebp, edx
343
        jmp     .1
344
 
345
    .sub:
346
        push    ebp
347
        call    expr_get_token
348
        call    expr_read1
349
        pop     edx
350
    ; ebp := edx-ebp
351
        xchg    edx, ebp
352
        sub     ebp, edx
353
        jmp     .1
354
 
355
;-----------------------------------------------------------------------------
356
 
357
; in: esi->expression
358
; out: CF=1 if error
359
;      CF=0 and ebp=value if ok
360
calc_expression:
361
        call    expr_get_token
362
        call    expr_read0
363
        cmp     al, token_end
364
        jz      .end
365
        cmp     al, token_err
366
        jz      @f
367
        mov     esi, aParseError
368
 
369
    @@:
370
        call    put_message
371
        stc
372
        ret
373
 
374
    .end:
375
        clc
376
        ret
377
 
378
;-----------------------------------------------------------------------------
379
 
380
get_arg:
381
        lodsb
382
        cmp     al, ' '
383
        ja      get_arg
384
        mov     byte [esi-1], 0
385
        cmp     al, 0
386
        jnz     .skip_spaces
387
        dec     esi
388
 
389
    .skip_spaces:
390
        lodsb
391
        cmp     al, 0
392
        jz      @f
393
        cmp     al, ' '
394
        jbe     .skip_spaces
395
 
396
    @@:
397
        dec     esi
398
        ret
399
 
400
 
401
 
402
; vim: ft=fasm tabstop=4
403