"Fossies" - the Fresh Open Source Software Archive

Member "fasm/source/exprpars.inc" (21 Feb 2022, 22151 Bytes) of package /linux/misc/fasm-1.73.30.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.29_vs_1.73.30.

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