"Fossies" - the Fresh Open Source Software Archive

Member "fasm/source/exprpars.inc" (9 Feb 2020, 21911 Bytes) of package /linux/misc/fasm-1.73.22.tgz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) fasm source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "exprpars.inc": 1.73.21_vs_1.73.22.

    1 
    2 ; flat assembler core
    3 ; Copyright (c) 1999-2020, Tomasz Grysztar.
    4 ; All rights reserved.
    5 
    6 convert_expression:
    7     push    ebp
    8     call    get_fp_value
    9     jnc fp_expression
   10     mov [current_offset],esp
   11       expression_loop:
   12     push    edi
   13     mov edi,single_operand_operators
   14     call    get_operator
   15     pop edi
   16     or  al,al
   17     jz  expression_element
   18     cmp al,82h
   19     je  expression_loop
   20     push    eax
   21     jmp expression_loop
   22       expression_element:
   23     mov al,[esi]
   24     cmp al,1Ah
   25     je  expression_number
   26     cmp al,22h
   27     je  expression_number
   28     cmp al,'('
   29     je  expression_number
   30     mov al,'!'
   31     stos    byte [edi]
   32     jmp expression_operator
   33       expression_number:
   34     call    convert_number
   35       expression_operator:
   36     push    edi
   37     mov edi,operators
   38     call    get_operator
   39     pop edi
   40     or  al,al
   41     jz  expression_end
   42       operators_loop:
   43     cmp esp,[current_offset]
   44     je  push_operator
   45     mov bl,al
   46     and bl,0F0h
   47     mov bh,byte [esp]
   48     and bh,0F0h
   49     cmp bl,bh
   50     ja  push_operator
   51     pop ebx
   52     mov byte [edi],bl
   53     inc edi
   54     jmp operators_loop
   55       push_operator:
   56     push    eax
   57     jmp expression_loop
   58       expression_end:
   59     cmp esp,[current_offset]
   60     je  expression_converted
   61     pop eax
   62     stos    byte [edi]
   63     jmp expression_end
   64       expression_converted:
   65     pop ebp
   66     ret
   67       fp_expression:
   68     mov al,'.'
   69     stos    byte [edi]
   70     mov eax,[fp_value]
   71     stos    dword [edi]
   72     mov eax,[fp_value+4]
   73     stos    dword [edi]
   74     mov eax,[fp_value+8]
   75     stos    dword [edi]
   76     pop ebp
   77     ret
   78 
   79 convert_number:
   80     lea eax,[edi+20h]
   81     mov edx,[memory_end]
   82     cmp [source_start],0
   83     je  check_memory_for_number
   84     mov edx,[labels_list]
   85       check_memory_for_number:
   86     cmp eax,edx
   87     jae out_of_memory
   88     mov eax,esp
   89     sub eax,[stack_limit]
   90     cmp eax,100h
   91     jb  stack_overflow
   92     cmp byte [esi],'('
   93     je  expression_value
   94     inc edi
   95     call    get_number
   96     jc  symbol_value
   97     or  ebp,ebp
   98     jz  valid_number
   99     mov byte [edi-1],0Fh
  100     ret
  101       valid_number:
  102     cmp dword [edi+4],0
  103     jne qword_number
  104     cmp word [edi+2],0
  105     jne dword_number
  106     cmp byte [edi+1],0
  107     jne word_number
  108       byte_number:
  109     mov byte [edi-1],1
  110     inc edi
  111     ret
  112       qword_number:
  113     mov byte [edi-1],8
  114     add edi,8
  115     ret
  116       dword_number:
  117     mov byte [edi-1],4
  118     scas    dword [edi]
  119     ret
  120       word_number:
  121     mov byte [edi-1],2
  122     scas    word [edi]
  123     ret
  124       expression_value:
  125     inc esi
  126     push    [current_offset]
  127     call    convert_expression
  128     pop [current_offset]
  129     lods    byte [esi]
  130     cmp al,')'
  131     je  subexpression_closed
  132     dec esi
  133     mov al,'!'
  134     stosb
  135       subexpression_closed:
  136     ret
  137       symbol_value:
  138     cmp [source_start],0
  139     je  preprocessor_value
  140     push    edi esi
  141     lods    word [esi]
  142     cmp al,1Ah
  143     jne no_address_register
  144     movzx   ecx,ah
  145     call    get_symbol
  146     jc  no_address_register
  147     cmp al,10h
  148     jne no_address_register
  149     mov al,ah
  150     shr ah,4
  151     cmp ah,4
  152     je  register_value
  153     and ah,not 1
  154     cmp ah,8
  155     je  register_value
  156     cmp ah,0Ch
  157     jae register_value
  158     cmp ah,6
  159     je  register_value
  160     cmp al,23h
  161     je  register_value
  162     cmp al,25h
  163     je  register_value
  164     cmp al,26h
  165     je  register_value
  166     cmp al,27h
  167     je  register_value
  168       no_address_register:
  169     pop esi
  170     mov edi,directive_operators
  171     call    get_operator
  172     pop edi
  173     or  al,al
  174     jnz broken_value
  175     lods    byte [esi]
  176     cmp al,1Ah
  177     jne invalid_value
  178     lods    byte [esi]
  179     movzx   ecx,al
  180     call    get_label_id
  181       store_label_value:
  182     mov byte [edi-1],11h
  183     stos    dword [edi]
  184     ret
  185       broken_value:
  186     mov eax,0Fh
  187     jmp store_label_value
  188       register_value:
  189     pop edx edi
  190     mov byte [edi-1],10h
  191     stos    byte [edi]
  192     ret
  193       preprocessor_value:
  194     dec edi
  195     cmp [hash_tree],0
  196     je  invalid_value
  197     lods    byte [esi]
  198     cmp al,1Ah
  199     jne invalid_value
  200     lods    byte [esi]
  201     mov cl,al
  202     mov ch,10b
  203     call    get_preprocessor_symbol
  204     jc  invalid_value
  205     push    esi
  206     mov esi,[edx+8]
  207     push    [current_offset]
  208     call    convert_expression
  209     pop [current_offset]
  210     pop esi
  211     ret
  212 
  213 get_number:
  214     xor ebp,ebp
  215     lods    byte [esi]
  216     cmp al,22h
  217     je  get_text_number
  218     cmp al,1Ah
  219     jne not_number
  220     lods    byte [esi]
  221     movzx   ecx,al
  222     mov [number_start],esi
  223     mov al,[esi]
  224     cmp al,'$'
  225     je  number_begin
  226     sub al,30h
  227     cmp al,9
  228     ja  invalid_number
  229       number_begin:
  230     mov ebx,esi
  231     add esi,ecx
  232     push    esi
  233     dec esi
  234     mov dword [edi],0
  235     mov dword [edi+4],0
  236     cmp byte [ebx],'$'
  237     je  pascal_hex_number
  238     cmp word [ebx],'0x'
  239     je  get_hex_number
  240     mov al,[esi]
  241     dec esi
  242     cmp al,'h'
  243     je  get_hex_number
  244     cmp al,'b'
  245     je  get_bin_number
  246     cmp al,'d'
  247     je  get_dec_number
  248     cmp al,'o'
  249     je  get_oct_number
  250     cmp al,'q'
  251     je  get_oct_number
  252     cmp al,'H'
  253     je  get_hex_number
  254     cmp al,'B'
  255     je  get_bin_number
  256     cmp al,'D'
  257     je  get_dec_number
  258     cmp al,'O'
  259     je  get_oct_number
  260     cmp al,'Q'
  261     je  get_oct_number
  262     inc esi
  263       get_dec_number:
  264     mov ebx,esi
  265     mov esi,[number_start]
  266       get_dec_digit:
  267     cmp esi,ebx
  268     ja  number_ok
  269     cmp byte [esi],27h
  270     je  next_dec_digit
  271     cmp byte [esi],'_'
  272     je  next_dec_digit
  273     xor edx,edx
  274     mov eax,[edi]
  275     shld    edx,eax,2
  276     shl eax,2
  277     add eax,[edi]
  278     adc edx,0
  279     add eax,eax
  280     adc edx,edx
  281     mov [edi],eax
  282     mov eax,[edi+4]
  283     add eax,eax
  284     jc  dec_out_of_range
  285     add eax,eax
  286     jc  dec_out_of_range
  287     add eax,[edi+4]
  288     jc  dec_out_of_range
  289     add eax,eax
  290     jc  dec_out_of_range
  291     add eax,edx
  292     jc  dec_out_of_range
  293     mov [edi+4],eax
  294     movzx   eax,byte [esi]
  295     sub al,30h
  296     jc  bad_number
  297     cmp al,9
  298     ja  bad_number
  299     add [edi],eax
  300     adc dword [edi+4],0
  301     jc  dec_out_of_range
  302       next_dec_digit:
  303     inc esi
  304     jmp get_dec_digit
  305       dec_out_of_range:
  306     cmp esi,ebx
  307     ja  dec_out_of_range_finished
  308     lods    byte [esi]
  309     cmp al,27h
  310     je  bad_number
  311     cmp al,'_'
  312     je  bad_number
  313     sub al,30h
  314     jc  bad_number
  315     cmp al,9
  316     ja  bad_number
  317     jmp dec_out_of_range
  318       dec_out_of_range_finished:
  319     or  ebp,-1
  320     jmp number_ok
  321       bad_number:
  322     pop eax
  323       invalid_number:
  324     mov esi,[number_start]
  325     dec esi
  326       not_number:
  327     dec esi
  328     stc
  329     ret
  330       get_bin_number:
  331     xor bl,bl
  332       get_bin_digit:
  333     cmp esi,[number_start]
  334     jb  number_ok
  335     movzx   eax,byte [esi]
  336     cmp al,27h
  337     je  bin_digit_skip
  338     cmp al,'_'
  339     je  bin_digit_skip
  340     sub al,30h
  341     cmp al,1
  342     ja  bad_number
  343     xor edx,edx
  344     mov cl,bl
  345     dec esi
  346     cmp bl,64
  347     je  bin_out_of_range
  348     inc bl
  349     cmp cl,32
  350     jae bin_digit_high
  351     shl eax,cl
  352     or  dword [edi],eax
  353     jmp get_bin_digit
  354       bin_digit_high:
  355     sub cl,32
  356     shl eax,cl
  357     or  dword [edi+4],eax
  358     jmp get_bin_digit
  359       bin_out_of_range:
  360     or  al,al
  361     jz  get_bin_digit
  362     or  ebp,-1
  363     jmp get_bin_digit
  364       bin_digit_skip:
  365     dec esi
  366     jmp get_bin_digit
  367       pascal_hex_number:
  368     cmp cl,1
  369     je  bad_number
  370       get_hex_number:
  371     xor bl,bl
  372       get_hex_digit:
  373     cmp esi,[number_start]
  374     jb  number_ok
  375     movzx   eax,byte [esi]
  376     cmp al,27h
  377     je  hex_digit_skip
  378     cmp al,'_'
  379     je  hex_digit_skip
  380     cmp al,'x'
  381     je  hex_number_ok
  382     cmp al,'$'
  383     je  pascal_hex_ok
  384     sub al,30h
  385     cmp al,9
  386     jbe hex_digit_ok
  387     sub al,7
  388     cmp al,15
  389     jbe hex_letter_digit_ok
  390     sub al,20h
  391     cmp al,15
  392     ja  bad_number
  393       hex_letter_digit_ok:
  394     cmp al,10
  395     jb  bad_number
  396       hex_digit_ok:
  397     xor edx,edx
  398     mov cl,bl
  399     dec esi
  400     cmp bl,64
  401     je  hex_out_of_range
  402     add bl,4
  403     cmp cl,32
  404     jae hex_digit_high
  405     shl eax,cl
  406     or  dword [edi],eax
  407     jmp get_hex_digit
  408       hex_digit_high:
  409     sub cl,32
  410     shl eax,cl
  411     or  dword [edi+4],eax
  412     jmp get_hex_digit
  413       hex_out_of_range:
  414     or  al,al
  415     jz  get_hex_digit
  416     or  ebp,-1
  417     jmp get_hex_digit
  418       hex_digit_skip:
  419     dec esi
  420     jmp get_hex_digit
  421       get_oct_number:
  422     xor bl,bl
  423       get_oct_digit:
  424     cmp esi,[number_start]
  425     jb  number_ok
  426     movzx   eax,byte [esi]
  427     cmp al,27h
  428     je  oct_digit_skip
  429     cmp al,'_'
  430     je  oct_digit_skip
  431     sub al,30h
  432     cmp al,7
  433     ja  bad_number
  434       oct_digit_ok:
  435     xor edx,edx
  436     mov cl,bl
  437     dec esi
  438     cmp bl,63
  439     ja  oct_out_of_range
  440     jne oct_range_ok
  441     cmp al,1
  442     ja  oct_out_of_range
  443       oct_range_ok:
  444     add bl,3
  445     cmp cl,30
  446     je  oct_digit_wrap
  447     ja  oct_digit_high
  448     shl eax,cl
  449     or  dword [edi],eax
  450     jmp get_oct_digit
  451       oct_digit_wrap:
  452     shl eax,cl
  453     adc dword [edi+4],0
  454     or  dword [edi],eax
  455     jmp get_oct_digit
  456       oct_digit_high:
  457     sub cl,32
  458     shl eax,cl
  459     or  dword [edi+4],eax
  460     jmp get_oct_digit
  461       oct_digit_skip:
  462     dec esi
  463     jmp get_oct_digit
  464       oct_out_of_range:
  465     or  al,al
  466     jz  get_oct_digit
  467     or  ebp,-1
  468     jmp get_oct_digit
  469       hex_number_ok:
  470     dec esi
  471       pascal_hex_ok:
  472     cmp esi,[number_start]
  473     jne bad_number
  474       number_ok:
  475     pop esi
  476       number_done:
  477     clc
  478     ret
  479       get_text_number:
  480     lods    dword [esi]
  481     mov edx,eax
  482     xor bl,bl
  483     mov dword [edi],0
  484     mov dword [edi+4],0
  485       get_text_character:
  486     sub edx,1
  487     jc  number_done
  488     movzx   eax,byte [esi]
  489     inc esi
  490     mov cl,bl
  491     cmp bl,64
  492     je  text_out_of_range
  493     add bl,8
  494     cmp cl,32
  495     jae text_character_high
  496     shl eax,cl
  497     or  dword [edi],eax
  498     jmp get_text_character
  499       text_character_high:
  500     sub cl,32
  501     shl eax,cl
  502     or  dword [edi+4],eax
  503     jmp get_text_character
  504       text_out_of_range:
  505     or  ebp,-1
  506     jmp get_text_character
  507 
  508 get_fp_value:
  509     push    edi esi
  510     lods    byte [esi]
  511     cmp al,1Ah
  512     je  fp_value_start
  513     cmp al,'-'
  514     je  fp_sign_ok
  515     cmp al,'+'
  516     jne not_fp_value
  517       fp_sign_ok:
  518     lods    byte [esi]
  519     cmp al,1Ah
  520     jne not_fp_value
  521       fp_value_start:
  522     lods    byte [esi]
  523     movzx   ecx,al
  524     cmp cl,1
  525     jbe not_fp_value
  526     lea edx,[esi+1]
  527     xor ah,ah
  528       check_fp_value:
  529     lods    byte [esi]
  530     cmp al,'.'
  531     je  fp_character_dot
  532     cmp al,'E'
  533     je  fp_character_exp
  534     cmp al,'e'
  535     je  fp_character_exp
  536     cmp al,'F'
  537     je  fp_last_character
  538     cmp al,'f'
  539     je  fp_last_character
  540       digit_expected:
  541     cmp al,'0'
  542     jb  not_fp_value
  543     cmp al,'9'
  544     ja  not_fp_value
  545     jmp fp_character_ok
  546       fp_character_dot:
  547     cmp esi,edx
  548     je  not_fp_value
  549     or  ah,ah
  550     jnz not_fp_value
  551     or  ah,1
  552     lods    byte [esi]
  553     loop    digit_expected
  554       not_fp_value:
  555     pop esi edi
  556     stc
  557     ret
  558       fp_last_character:
  559     cmp cl,1
  560     jne not_fp_value
  561     or  ah,4
  562     jmp fp_character_ok
  563       fp_character_exp:
  564     cmp esi,edx
  565     je  not_fp_value
  566     cmp ah,1
  567     ja  not_fp_value
  568     or  ah,2
  569     cmp ecx,1
  570     jne fp_character_ok
  571     cmp byte [esi],'+'
  572     je  fp_exp_sign
  573     cmp byte [esi],'-'
  574     jne fp_character_ok
  575       fp_exp_sign:
  576     inc esi
  577     cmp byte [esi],1Ah
  578     jne not_fp_value
  579     inc esi
  580     lods    byte [esi]
  581     movzx   ecx,al
  582     inc ecx
  583       fp_character_ok:
  584     dec ecx
  585     jnz check_fp_value
  586     or  ah,ah
  587     jz  not_fp_value
  588     pop esi
  589     lods    byte [esi]
  590     mov [fp_sign],0
  591     cmp al,1Ah
  592     je  fp_get
  593     inc esi
  594     cmp al,'+'
  595     je  fp_get
  596     mov [fp_sign],1
  597       fp_get:
  598     lods    byte [esi]
  599     movzx   ecx,al
  600     xor edx,edx
  601     mov edi,fp_value
  602     mov [edi],edx
  603     mov [edi+4],edx
  604     mov [edi+12],edx
  605     call    fp_optimize
  606     mov [fp_format],0
  607     mov al,[esi]
  608       fp_before_dot:
  609     lods    byte [esi]
  610     cmp al,'.'
  611     je  fp_dot
  612     cmp al,'E'
  613     je  fp_exponent
  614     cmp al,'e'
  615     je  fp_exponent
  616     cmp al,'F'
  617     je  fp_done
  618     cmp al,'f'
  619     je  fp_done
  620     sub al,30h
  621     mov edi,fp_value+16
  622     xor edx,edx
  623     mov dword [edi+12],edx
  624     mov dword [edi],edx
  625     mov dword [edi+4],edx
  626     mov [edi+7],al
  627     mov dl,7
  628     mov dword [edi+8],edx
  629     call    fp_optimize
  630     mov edi,fp_value
  631     push    ecx
  632     mov ecx,10
  633     call    fp_mul
  634     pop ecx
  635     mov ebx,fp_value+16
  636     call    fp_add
  637     loop    fp_before_dot
  638       fp_dot:
  639     mov edi,fp_value+16
  640     xor edx,edx
  641     mov [edi],edx
  642     mov [edi+4],edx
  643     mov byte [edi+7],80h
  644     mov [edi+8],edx
  645     mov dword [edi+12],edx
  646     dec ecx
  647     jz  fp_done
  648       fp_after_dot:
  649     lods    byte [esi]
  650     cmp al,'E'
  651     je  fp_exponent
  652     cmp al,'e'
  653     je  fp_exponent
  654     cmp al,'F'
  655     je  fp_done
  656     cmp al,'f'
  657     je  fp_done
  658     inc [fp_format]
  659     cmp [fp_format],80h
  660     jne fp_counter_ok
  661     mov [fp_format],7Fh
  662       fp_counter_ok:
  663     dec esi
  664     mov edi,fp_value+16
  665     push    ecx
  666     mov ecx,10
  667     call    fp_div
  668     push    dword [edi]
  669     push    dword [edi+4]
  670     push    dword [edi+8]
  671     push    dword [edi+12]
  672     lods    byte [esi]
  673     sub al,30h
  674     movzx   ecx,al
  675     call    fp_mul
  676     mov ebx,edi
  677     mov edi,fp_value
  678     call    fp_add
  679     mov edi,fp_value+16
  680     pop dword [edi+12]
  681     pop dword [edi+8]
  682     pop dword [edi+4]
  683     pop dword [edi]
  684     pop ecx
  685     dec ecx
  686     jnz fp_after_dot
  687     jmp fp_done
  688       fp_exponent:
  689     or  [fp_format],80h
  690     xor edx,edx
  691     xor ebp,ebp
  692     dec ecx
  693     jnz get_exponent
  694     cmp byte [esi],'+'
  695     je  fp_exponent_sign
  696     cmp byte [esi],'-'
  697     jne fp_done
  698     not ebp
  699       fp_exponent_sign:
  700     add esi,2
  701     lods    byte [esi]
  702     movzx   ecx,al
  703       get_exponent:
  704     movzx   eax,byte [esi]
  705     inc esi
  706     sub al,30h
  707     cmp al,10
  708     jae exponent_ok
  709     imul    edx,10
  710     cmp edx,8000h
  711     jae value_out_of_range
  712     add edx,eax
  713     loop    get_exponent
  714       exponent_ok:
  715     mov edi,fp_value
  716     or  edx,edx
  717     jz  fp_done
  718     mov ecx,edx
  719     or  ebp,ebp
  720     jnz fp_negative_power
  721       fp_power:
  722     push    ecx
  723     mov ecx,10
  724     call    fp_mul
  725     pop ecx
  726     loop    fp_power
  727     jmp fp_done
  728       fp_negative_power:
  729     push    ecx
  730     mov ecx,10
  731     call    fp_div
  732     pop ecx
  733     loop    fp_negative_power
  734       fp_done:
  735     mov edi,fp_value
  736     mov al,[fp_format]
  737     mov [edi+10],al
  738     mov al,[fp_sign]
  739     mov [edi+11],al
  740     test    byte [edi+15],80h
  741     jz  fp_ok
  742     add dword [edi],1
  743     adc dword [edi+4],0
  744     jnc fp_ok
  745     mov eax,[edi+4]
  746     shrd    [edi],eax,1
  747     shr eax,1
  748     or  eax,80000000h
  749     mov [edi+4],eax
  750     inc word [edi+8]
  751       fp_ok:
  752     pop edi
  753     clc
  754     ret
  755       fp_mul:
  756     or  ecx,ecx
  757     jz  fp_zero
  758     mov eax,[edi+12]
  759     mul ecx
  760     mov [edi+12],eax
  761     mov ebx,edx
  762     mov eax,[edi]
  763     mul ecx
  764     add eax,ebx
  765     adc edx,0
  766     mov [edi],eax
  767     mov ebx,edx
  768     mov eax,[edi+4]
  769     mul ecx
  770     add eax,ebx
  771     adc edx,0
  772     mov [edi+4],eax
  773       .loop:
  774     or  edx,edx
  775     jz  .done
  776     mov eax,[edi]
  777     shrd    [edi+12],eax,1
  778     mov eax,[edi+4]
  779     shrd    [edi],eax,1
  780     shrd    eax,edx,1
  781     mov [edi+4],eax
  782     shr edx,1
  783     inc dword [edi+8]
  784     cmp dword [edi+8],8000h
  785     jge value_out_of_range
  786     jmp .loop
  787       .done:
  788     ret
  789       fp_div:
  790     mov eax,[edi+4]
  791     xor edx,edx
  792     div ecx
  793     mov [edi+4],eax
  794     mov eax,[edi]
  795     div ecx
  796     mov [edi],eax
  797     mov eax,[edi+12]
  798     div ecx
  799     mov [edi+12],eax
  800     mov ebx,eax
  801     or  ebx,[edi]
  802     or  ebx,[edi+4]
  803     jz  fp_zero
  804       .loop:
  805     test    byte [edi+7],80h
  806     jnz .exp_ok
  807     mov eax,[edi]
  808     shld    [edi+4],eax,1
  809     mov eax,[edi+12]
  810     shld    [edi],eax,1
  811     add eax,eax
  812     mov [edi+12],eax
  813     dec dword [edi+8]
  814     add edx,edx
  815     jmp .loop
  816       .exp_ok:
  817     mov eax,edx
  818     xor edx,edx
  819     div ecx
  820     add [edi+12],eax
  821     adc dword [edi],0
  822     adc dword [edi+4],0
  823     jnc .done
  824     mov eax,[edi+4]
  825     mov ebx,[edi]
  826     shrd    [edi],eax,1
  827     shrd    [edi+12],ebx,1
  828     shr eax,1
  829     or  eax,80000000h
  830     mov [edi+4],eax
  831     inc dword [edi+8]
  832       .done:
  833     ret
  834       fp_add:
  835     cmp dword [ebx+8],8000h
  836     je  .done
  837     cmp dword [edi+8],8000h
  838     je  .copy
  839     mov eax,[ebx+8]
  840     cmp eax,[edi+8]
  841     jge .exp_ok
  842     mov eax,[edi+8]
  843       .exp_ok:
  844     call    .change_exp
  845     xchg    ebx,edi
  846     call    .change_exp
  847     xchg    ebx,edi
  848     mov edx,[ebx+12]
  849     mov eax,[ebx]
  850     mov ebx,[ebx+4]
  851     add [edi+12],edx
  852     adc [edi],eax
  853     adc [edi+4],ebx
  854     jnc .done
  855     mov eax,[edi]
  856     shrd    [edi+12],eax,1
  857     mov eax,[edi+4]
  858     shrd    [edi],eax,1
  859     shr eax,1
  860     or  eax,80000000h
  861     mov [edi+4],eax
  862     inc dword [edi+8]
  863       .done:
  864     ret
  865       .copy:
  866     mov eax,[ebx]
  867     mov [edi],eax
  868     mov eax,[ebx+4]
  869     mov [edi+4],eax
  870     mov eax,[ebx+8]
  871     mov [edi+8],eax
  872     mov eax,[ebx+12]
  873     mov [edi+12],eax
  874     ret
  875       .change_exp:
  876     push    ecx
  877     mov ecx,eax
  878     sub ecx,[ebx+8]
  879     mov edx,[ebx+4]
  880     jecxz   .exp_done
  881       .exp_loop:
  882     mov ebp,[ebx]
  883     shrd    [ebx+12],ebp,1
  884     shrd    [ebx],edx,1
  885     shr edx,1
  886     inc dword [ebx+8]
  887     loop    .exp_loop
  888       .exp_done:
  889     mov [ebx+4],edx
  890     pop ecx
  891     ret
  892       fp_optimize:
  893     mov eax,[edi]
  894     mov ebp,[edi+4]
  895     or  ebp,[edi]
  896     or  ebp,[edi+12]
  897     jz  fp_zero
  898       .loop:
  899     test    byte [edi+7],80h
  900     jnz .done
  901     shld    [edi+4],eax,1
  902     mov ebp,[edi+12]
  903     shld    eax,ebp,1
  904     mov [edi],eax
  905     shl dword [edi+12],1
  906     dec dword [edi+8]
  907     jmp .loop
  908       .done:
  909     ret
  910       fp_zero:
  911     mov dword [edi+8],8000h
  912     ret
  913 
  914 preevaluate_logical_expression:
  915     xor al,al
  916   preevaluate_embedded_logical_expression:
  917     mov [logical_value_wrapping],al
  918     push    edi
  919     call    preevaluate_logical_value
  920       preevaluation_loop:
  921     cmp al,0FFh
  922     je  invalid_logical_expression
  923     mov dl,[esi]
  924     inc esi
  925     cmp dl,'|'
  926     je  preevaluate_or
  927     cmp dl,'&'
  928     je  preevaluate_and
  929     cmp dl,92h
  930     je  preevaluation_done
  931     or  dl,dl
  932     jnz invalid_logical_expression
  933       preevaluation_done:
  934     pop edx
  935     dec esi
  936     ret
  937       preevaluate_or:
  938     cmp al,'1'
  939     je  quick_true
  940     cmp al,'0'
  941     je  leave_only_following
  942     push    edi
  943     mov al,dl
  944     stos    byte [edi]
  945     call    preevaluate_logical_value
  946     pop ebx
  947     cmp al,'0'
  948     je  leave_only_preceding
  949     cmp al,'1'
  950     jne preevaluation_loop
  951     stos    byte [edi]
  952     xor al,al
  953     jmp preevaluation_loop
  954       preevaluate_and:
  955     cmp al,'0'
  956     je  quick_false
  957     cmp al,'1'
  958     je  leave_only_following
  959     push    edi
  960     mov al,dl
  961     stos    byte [edi]
  962     call    preevaluate_logical_value
  963     pop ebx
  964     cmp al,'1'
  965     je  leave_only_preceding
  966     cmp al,'0'
  967     jne preevaluation_loop
  968     stos    byte [edi]
  969     xor al,al
  970     jmp preevaluation_loop
  971       leave_only_following:
  972     mov edi,[esp]
  973     call    preevaluate_logical_value
  974     jmp preevaluation_loop
  975       leave_only_preceding:
  976     mov edi,ebx
  977     xor al,al
  978     jmp preevaluation_loop
  979       quick_true:
  980     call    skip_logical_value
  981     jc  invalid_logical_expression
  982     mov edi,[esp]
  983     mov al,'1'
  984     jmp preevaluation_loop
  985       quick_false:
  986     call    skip_logical_value
  987     jc  invalid_logical_expression
  988     mov edi,[esp]
  989     mov al,'0'
  990     jmp preevaluation_loop
  991       invalid_logical_expression:
  992     pop edi
  993     mov esi,edi
  994     mov al,0FFh
  995     stos    byte [edi]
  996     ret
  997   skip_logical_value:
  998     cmp byte [esi],'~'
  999     jne negation_skipped
 1000     inc esi
 1001     jmp skip_logical_value
 1002       negation_skipped:
 1003     mov al,[esi]
 1004     cmp al,91h
 1005     jne skip_simple_logical_value
 1006     inc esi
 1007     xchg    al,[logical_value_wrapping]
 1008     push    eax
 1009       skip_logical_expression:
 1010     call    skip_logical_value
 1011     lods    byte [esi]
 1012     or  al,al
 1013     jz  wrongly_structured_logical_expression
 1014     cmp al,0Fh
 1015     je  wrongly_structured_logical_expression
 1016     cmp al,'|'
 1017     je  skip_logical_expression
 1018     cmp al,'&'
 1019     je  skip_logical_expression
 1020     cmp al,92h
 1021     jne wrongly_structured_logical_expression
 1022     pop eax
 1023     mov [logical_value_wrapping],al
 1024       logical_value_skipped:
 1025     clc
 1026     ret
 1027       wrongly_structured_logical_expression:
 1028     pop eax
 1029     stc
 1030     ret
 1031       skip_simple_logical_value:
 1032     mov [logical_value_parentheses],0
 1033       find_simple_logical_value_end:
 1034     mov al,[esi]
 1035     or  al,al
 1036     jz  logical_value_skipped
 1037     cmp al,0Fh
 1038     je  logical_value_skipped
 1039     cmp al,'|'
 1040     je  logical_value_skipped
 1041     cmp al,'&'
 1042     je  logical_value_skipped
 1043     cmp al,91h
 1044     je  skip_logical_value_internal_parenthesis
 1045     cmp al,92h
 1046     jne skip_logical_value_symbol
 1047     sub [logical_value_parentheses],1
 1048     jnc skip_logical_value_symbol
 1049     cmp [logical_value_wrapping],91h
 1050     jne skip_logical_value_symbol
 1051     jmp logical_value_skipped
 1052       skip_logical_value_internal_parenthesis:
 1053     inc [logical_value_parentheses]
 1054       skip_logical_value_symbol:
 1055     call    skip_symbol
 1056     jmp find_simple_logical_value_end
 1057   preevaluate_logical_value:
 1058     mov ebp,edi
 1059       preevaluate_negation:
 1060     cmp byte [esi],'~'
 1061     jne preevaluate_negation_ok
 1062     movs    byte [edi],[esi]
 1063     jmp preevaluate_negation
 1064       preevaluate_negation_ok:
 1065     mov ebx,esi
 1066     cmp byte [esi],91h
 1067     jne preevaluate_simple_logical_value
 1068     lods    byte [esi]
 1069     stos    byte [edi]
 1070     push    ebp
 1071     mov dl,[logical_value_wrapping]
 1072     push    edx
 1073     call    preevaluate_embedded_logical_expression
 1074     pop edx
 1075     mov [logical_value_wrapping],dl
 1076     pop ebp
 1077     cmp al,0FFh
 1078     je  invalid_logical_value
 1079     cmp byte [esi],92h
 1080     jne invalid_logical_value
 1081     or  al,al
 1082     jnz preevaluated_expression_value
 1083     movs    byte [edi],[esi]
 1084     ret
 1085       preevaluated_expression_value:
 1086     inc esi
 1087     lea edx,[edi-1]
 1088     sub edx,ebp
 1089     test    edx,1
 1090     jz  expression_negation_ok
 1091     xor al,1
 1092       expression_negation_ok:
 1093     mov edi,ebp
 1094     ret
 1095       invalid_logical_value:
 1096     mov edi,ebp
 1097     mov al,0FFh
 1098     ret
 1099       preevaluate_simple_logical_value:
 1100     xor edx,edx
 1101     mov [logical_value_parentheses],edx
 1102       find_logical_value_boundaries:
 1103     mov al,[esi]
 1104     or  al,al
 1105     jz  logical_value_boundaries_found
 1106     cmp al,91h
 1107     je  logical_value_internal_parentheses
 1108     cmp al,92h
 1109     je  logical_value_boundaries_parenthesis_close
 1110     cmp al,'|'
 1111     je  logical_value_boundaries_found
 1112     cmp al,'&'
 1113     je  logical_value_boundaries_found
 1114     or  edx,edx
 1115     jnz next_symbol_in_logical_value
 1116     cmp al,0F0h
 1117     je  preevaluable_logical_operator
 1118     cmp al,0F7h
 1119     je  preevaluable_logical_operator
 1120     cmp al,0F6h
 1121     jne next_symbol_in_logical_value
 1122       preevaluable_logical_operator:
 1123     mov edx,esi
 1124       next_symbol_in_logical_value:
 1125     call    skip_symbol
 1126     jmp find_logical_value_boundaries
 1127       logical_value_internal_parentheses:
 1128     inc [logical_value_parentheses]
 1129     jmp next_symbol_in_logical_value
 1130       logical_value_boundaries_parenthesis_close:
 1131     sub [logical_value_parentheses],1
 1132     jnc next_symbol_in_logical_value
 1133     cmp [logical_value_wrapping],91h
 1134     jne next_symbol_in_logical_value
 1135       logical_value_boundaries_found:
 1136     or  edx,edx
 1137     jz  non_preevaluable_logical_value
 1138     mov al,[edx]
 1139     cmp al,0F0h
 1140     je  compare_symbols
 1141     cmp al,0F7h
 1142     je  compare_symbol_types
 1143     cmp al,0F6h
 1144     je  scan_symbols_list
 1145       non_preevaluable_logical_value:
 1146     mov ecx,esi
 1147     mov esi,ebx
 1148     sub ecx,esi
 1149     jz  invalid_logical_value
 1150     cmp esi,edi
 1151     je  leave_logical_value_intact
 1152     rep movs byte [edi],[esi]
 1153     xor al,al
 1154     ret
 1155       leave_logical_value_intact:
 1156     add edi,ecx
 1157     add esi,ecx
 1158     xor al,al
 1159     ret
 1160       compare_symbols:
 1161     lea ecx,[esi-1]
 1162     sub ecx,edx
 1163     mov eax,edx
 1164     sub eax,ebx
 1165     cmp ecx,eax
 1166     jne preevaluated_false
 1167     push    esi edi
 1168     mov esi,ebx
 1169     lea edi,[edx+1]
 1170     repe    cmps byte [esi],[edi]
 1171     pop edi esi
 1172     je  preevaluated_true
 1173       preevaluated_false:
 1174     mov eax,edi
 1175     sub eax,ebp
 1176     test    eax,1
 1177     jnz store_true
 1178       store_false:
 1179     mov edi,ebp
 1180     mov al,'0'
 1181     ret
 1182       preevaluated_true:
 1183     mov eax,edi
 1184     sub eax,ebp
 1185     test    eax,1
 1186     jnz store_false
 1187       store_true:
 1188     mov edi,ebp
 1189     mov al,'1'
 1190     ret
 1191       compare_symbol_types:
 1192     push    esi
 1193     lea esi,[edx+1]
 1194       type_comparison:
 1195     cmp esi,[esp]
 1196     je  types_compared
 1197     mov al,[esi]
 1198     cmp al,[ebx]
 1199     jne different_type
 1200     cmp al,'('
 1201     jne equal_type
 1202     mov al,[esi+1]
 1203     mov ah,[ebx+1]
 1204     cmp al,ah
 1205     je  equal_type
 1206     or  al,al
 1207     jz  different_type
 1208     or  ah,ah
 1209     jz  different_type
 1210     cmp al,'.'
 1211     je  different_type
 1212     cmp ah,'.'
 1213     je  different_type
 1214       equal_type:
 1215     call    skip_symbol
 1216     xchg    esi,ebx
 1217     call    skip_symbol
 1218     xchg    esi,ebx
 1219     jmp type_comparison
 1220       types_compared:
 1221     pop esi
 1222     cmp byte [ebx],0F7h
 1223     jne preevaluated_false
 1224     jmp preevaluated_true
 1225       different_type:
 1226     pop esi
 1227     jmp preevaluated_false
 1228       scan_symbols_list:
 1229     push    edi esi
 1230     lea esi,[edx+1]
 1231     sub edx,ebx
 1232     lods    byte [esi]
 1233     cmp al,'<'
 1234     jne invalid_symbols_list
 1235       get_next_from_list:
 1236     mov edi,esi
 1237       get_from_list:
 1238     cmp byte [esi],','
 1239     je  compare_in_list
 1240     cmp byte [esi],'>'
 1241     je  compare_in_list
 1242     cmp esi,[esp]
 1243     jae invalid_symbols_list
 1244     call    skip_symbol
 1245     jmp get_from_list
 1246       compare_in_list:
 1247     mov ecx,esi
 1248     sub ecx,edi
 1249     cmp ecx,edx
 1250     jne not_equal_length_in_list
 1251     mov esi,ebx
 1252     repe    cmps byte [esi],[edi]
 1253     mov esi,edi
 1254     jne not_equal_in_list
 1255       skip_rest_of_list:
 1256     cmp byte [esi],'>'
 1257     je  check_list_end
 1258     cmp esi,[esp]
 1259     jae invalid_symbols_list
 1260     call    skip_symbol
 1261     jmp skip_rest_of_list
 1262       check_list_end:
 1263     inc esi
 1264     cmp esi,[esp]
 1265     jne invalid_symbols_list
 1266     pop esi edi
 1267     jmp preevaluated_true
 1268       not_equal_in_list:
 1269     add esi,ecx
 1270       not_equal_length_in_list:
 1271     lods    byte [esi]
 1272     cmp al,','
 1273     je  get_next_from_list
 1274     cmp esi,[esp]
 1275     jne invalid_symbols_list
 1276     pop esi edi
 1277     jmp preevaluated_false
 1278       invalid_symbols_list:
 1279     pop esi edi
 1280     jmp invalid_logical_value