Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1.  
  2. ; flat assembler core
  3. ; Copyright (c) 1999-2019, Tomasz Grysztar.
  4. ; All rights reserved.
  5.  
  6. calculate_expression:
  7.         mov     [current_offset],edi
  8.         mov     [value_undefined],0
  9.         cmp     byte [esi],0
  10.         je      get_string_value
  11.         cmp     byte [esi],'.'
  12.         je      convert_fp
  13.       calculation_loop:
  14.         mov     eax,[tagged_blocks]
  15.         sub     eax,0Ch
  16.         cmp     eax,edi
  17.         jbe     out_of_memory
  18.         lods    byte [esi]
  19.         cmp     al,1
  20.         je      get_byte_number
  21.         cmp     al,2
  22.         je      get_word_number
  23.         cmp     al,4
  24.         je      get_dword_number
  25.         cmp     al,8
  26.         je      get_qword_number
  27.         cmp     al,0Fh
  28.         je      value_out_of_range
  29.         cmp     al,10h
  30.         je      get_register
  31.         cmp     al,11h
  32.         je      get_label
  33.         cmp     al,')'
  34.         je      expression_calculated
  35.         cmp     al,']'
  36.         je      expression_calculated
  37.         cmp     al,'!'
  38.         je      invalid_expression
  39.         sub     edi,14h
  40.         mov     ebx,edi
  41.         sub     ebx,14h
  42.         cmp     al,0F0h
  43.         je      calculate_rva
  44.         cmp     al,0F1h
  45.         je      calculate_plt
  46.         cmp     al,0D0h
  47.         je      calculate_not
  48.         cmp     al,0E0h
  49.         je      calculate_bsf
  50.         cmp     al,0E1h
  51.         je      calculate_bsr
  52.         cmp     al,083h
  53.         je      calculate_neg
  54.         mov     dx,[ebx+8]
  55.         or      dx,[edi+8]
  56.         cmp     al,80h
  57.         je      calculate_add
  58.         cmp     al,81h
  59.         je      calculate_sub
  60.         mov     ah,[ebx+12]
  61.         or      ah,[edi+12]
  62.         jz      absolute_values_calculation
  63.         call    recoverable_misuse
  64.       absolute_values_calculation:
  65.         cmp     al,90h
  66.         je      calculate_mul
  67.         cmp     al,91h
  68.         je      calculate_div
  69.         or      dx,dx
  70.         jnz     invalid_expression
  71.         cmp     al,0A0h
  72.         je      calculate_mod
  73.         cmp     al,0B0h
  74.         je      calculate_and
  75.         cmp     al,0B1h
  76.         je      calculate_or
  77.         cmp     al,0B2h
  78.         je      calculate_xor
  79.         cmp     al,0C0h
  80.         je      calculate_shl
  81.         cmp     al,0C1h
  82.         je      calculate_shr
  83.         jmp     invalid_expression
  84.       expression_calculated:
  85.         sub     edi,14h
  86.         cmp     [value_undefined],0
  87.         je      expression_value_ok
  88.         xor     eax,eax
  89.         mov     [edi],eax
  90.         mov     [edi+4],eax
  91.         mov     [edi+12],eax
  92.       expression_value_ok:
  93.         ret
  94.       get_byte_number:
  95.         xor     eax,eax
  96.         lods    byte [esi]
  97.         stos    dword [edi]
  98.         xor     al,al
  99.         stos    dword [edi]
  100.       got_number:
  101.         and     word [edi-8+8],0
  102.         and     word [edi-8+12],0
  103.         and     dword [edi-8+16],0
  104.         add     edi,0Ch
  105.         jmp     calculation_loop
  106.       get_word_number:
  107.         xor     eax,eax
  108.         lods    word [esi]
  109.         stos    dword [edi]
  110.         xor     ax,ax
  111.         stos    dword [edi]
  112.         jmp     got_number
  113.       get_dword_number:
  114.         movs    dword [edi],[esi]
  115.         xor     eax,eax
  116.         stos    dword [edi]
  117.         jmp     got_number
  118.       get_qword_number:
  119.         movs    dword [edi],[esi]
  120.         movs    dword [edi],[esi]
  121.         jmp     got_number
  122.       get_register:
  123.         mov     byte [edi+9],0
  124.         and     word [edi+12],0
  125.         lods    byte [esi]
  126.         mov     [edi+8],al
  127.         mov     byte [edi+10],1
  128.         xor     eax,eax
  129.         mov     [edi+16],eax
  130.         stos    dword [edi]
  131.         stos    dword [edi]
  132.         add     edi,0Ch
  133.         jmp     calculation_loop
  134.       get_label:
  135.         xor     eax,eax
  136.         mov     [edi+8],eax
  137.         mov     [edi+12],eax
  138.         mov     [edi+20],eax
  139.         lods    dword [esi]
  140.         cmp     eax,0Fh
  141.         jb      predefined_label
  142.         je      reserved_word_used_as_symbol
  143.         mov     ebx,eax
  144.         mov     ax,[current_pass]
  145.         mov     [ebx+18],ax
  146.         mov     cl,[ebx+9]
  147.         shr     cl,1
  148.         and     cl,1
  149.         neg     cl
  150.         or      byte [ebx+8],8
  151.         test    byte [ebx+8],1
  152.         jz      label_undefined
  153.         cmp     ax,[ebx+16]
  154.         je      unadjusted_label
  155.         test    byte [ebx+8],4
  156.         jnz     label_out_of_scope
  157.         test    byte [ebx+9],1
  158.         jz      unadjusted_label
  159.         mov     eax,[ebx]
  160.         sub     eax,dword [adjustment]
  161.         stos    dword [edi]
  162.         mov     eax,[ebx+4]
  163.         sbb     eax,dword [adjustment+4]
  164.         stos    dword [edi]
  165.         sbb     cl,[adjustment_sign]
  166.         mov     [edi-8+13],cl
  167.         mov     eax,dword [adjustment]
  168.         or      al,[adjustment_sign]
  169.         or      eax,dword [adjustment+4]
  170.         jz      got_label
  171.         or      [next_pass_needed],-1
  172.         jmp     got_label
  173.       unadjusted_label:
  174.         mov     eax,[ebx]
  175.         stos    dword [edi]
  176.         mov     eax,[ebx+4]
  177.         stos    dword [edi]
  178.         mov     [edi-8+13],cl
  179.       got_label:
  180.         test    byte [ebx+9],4
  181.         jnz     invalid_use_of_symbol
  182.         call    store_label_reference
  183.         mov     al,[ebx+11]
  184.         mov     [edi-8+12],al
  185.         mov     eax,[ebx+12]
  186.         mov     [edi-8+8],eax
  187.         cmp     al,ah
  188.         jne     labeled_registers_ok
  189.         shr     eax,16
  190.         add     al,ah
  191.         jo      labeled_registers_ok
  192.         xor     ah,ah
  193.         mov     [edi-8+10],ax
  194.         mov     [edi-8+9],ah
  195.       labeled_registers_ok:
  196.         mov     eax,[ebx+20]
  197.         mov     [edi-8+16],eax
  198.         add     edi,0Ch
  199.         mov     al,[ebx+10]
  200.         or      al,al
  201.         jz      calculation_loop
  202.         test    [operand_flags],1
  203.         jnz     calculation_loop
  204.       check_size:
  205.         xchg    [operand_size],al
  206.         or      al,al
  207.         jz      calculation_loop
  208.         cmp     al,[operand_size]
  209.         jne     operand_sizes_do_not_match
  210.         jmp     calculation_loop
  211.       actual_file_offset_label:
  212.         mov     eax,[undefined_data_end]
  213.         mov     ebp,[addressing_space]
  214.         test    byte [ds:ebp+0Ah],1
  215.         jnz     use_undefined_data_offset
  216.         cmp     eax,[current_offset]
  217.         jne     use_current_offset
  218.        use_undefined_data_offset:
  219.         mov     eax,[undefined_data_start]
  220.         jmp     make_file_offset_label
  221.       current_file_offset_label:
  222.         mov     ebp,[addressing_space]
  223.         test    byte [ds:ebp+0Ah],1
  224.         jz      use_current_offset
  225.         mov     eax,[undefined_data_end]
  226.         jmp     make_file_offset_label
  227.        use_current_offset:
  228.         mov     eax,[current_offset]
  229.        make_file_offset_label:
  230.         cmp     [output_format],2
  231.         jae     invalid_use_of_symbol
  232.         sub     eax,[code_start]
  233.         jmp     make_dword_label_value
  234.       current_offset_label:
  235.         mov     eax,[current_offset]
  236.        make_current_offset_label:
  237.         xor     edx,edx
  238.         xor     ch,ch
  239.         mov     ebp,[addressing_space]
  240.         sub     eax,[ds:ebp]
  241.         sbb     edx,[ds:ebp+4]
  242.         sbb     ch,[ds:ebp+8]
  243.         jp      current_offset_label_ok
  244.         call    recoverable_overflow
  245.        current_offset_label_ok:
  246.         stos    dword [edi]
  247.         mov     eax,edx
  248.         stos    dword [edi]
  249.         mov     eax,[ds:ebp+10h]
  250.         stos    dword [edi]
  251.         mov     cl,[ds:ebp+9]
  252.         mov     [edi-12+12],cx
  253.         mov     eax,[ds:ebp+14h]
  254.         mov     [edi-12+16],eax
  255.         add     edi,8
  256.         jmp     calculation_loop
  257.       org_origin_label:
  258.         mov     eax,[addressing_space]
  259.         mov     eax,[eax+18h]
  260.         jmp     make_current_offset_label
  261.       counter_label:
  262.         mov     eax,[counter]
  263.       make_dword_label_value:
  264.         stos    dword [edi]
  265.         xor     eax,eax
  266.         stos    dword [edi]
  267.         add     edi,0Ch
  268.         jmp     calculation_loop
  269.       timestamp_label:
  270.         call    make_timestamp
  271.       make_qword_label_value:
  272.         stos    dword [edi]
  273.         mov     eax,edx
  274.         stos    dword [edi]
  275.         add     edi,0Ch
  276.         jmp     calculation_loop
  277.       predefined_label:
  278.         or      eax,eax
  279.         jz      current_offset_label
  280.         cmp     eax,1
  281.         je      counter_label
  282.         cmp     eax,2
  283.         je      timestamp_label
  284.         cmp     eax,3
  285.         je      org_origin_label
  286.         cmp     eax,4
  287.         je      current_file_offset_label
  288.         cmp     eax,5
  289.         je      actual_file_offset_label
  290.         mov     edx,invalid_value
  291.         jmp     error_undefined
  292.       label_out_of_scope:
  293.         mov     edx,symbol_out_of_scope
  294.         jmp     error_undefined
  295.       label_undefined:
  296.         mov     edx,undefined_symbol
  297.       error_undefined:
  298.         cmp     [current_pass],1
  299.         ja      undefined_value
  300.       force_next_pass:
  301.         or      [next_pass_needed],-1
  302.       undefined_value:
  303.         or      [value_undefined],-1
  304.         and     word [edi+12],0
  305.         xor     eax,eax
  306.         stos    dword [edi]
  307.         stos    dword [edi]
  308.         add     edi,0Ch
  309.         cmp     [error_line],0
  310.         jne     calculation_loop
  311.         mov     eax,[current_line]
  312.         mov     [error_line],eax
  313.         mov     [error],edx
  314.         mov     [error_info],ebx
  315.         jmp     calculation_loop
  316.       calculate_add:
  317.         xor     ah,ah
  318.         mov     ah,[ebx+12]
  319.         mov     al,[edi+12]
  320.         or      al,al
  321.         jz      add_values
  322.         or      ah,ah
  323.         jz      add_relocatable
  324.         add     ah,al
  325.         jnz     invalid_add
  326.         mov     ecx,[edi+16]
  327.         cmp     ecx,[ebx+16]
  328.         je      add_values
  329.       invalid_add:
  330.         call    recoverable_misuse
  331.         jmp     add_values
  332.       add_relocatable:
  333.         mov     ah,al
  334.         mov     ecx,[edi+16]
  335.         mov     [ebx+16],ecx
  336.       add_values:
  337.         mov     [ebx+12],ah
  338.         mov     eax,[edi]
  339.         add     [ebx],eax
  340.         mov     eax,[edi+4]
  341.         adc     [ebx+4],eax
  342.         mov     al,[edi+13]
  343.         adc     [ebx+13],al
  344.         jp      add_sign_ok
  345.         call    recoverable_overflow
  346.       add_sign_ok:
  347.         or      dx,dx
  348.         jz      calculation_loop
  349.         push    esi
  350.         mov     esi,ebx
  351.         mov     cl,[edi+10]
  352.         mov     al,[edi+8]
  353.         call    add_register
  354.         mov     cl,[edi+11]
  355.         mov     al,[edi+9]
  356.         call    add_register
  357.         pop     esi
  358.         jmp     calculation_loop
  359.       add_register:
  360.         or      al,al
  361.         jz      add_register_done
  362.       add_register_start:
  363.         cmp     [esi+8],al
  364.         jne     add_in_second_slot
  365.         add     [esi+10],cl
  366.         jo      value_out_of_range
  367.         jnz     add_register_done
  368.         mov     byte [esi+8],0
  369.         ret
  370.       add_in_second_slot:
  371.         cmp     [esi+9],al
  372.         jne     create_in_first_slot
  373.         add     [esi+11],cl
  374.         jo      value_out_of_range
  375.         jnz     add_register_done
  376.         mov     byte [esi+9],0
  377.         ret
  378.       create_in_first_slot:
  379.         cmp     byte [esi+8],0
  380.         jne     create_in_second_slot
  381.         mov     [esi+8],al
  382.         mov     [esi+10],cl
  383.         ret
  384.       create_in_second_slot:
  385.         cmp     byte [esi+9],0
  386.         jne     invalid_expression
  387.         mov     [esi+9],al
  388.         mov     [esi+11],cl
  389.       add_register_done:
  390.         ret
  391.       out_of_range:
  392.         jmp     calculation_loop
  393.       calculate_sub:
  394.         xor     ah,ah
  395.         mov     ah,[ebx+12]
  396.         mov     al,[edi+12]
  397.         or      al,al
  398.         jz      sub_values
  399.         or      ah,ah
  400.         jz      negate_relocatable
  401.         cmp     al,ah
  402.         jne     invalid_sub
  403.         xor     ah,ah
  404.         mov     ecx,[edi+16]
  405.         cmp     ecx,[ebx+16]
  406.         je      sub_values
  407.       invalid_sub:
  408.         call    recoverable_misuse
  409.         jmp     sub_values
  410.       negate_relocatable:
  411.         neg     al
  412.         mov     ah,al
  413.         mov     ecx,[edi+16]
  414.         mov     [ebx+16],ecx
  415.       sub_values:
  416.         mov     [ebx+12],ah
  417.         mov     eax,[edi]
  418.         sub     [ebx],eax
  419.         mov     eax,[edi+4]
  420.         sbb     [ebx+4],eax
  421.         mov     al,[edi+13]
  422.         sbb     [ebx+13],al
  423.         jp      sub_sign_ok
  424.         cmp     [error_line],0
  425.         jne     sub_sign_ok
  426.         call    recoverable_overflow
  427.       sub_sign_ok:
  428.         or      dx,dx
  429.         jz      calculation_loop
  430.         push    esi
  431.         mov     esi,ebx
  432.         mov     cl,[edi+10]
  433.         mov     al,[edi+8]
  434.         call    sub_register
  435.         mov     cl,[edi+11]
  436.         mov     al,[edi+9]
  437.         call    sub_register
  438.         pop     esi
  439.         jmp     calculation_loop
  440.       sub_register:
  441.         or      al,al
  442.         jz      add_register_done
  443.         neg     cl
  444.         jo      value_out_of_range
  445.         jmp     add_register_start
  446.       calculate_mul:
  447.         or      dx,dx
  448.         jz      mul_start
  449.         cmp     word [ebx+8],0
  450.         jne     mul_start
  451.         xor     ecx,ecx
  452.       swap_values:
  453.         mov     eax,[ebx+ecx]
  454.         xchg    eax,[edi+ecx]
  455.         mov     [ebx+ecx],eax
  456.         add     ecx,4
  457.         cmp     ecx,16
  458.         jb      swap_values
  459.       mul_start:
  460.         push    esi edx
  461.         mov     esi,ebx
  462.         xor     bl,bl
  463.         cmp     byte [esi+13],0
  464.         je      mul_first_sign_ok
  465.         xor     bl,-1
  466.         mov     eax,[esi]
  467.         mov     edx,[esi+4]
  468.         not     eax
  469.         not     edx
  470.         add     eax,1
  471.         adc     edx,0
  472.         mov     [esi],eax
  473.         mov     [esi+4],edx
  474.         or      eax,edx
  475.         jz      mul_overflow
  476.       mul_first_sign_ok:
  477.         cmp     byte [edi+13],0
  478.         je      mul_second_sign_ok
  479.         xor     bl,-1
  480.         cmp     byte [esi+8],0
  481.         je      mul_first_register_sign_ok
  482.         neg     byte [esi+10]
  483.         jo      invalid_expression
  484.       mul_first_register_sign_ok:
  485.         cmp     byte [esi+9],0
  486.         je      mul_second_register_sign_ok
  487.         neg     byte [esi+11]
  488.         jo      invalid_expression
  489.       mul_second_register_sign_ok:
  490.         mov     eax,[edi]
  491.         mov     edx,[edi+4]
  492.         not     eax
  493.         not     edx
  494.         add     eax,1
  495.         adc     edx,0
  496.         mov     [edi],eax
  497.         mov     [edi+4],edx
  498.         or      eax,edx
  499.         jz      mul_overflow
  500.       mul_second_sign_ok:
  501.         cmp     dword [esi+4],0
  502.         jz      mul_numbers
  503.         cmp     dword [edi+4],0
  504.         jz      mul_numbers
  505.         jnz     mul_overflow
  506.       mul_numbers:
  507.         mov     eax,[esi+4]
  508.         mul     dword [edi]
  509.         or      edx,edx
  510.         jnz     mul_overflow
  511.         mov     ecx,eax
  512.         mov     eax,[esi]
  513.         mul     dword [edi+4]
  514.         or      edx,edx
  515.         jnz     mul_overflow
  516.         add     ecx,eax
  517.         jc      mul_overflow
  518.         mov     eax,[esi]
  519.         mul     dword [edi]
  520.         add     edx,ecx
  521.         jc      mul_overflow
  522.         mov     [esi],eax
  523.         mov     [esi+4],edx
  524.         or      bl,bl
  525.         jz      mul_ok
  526.         not     eax
  527.         not     edx
  528.         add     eax,1
  529.         adc     edx,0
  530.         mov     [esi],eax
  531.         mov     [esi+4],edx
  532.         or      eax,edx
  533.         jnz     mul_ok
  534.         not     bl
  535.       mul_ok:
  536.         mov     [esi+13],bl
  537.         pop     edx
  538.         or      dx,dx
  539.         jz      mul_calculated
  540.         cmp     word [edi+8],0
  541.         jne     invalid_value
  542.         cmp     byte [esi+8],0
  543.         je      mul_first_register_ok
  544.         call    get_byte_scale
  545.         imul    byte [esi+10]
  546.         mov     dl,ah
  547.         cbw
  548.         cmp     ah,dl
  549.         jne     value_out_of_range
  550.         mov     [esi+10],al
  551.         or      al,al
  552.         jnz     mul_first_register_ok
  553.         mov     [esi+8],al
  554.       mul_first_register_ok:
  555.         cmp     byte [esi+9],0
  556.         je      mul_calculated
  557.         call    get_byte_scale
  558.         imul    byte [esi+11]
  559.         mov     dl,ah
  560.         cbw
  561.         cmp     ah,dl
  562.         jne     value_out_of_range
  563.         mov     [esi+11],al
  564.         or      al,al
  565.         jnz     mul_calculated
  566.         mov     [esi+9],al
  567.       mul_calculated:
  568.         pop     esi
  569.         jmp     calculation_loop
  570.       mul_overflow:
  571.         pop     edx esi
  572.         call    recoverable_overflow
  573.         jmp     calculation_loop
  574.       get_byte_scale:
  575.         mov     al,[edi]
  576.         cbw
  577.         cwde
  578.         cdq
  579.         cmp     edx,[edi+4]
  580.         jne     value_out_of_range
  581.         cmp     eax,[edi]
  582.         jne     value_out_of_range
  583.         ret
  584.       calculate_div:
  585.         push    esi edx
  586.         mov     esi,ebx
  587.         call    div_64
  588.         pop     edx
  589.         or      dx,dx
  590.         jz      div_calculated
  591.         cmp     byte [esi+8],0
  592.         je      div_first_register_ok
  593.         call    get_byte_scale
  594.         or      al,al
  595.         jz      value_out_of_range
  596.         mov     al,[esi+10]
  597.         cbw
  598.         idiv    byte [edi]
  599.         or      ah,ah
  600.         jnz     invalid_use_of_symbol
  601.         mov     [esi+10],al
  602.       div_first_register_ok:
  603.         cmp     byte [esi+9],0
  604.         je      div_calculated
  605.         call    get_byte_scale
  606.         or      al,al
  607.         jz      value_out_of_range
  608.         mov     al,[esi+11]
  609.         cbw
  610.         idiv    byte [edi]
  611.         or      ah,ah
  612.         jnz     invalid_use_of_symbol
  613.         mov     [esi+11],al
  614.       div_calculated:
  615.         pop     esi
  616.         jmp     calculation_loop
  617.       calculate_mod:
  618.         push    esi
  619.         mov     esi,ebx
  620.         call    div_64
  621.         mov     [esi],eax
  622.         mov     [esi+4],edx
  623.         mov     [esi+13],bh
  624.         pop     esi
  625.         jmp     calculation_loop
  626.       calculate_and:
  627.         mov     eax,[edi]
  628.         mov     edx,[edi+4]
  629.         mov     cl,[edi+13]
  630.         and     [ebx],eax
  631.         and     [ebx+4],edx
  632.         and     [ebx+13],cl
  633.         jmp     calculation_loop
  634.       calculate_or:
  635.         mov     eax,[edi]
  636.         mov     edx,[edi+4]
  637.         mov     cl,[edi+13]
  638.         or      [ebx],eax
  639.         or      [ebx+4],edx
  640.         or      [ebx+13],cl
  641.         jmp     calculation_loop
  642.       calculate_xor:
  643.         mov     eax,[edi]
  644.         mov     edx,[edi+4]
  645.         mov     cl,[edi+13]
  646.         xor     [ebx],eax
  647.         xor     [ebx+4],edx
  648.         xor     [ebx+13],cl
  649.         jmp     calculation_loop
  650.       shr_negative:
  651.         mov     byte [edi+13],0
  652.         not     dword [edi]
  653.         not     dword [edi+4]
  654.         add     dword [edi],1
  655.         adc     dword [edi+4],0
  656.         jc      shl_over
  657.       calculate_shl:
  658.         cmp     byte [edi+13],0
  659.         jne     shl_negative
  660.         mov     edx,[ebx+4]
  661.         mov     eax,[ebx]
  662.         cmp     dword [edi+4],0
  663.         jne     shl_over
  664.         movsx   ecx,byte [ebx+13]
  665.         xchg    ecx,[edi]
  666.         cmp     ecx,64
  667.         je      shl_max
  668.         ja      shl_over
  669.         cmp     ecx,32
  670.         jae     shl_high
  671.         shld    [edi],edx,cl
  672.         shld    edx,eax,cl
  673.         shl     eax,cl
  674.         mov     [ebx],eax
  675.         mov     [ebx+4],edx
  676.         jmp     shl_done
  677.       shl_over:
  678.         cmp     byte [ebx+13],0
  679.         jne     shl_overflow
  680.       shl_max:
  681.         movsx   ecx,byte [ebx+13]
  682.         cmp     eax,ecx
  683.         jne     shl_overflow
  684.         cmp     edx,ecx
  685.         jne     shl_overflow
  686.         xor     eax,eax
  687.         mov     [ebx],eax
  688.         mov     [ebx+4],eax
  689.         jmp     calculation_loop
  690.       shl_high:
  691.         sub     cl,32
  692.         shld    [edi],edx,cl
  693.         shld    edx,eax,cl
  694.         shl     eax,cl
  695.         mov     [ebx+4],eax
  696.         and     dword [ebx],0
  697.         cmp     edx,[edi]
  698.         jne     shl_overflow
  699.       shl_done:
  700.         movsx   eax,byte [ebx+13]
  701.         cmp     eax,[edi]
  702.         je      calculation_loop
  703.       shl_overflow:
  704.         call    recoverable_overflow
  705.         jmp     calculation_loop
  706.       shl_negative:
  707.         mov     byte [edi+13],0
  708.         not     dword [edi]
  709.         not     dword [edi+4]
  710.         add     dword [edi],1
  711.         adc     dword [edi+4],0
  712.         jnc     calculate_shr
  713.         dec     dword [edi+4]
  714.       calculate_shr:
  715.         cmp     byte [edi+13],0
  716.         jne     shr_negative
  717.         mov     edx,[ebx+4]
  718.         mov     eax,[ebx]
  719.         cmp     dword [edi+4],0
  720.         jne     shr_over
  721.         mov     ecx,[edi]
  722.         cmp     ecx,64
  723.         jae     shr_over
  724.         push    esi
  725.         movsx   esi,byte [ebx+13]
  726.         cmp     ecx,32
  727.         jae     shr_high
  728.         shrd    eax,edx,cl
  729.         shrd    edx,esi,cl
  730.         mov     [ebx],eax
  731.         mov     [ebx+4],edx
  732.         pop     esi
  733.         jmp     calculation_loop
  734.       shr_high:
  735.         sub     cl,32
  736.         shrd    edx,esi,cl
  737.         mov     [ebx],edx
  738.         mov     [ebx+4],esi
  739.         pop     esi
  740.         jmp     calculation_loop
  741.       shr_over:
  742.         movsx   eax,byte [ebx+13]
  743.         mov     dword [ebx],eax
  744.         mov     dword [ebx+4],eax
  745.         jmp     calculation_loop
  746.       calculate_not:
  747.         cmp     word [edi+8],0
  748.         jne     invalid_expression
  749.         cmp     byte [edi+12],0
  750.         je      not_ok
  751.         call    recoverable_misuse
  752.       not_ok:
  753.         not     dword [edi]
  754.         not     dword [edi+4]
  755.         not     byte [edi+13]
  756.         add     edi,14h
  757.         jmp     calculation_loop
  758.       calculate_bsf:
  759.         cmp     word [edi+8],0
  760.         jne     invalid_expression
  761.         cmp     byte [edi+12],0
  762.         je      bsf_ok
  763.         call    recoverable_misuse
  764.       bsf_ok:
  765.         xor     ecx,ecx
  766.         bsf     eax,[edi]
  767.         jnz     finish_bs
  768.         mov     ecx,32
  769.         bsf     eax,[edi+4]
  770.         jnz     finish_bs
  771.         cmp     byte [edi+13],0
  772.         jne     finish_bs
  773.       bs_overflow:
  774.         call    recoverable_overflow
  775.         add     edi,14h
  776.         jmp     calculation_loop
  777.       calculate_bsr:
  778.         cmp     word [edi+8],0
  779.         jne     invalid_expression
  780.         cmp     byte [edi+12],0
  781.         je      bsr_ok
  782.         call    recoverable_misuse
  783.       bsr_ok:
  784.         cmp     byte [edi+13],0
  785.         jne     bs_overflow
  786.         mov     ecx,32
  787.         bsr     eax,[edi+4]
  788.         jnz     finish_bs
  789.         xor     ecx,ecx
  790.         bsr     eax,[edi]
  791.         jz      bs_overflow
  792.       finish_bs:
  793.         add     eax,ecx
  794.         xor     edx,edx
  795.         mov     [edi],eax
  796.         mov     [edi+4],edx
  797.         mov     [edi+13],dl
  798.         add     edi,14h
  799.         jmp     calculation_loop
  800.       calculate_neg:
  801.         cmp     byte [edi+8],0
  802.         je      neg_first_register_ok
  803.         neg     byte [edi+10]
  804.         jo      invalid_expression
  805.       neg_first_register_ok:
  806.         cmp     byte [edi+9],0
  807.         je      neg_second_register_ok
  808.         neg     byte [edi+11]
  809.         jo      invalid_expression
  810.       neg_second_register_ok:
  811.         neg     byte [edi+12]
  812.         xor     eax,eax
  813.         xor     edx,edx
  814.         xor     cl,cl
  815.         xchg    eax,[edi]
  816.         xchg    edx,[edi+4]
  817.         xchg    cl,[edi+13]
  818.         sub     [edi],eax
  819.         sbb     [edi+4],edx
  820.         sbb     [edi+13],cl
  821.         jp      neg_sign_ok
  822.         call    recoverable_overflow
  823.       neg_sign_ok:
  824.         add     edi,14h
  825.         jmp     calculation_loop
  826.       calculate_rva:
  827.         cmp     word [edi+8],0
  828.         jne     invalid_expression
  829.         mov     al,[output_format]
  830.         cmp     al,5
  831.         je      calculate_gotoff
  832.         cmp     al,4
  833.         je      calculate_coff_rva
  834.         cmp     al,3
  835.         jne     invalid_expression
  836.         test    [format_flags],8
  837.         jnz     pe64_rva
  838.         mov     al,2
  839.         bt      [resolver_flags],0
  840.         jc      rva_type_ok
  841.         xor     al,al
  842.       rva_type_ok:
  843.         cmp     byte [edi+12],al
  844.         je      rva_ok
  845.         call    recoverable_misuse
  846.       rva_ok:
  847.         mov     byte [edi+12],0
  848.         mov     eax,[code_start]
  849.         mov     eax,[eax+34h]
  850.         xor     edx,edx
  851.       finish_rva:
  852.         sub     [edi],eax
  853.         sbb     [edi+4],edx
  854.         sbb     byte [edi+13],0
  855.         jp      rva_finished
  856.         call    recoverable_overflow
  857.       rva_finished:
  858.         add     edi,14h
  859.         jmp     calculation_loop
  860.       pe64_rva:
  861.         mov     al,4
  862.         bt      [resolver_flags],0
  863.         jc      pe64_rva_type_ok
  864.         xor     al,al
  865.       pe64_rva_type_ok:
  866.         cmp     byte [edi+12],al
  867.         je      pe64_rva_ok
  868.         call    recoverable_misuse
  869.       pe64_rva_ok:
  870.         mov     byte [edi+12],0
  871.         mov     eax,[code_start]
  872.         mov     edx,[eax+34h]
  873.         mov     eax,[eax+30h]
  874.         jmp     finish_rva
  875.       calculate_gotoff:
  876.         test    [format_flags],1
  877.         jnz     calculate_elf_dyn_rva
  878.         test    [format_flags],8
  879.         jnz     invalid_expression
  880.       calculate_coff_rva:
  881.         mov     dl,5
  882.         cmp     byte [edi+12],2
  883.         je      change_value_type
  884.       incorrect_change_of_value_type:
  885.         call    recoverable_misuse
  886.       change_value_type:
  887.         mov     byte [edi+12],dl
  888.         add     edi,14h
  889.         jmp     calculation_loop
  890.       calculate_elf_dyn_rva:
  891.         xor     dl,dl
  892.         test    byte [edi+12],1
  893.         jnz     incorrect_change_of_value_type
  894.         jmp     change_value_type
  895.       calculate_plt:
  896.         cmp     word [edi+8],0
  897.         jne     invalid_expression
  898.         cmp     [output_format],5
  899.         jne     invalid_expression
  900.         test    [format_flags],1
  901.         jnz     invalid_expression
  902.         mov     dl,6
  903.         mov     dh,2
  904.         test    [format_flags],8
  905.         jz      check_value_for_plt
  906.         mov     dh,4
  907.       check_value_for_plt:
  908.         mov     eax,[edi]
  909.         or      eax,[edi+4]
  910.         jnz     incorrect_change_of_value_type
  911.         cmp     byte [edi+12],dh
  912.         jne     incorrect_change_of_value_type
  913.         mov     eax,[edi+16]
  914.         cmp     byte [eax],80h
  915.         jne     incorrect_change_of_value_type
  916.         jmp     change_value_type
  917.       div_64:
  918.         xor     ebx,ebx
  919.         cmp     dword [edi],0
  920.         jne     divider_ok
  921.         cmp     dword [edi+4],0
  922.         jne     divider_ok
  923.         cmp     [next_pass_needed],0
  924.         je      value_out_of_range
  925.         jmp     div_done
  926.       divider_ok:
  927.         cmp     byte [esi+13],0
  928.         je      div_first_sign_ok
  929.         mov     eax,[esi]
  930.         mov     edx,[esi+4]
  931.         not     eax
  932.         not     edx
  933.         add     eax,1
  934.         adc     edx,0
  935.         mov     [esi],eax
  936.         mov     [esi+4],edx
  937.         or      eax,edx
  938.         jz      value_out_of_range
  939.         xor     bx,-1
  940.       div_first_sign_ok:
  941.         cmp     byte [edi+13],0
  942.         je      div_second_sign_ok
  943.         mov     eax,[edi]
  944.         mov     edx,[edi+4]
  945.         not     eax
  946.         not     edx
  947.         add     eax,1
  948.         adc     edx,0
  949.         mov     [edi],eax
  950.         mov     [edi+4],edx
  951.         or      eax,edx
  952.         jz      value_out_of_range
  953.         xor     bl,-1
  954.       div_second_sign_ok:
  955.         cmp     dword [edi+4],0
  956.         jne     div_high
  957.         mov     ecx,[edi]
  958.         mov     eax,[esi+4]
  959.         xor     edx,edx
  960.         div     ecx
  961.         mov     [esi+4],eax
  962.         mov     eax,[esi]
  963.         div     ecx
  964.         mov     [esi],eax
  965.         mov     eax,edx
  966.         xor     edx,edx
  967.         jmp     div_done
  968.       div_high:
  969.         push    ebx
  970.         mov     eax,[esi+4]
  971.         xor     edx,edx
  972.         div     dword [edi+4]
  973.         mov     ebx,[esi]
  974.         mov     [esi],eax
  975.         and     dword [esi+4],0
  976.         mov     ecx,edx
  977.         mul     dword [edi]
  978.       div_high_loop:
  979.         cmp     ecx,edx
  980.         ja      div_high_done
  981.         jb      div_high_large_correction
  982.         cmp     ebx,eax
  983.         jae     div_high_done
  984.       div_high_correction:
  985.         dec     dword [esi]
  986.         sub     eax,[edi]
  987.         sbb     edx,[edi+4]
  988.         jnc     div_high_loop
  989.       div_high_done:
  990.         sub     ebx,eax
  991.         sbb     ecx,edx
  992.         mov     edx,ecx
  993.         mov     eax,ebx
  994.         pop     ebx
  995.         jmp     div_done
  996.       div_high_large_correction:
  997.         push    eax edx
  998.         mov     eax,edx
  999.         sub     eax,ecx
  1000.         xor     edx,edx
  1001.         div     dword [edi+4]
  1002.         shr     eax,1
  1003.         jz      div_high_small_correction
  1004.         sub     [esi],eax
  1005.         push    eax
  1006.         mul     dword [edi+4]
  1007.         sub     dword [esp+4],eax
  1008.         pop     eax
  1009.         mul     dword [edi]
  1010.         sub     dword [esp+4],eax
  1011.         sbb     dword [esp],edx
  1012.         pop     edx eax
  1013.         jmp     div_high_loop
  1014.       div_high_small_correction:
  1015.         pop     edx eax
  1016.         jmp     div_high_correction
  1017.       div_done:
  1018.         or      bh,bh
  1019.         jz      remainder_ok
  1020.         not     eax
  1021.         not     edx
  1022.         add     eax,1
  1023.         adc     edx,0
  1024.         mov     ecx,eax
  1025.         or      ecx,edx
  1026.         jnz     remainder_ok
  1027.         not     bh
  1028.       remainder_ok:
  1029.         or      bl,bl
  1030.         jz      div_ok
  1031.         not     dword [esi]
  1032.         not     dword [esi+4]
  1033.         add     dword [esi],1
  1034.         adc     dword [esi+4],0
  1035.         mov     ecx,[esi]
  1036.         or      ecx,[esi+4]
  1037.         jnz     div_ok
  1038.         not     bl
  1039.       div_ok:
  1040.         mov     [esi+13],bl
  1041.         ret
  1042.       store_label_reference:
  1043.         cmp     [symbols_file],0
  1044.         je      label_reference_ok
  1045.         cmp     [next_pass_needed],0
  1046.         jne     label_reference_ok
  1047.         mov     eax,[tagged_blocks]
  1048.         mov     dword [eax-4],2
  1049.         mov     dword [eax-8],4
  1050.         sub     eax,8+4
  1051.         cmp     eax,edi
  1052.         jbe     out_of_memory
  1053.         mov     [tagged_blocks],eax
  1054.         mov     [eax],ebx
  1055.       label_reference_ok:
  1056.         ret
  1057.       convert_fp:
  1058.         inc     esi
  1059.         and     word [edi+8],0
  1060.         and     word [edi+12],0
  1061.         mov     al,[value_size]
  1062.         cmp     al,2
  1063.         je      convert_fp_word
  1064.         cmp     al,4
  1065.         je      convert_fp_dword
  1066.         test    al,not 8
  1067.         jz      convert_fp_qword
  1068.         call    recoverable_misuse
  1069.       convert_fp_qword:
  1070.         xor     eax,eax
  1071.         xor     edx,edx
  1072.         cmp     word [esi+8],8000h
  1073.         je      fp_qword_store
  1074.         mov     bx,[esi+8]
  1075.         mov     eax,[esi]
  1076.         mov     edx,[esi+4]
  1077.         add     eax,eax
  1078.         adc     edx,edx
  1079.         mov     ecx,edx
  1080.         shr     edx,12
  1081.         shrd    eax,ecx,12
  1082.         jnc     fp_qword_ok
  1083.         add     eax,1
  1084.         adc     edx,0
  1085.         bt      edx,20
  1086.         jnc     fp_qword_ok
  1087.         and     edx,1 shl 20 - 1
  1088.         inc     bx
  1089.         shr     edx,1
  1090.         rcr     eax,1
  1091.       fp_qword_ok:
  1092.         add     bx,3FFh
  1093.         cmp     bx,7FFh
  1094.         jge     value_out_of_range
  1095.         cmp     bx,0
  1096.         jg      fp_qword_exp_ok
  1097.         or      edx,1 shl 20
  1098.         mov     cx,bx
  1099.         neg     cx
  1100.         inc     cx
  1101.         cmp     cx,52+1
  1102.         ja      value_out_of_range
  1103.         cmp     cx,32
  1104.         jb      fp_qword_small_shift
  1105.         sub     cx,32
  1106.         mov     eax,edx
  1107.         xor     edx,edx
  1108.         shr     eax,cl
  1109.         jmp     fp_qword_shift_done
  1110.       fp_qword_small_shift:
  1111.         mov     ebx,edx
  1112.         shr     edx,cl
  1113.         shrd    eax,ebx,cl
  1114.       fp_qword_shift_done:
  1115.         mov     bx,0
  1116.         jnc     fp_qword_exp_ok
  1117.         add     eax,1
  1118.         adc     edx,0
  1119.         test    edx,1 shl 20
  1120.         jz      fp_qword_exp_ok
  1121.         and     edx,1 shl 20 - 1
  1122.         inc     bx
  1123.       fp_qword_exp_ok:
  1124.         shl     ebx,20
  1125.         or      edx,ebx
  1126.         jnz     fp_qword_store
  1127.         or      eax,eax
  1128.         jz      value_out_of_range
  1129.       fp_qword_store:
  1130.         mov     bl,[esi+11]
  1131.         shl     ebx,31
  1132.         or      edx,ebx
  1133.         mov     [edi],eax
  1134.         mov     [edi+4],edx
  1135.         add     esi,13
  1136.         ret
  1137.       convert_fp_word:
  1138.         xor     eax,eax
  1139.         cmp     word [esi+8],8000h
  1140.         je      fp_word_store
  1141.         mov     bx,[esi+8]
  1142.         mov     ax,[esi+6]
  1143.         shl     ax,1
  1144.         shr     ax,6
  1145.         jnc     fp_word_ok
  1146.         inc     ax
  1147.         bt      ax,10
  1148.         jnc     fp_word_ok
  1149.         and     ax,1 shl 10 - 1
  1150.         inc     bx
  1151.         shr     ax,1
  1152.       fp_word_ok:
  1153.         add     bx,0Fh
  1154.         cmp     bx,01Fh
  1155.         jge     value_out_of_range
  1156.         cmp     bx,0
  1157.         jg      fp_word_exp_ok
  1158.         or      ax,1 shl 10
  1159.         mov     cx,bx
  1160.         neg     cx
  1161.         inc     cx
  1162.         cmp     cx,10+1
  1163.         ja      value_out_of_range
  1164.         xor     bx,bx
  1165.         shr     ax,cl
  1166.         jnc     fp_word_exp_ok
  1167.         inc     ax
  1168.         test    ax,1 shl 10
  1169.         jz      fp_word_exp_ok
  1170.         and     ax,1 shl 10 - 1
  1171.         inc     bx
  1172.       fp_word_exp_ok:
  1173.         shl     bx,10
  1174.         or      ax,bx
  1175.         jz      value_out_of_range
  1176.       fp_word_store:
  1177.         mov     bl,[esi+11]
  1178.         shl     bx,15
  1179.         or      ax,bx
  1180.         mov     [edi],eax
  1181.         xor     eax,eax
  1182.         mov     [edi+4],eax
  1183.         add     esi,13
  1184.         ret
  1185.       convert_fp_dword:
  1186.         xor     eax,eax
  1187.         cmp     word [esi+8],8000h
  1188.         je      fp_dword_store
  1189.         mov     bx,[esi+8]
  1190.         mov     eax,[esi+4]
  1191.         shl     eax,1
  1192.         shr     eax,9
  1193.         jnc     fp_dword_ok
  1194.         inc     eax
  1195.         bt      eax,23
  1196.         jnc     fp_dword_ok
  1197.         and     eax,1 shl 23 - 1
  1198.         inc     bx
  1199.         shr     eax,1
  1200.       fp_dword_ok:
  1201.         add     bx,7Fh
  1202.         cmp     bx,0FFh
  1203.         jge     value_out_of_range
  1204.         cmp     bx,0
  1205.         jg      fp_dword_exp_ok
  1206.         or      eax,1 shl 23
  1207.         mov     cx,bx
  1208.         neg     cx
  1209.         inc     cx
  1210.         cmp     cx,23+1
  1211.         ja      value_out_of_range
  1212.         xor     bx,bx
  1213.         shr     eax,cl
  1214.         jnc     fp_dword_exp_ok
  1215.         inc     eax
  1216.         test    eax,1 shl 23
  1217.         jz      fp_dword_exp_ok
  1218.         and     eax,1 shl 23 - 1
  1219.         inc     bx
  1220.       fp_dword_exp_ok:
  1221.         shl     ebx,23
  1222.         or      eax,ebx
  1223.         jz      value_out_of_range
  1224.       fp_dword_store:
  1225.         mov     bl,[esi+11]
  1226.         shl     ebx,31
  1227.         or      eax,ebx
  1228.         mov     [edi],eax
  1229.         xor     eax,eax
  1230.         mov     [edi+4],eax
  1231.         add     esi,13
  1232.         ret
  1233.       get_string_value:
  1234.         inc     esi
  1235.         lods    dword [esi]
  1236.         mov     ecx,eax
  1237.         cmp     ecx,8
  1238.         ja      value_out_of_range
  1239.         mov     edx,edi
  1240.         xor     eax,eax
  1241.         stos    dword [edi]
  1242.         stos    dword [edi]
  1243.         mov     edi,edx
  1244.         rep     movs byte [edi],[esi]
  1245.         mov     edi,edx
  1246.         inc     esi
  1247.         and     word [edi+8],0
  1248.         and     word [edi+12],0
  1249.         ret
  1250.  
  1251. get_byte_value:
  1252.         mov     [value_size],1
  1253.         or      [operand_flags],1
  1254.         call    calculate_value
  1255.         or      al,al
  1256.         jz      check_byte_value
  1257.         call    recoverable_misuse
  1258.       check_byte_value:
  1259.         mov     eax,[edi]
  1260.         mov     edx,[edi+4]
  1261.         cmp     byte [edi+13],0
  1262.         je      byte_positive
  1263.         cmp     edx,-1
  1264.         jne     range_exceeded
  1265.         cmp     eax,-100h
  1266.         jb      range_exceeded
  1267.         ret
  1268.       byte_positive:
  1269.         test    edx,edx
  1270.         jnz     range_exceeded
  1271.         cmp     eax,100h
  1272.         jae     range_exceeded
  1273.       return_byte_value:
  1274.         ret
  1275.       range_exceeded:
  1276.         xor     eax,eax
  1277.         xor     edx,edx
  1278.       recoverable_overflow:
  1279.         cmp     [error_line],0
  1280.         jne     ignore_overflow
  1281.         push    [current_line]
  1282.         pop     [error_line]
  1283.         mov     [error],value_out_of_range
  1284.         or      [value_undefined],-1
  1285.       ignore_overflow:
  1286.         ret
  1287.       recoverable_misuse:
  1288.         cmp     [error_line],0
  1289.         jne     ignore_misuse
  1290.         push    [current_line]
  1291.         pop     [error_line]
  1292.         mov     [error],invalid_use_of_symbol
  1293.       ignore_misuse:
  1294.         ret
  1295. get_word_value:
  1296.         mov     [value_size],2
  1297.         or      [operand_flags],1
  1298.         call    calculate_value
  1299.         cmp     al,2
  1300.         jb      check_word_value
  1301.         call    recoverable_misuse
  1302.       check_word_value:
  1303.         mov     eax,[edi]
  1304.         mov     edx,[edi+4]
  1305.         cmp     byte [edi+13],0
  1306.         je      word_positive
  1307.         cmp     edx,-1
  1308.         jne     range_exceeded
  1309.         cmp     eax,-10000h
  1310.         jb      range_exceeded
  1311.         ret
  1312.       word_positive:
  1313.         test    edx,edx
  1314.         jnz     range_exceeded
  1315.         cmp     eax,10000h
  1316.         jae     range_exceeded
  1317.         ret
  1318. get_dword_value:
  1319.         mov     [value_size],4
  1320.         or      [operand_flags],1
  1321.         call    calculate_value
  1322.         cmp     al,4
  1323.         jne     check_dword_value
  1324.         mov     [value_type],2
  1325.         mov     eax,[edi]
  1326.         cdq
  1327.         cmp     edx,[edi+4]
  1328.         jne     range_exceeded
  1329.         mov     ecx,edx
  1330.         shr     ecx,31
  1331.         cmp     cl,[value_sign]
  1332.         jne     range_exceeded
  1333.         ret
  1334.       check_dword_value:
  1335.         mov     eax,[edi]
  1336.         mov     edx,[edi+4]
  1337.         cmp     byte [edi+13],0
  1338.         je      dword_positive
  1339.         cmp     edx,-1
  1340.         jne     range_exceeded
  1341.         ret
  1342.       dword_positive:
  1343.         test    edx,edx
  1344.         jne     range_exceeded
  1345.         ret
  1346. get_pword_value:
  1347.         mov     [value_size],6
  1348.         or      [operand_flags],1
  1349.         call    calculate_value
  1350.         cmp     al,4
  1351.         jne     check_pword_value
  1352.         call    recoverable_misuse
  1353.       check_pword_value:
  1354.         mov     eax,[edi]
  1355.         mov     edx,[edi+4]
  1356.         cmp     byte [edi+13],0
  1357.         je      pword_positive
  1358.         cmp     edx,-10000h
  1359.         jb      range_exceeded
  1360.         ret
  1361.       pword_positive:
  1362.         cmp     edx,10000h
  1363.         jae     range_exceeded
  1364.         ret
  1365. get_qword_value:
  1366.         mov     [value_size],8
  1367.         or      [operand_flags],1
  1368.         call    calculate_value
  1369.       check_qword_value:
  1370.         mov     eax,[edi]
  1371.         mov     edx,[edi+4]
  1372.         ret
  1373. get_count_value:
  1374.         mov     [value_size],8
  1375.         or      [operand_flags],1
  1376.         call    calculate_expression
  1377.         cmp     word [edi+8],0
  1378.         jne     invalid_value
  1379.         mov     [value_sign],0
  1380.         mov     al,[edi+12]
  1381.         or      al,al
  1382.         jz      check_count_value
  1383.         call    recoverable_misuse
  1384.       check_count_value:
  1385.         cmp     byte [edi+13],0
  1386.         jne     invalid_count_value
  1387.         mov     eax,[edi]
  1388.         mov     edx,[edi+4]
  1389.         or      edx,edx
  1390.         jnz     invalid_count_value
  1391.         ret
  1392.       invalid_count_value:
  1393.         cmp     [error_line],0
  1394.         jne     zero_count
  1395.         mov     eax,[current_line]
  1396.         mov     [error_line],eax
  1397.         mov     [error],invalid_value
  1398.       zero_count:
  1399.         xor     eax,eax
  1400.         ret
  1401. get_value:
  1402.         mov     [operand_size],0
  1403.         lods    byte [esi]
  1404.         call    get_size_operator
  1405.         cmp     al,'('
  1406.         jne     invalid_value
  1407.         mov     al,[operand_size]
  1408.         cmp     al,1
  1409.         je      value_byte
  1410.         cmp     al,2
  1411.         je      value_word
  1412.         cmp     al,4
  1413.         je      value_dword
  1414.         cmp     al,6
  1415.         je      value_pword
  1416.         cmp     al,8
  1417.         je      value_qword
  1418.         or      al,al
  1419.         jnz     invalid_value
  1420.         mov     [value_size],al
  1421.         call    calculate_value
  1422.         mov     eax,[edi]
  1423.         mov     edx,[edi+4]
  1424.         ret
  1425.       calculate_value:
  1426.         call    calculate_expression
  1427.         cmp     word [edi+8],0
  1428.         jne     invalid_value
  1429.         mov     eax,[edi+16]
  1430.         mov     [symbol_identifier],eax
  1431.         mov     al,[edi+13]
  1432.         mov     [value_sign],al
  1433.         mov     al,[edi+12]
  1434.         mov     [value_type],al
  1435.         ret
  1436.       value_qword:
  1437.         call    get_qword_value
  1438.       truncated_value:
  1439.         mov     [value_sign],0
  1440.         ret
  1441.       value_pword:
  1442.         call    get_pword_value
  1443.         movzx   edx,dx
  1444.         jmp     truncated_value
  1445.       value_dword:
  1446.         call    get_dword_value
  1447.         xor     edx,edx
  1448.         jmp     truncated_value
  1449.       value_word:
  1450.         call    get_word_value
  1451.         xor     edx,edx
  1452.         movzx   eax,ax
  1453.         jmp     truncated_value
  1454.       value_byte:
  1455.         call    get_byte_value
  1456.         xor     edx,edx
  1457.         movzx   eax,al
  1458.         jmp     truncated_value
  1459. get_address_word_value:
  1460.         mov     [address_size],2
  1461.         mov     [value_size],2
  1462.         mov     [free_address_range],0
  1463.         jmp     calculate_address
  1464. get_address_dword_value:
  1465.         mov     [address_size],4
  1466.         mov     [value_size],4
  1467.         mov     [free_address_range],0
  1468.         jmp     calculate_address
  1469. get_address_qword_value:
  1470.         mov     [address_size],8
  1471.         mov     [value_size],8
  1472.         mov     [free_address_range],0
  1473.         jmp     calculate_address
  1474. get_address_value:
  1475.         mov     [address_size],0
  1476.         mov     [value_size],8
  1477.         or      [free_address_range],-1
  1478.       calculate_address:
  1479.         cmp     byte [esi],'.'
  1480.         je      invalid_address
  1481.         call    calculate_expression
  1482.         mov     eax,[edi+16]
  1483.         mov     [address_symbol],eax
  1484.         mov     al,[edi+13]
  1485.         mov     [address_sign],al
  1486.         mov     al,[edi+12]
  1487.         mov     [value_type],al
  1488.         cmp     al,0
  1489.         je      address_size_ok
  1490.         jg      get_address_symbol_size
  1491.         neg     al
  1492.       get_address_symbol_size:
  1493.         cmp     al,6
  1494.         je      special_address_type_32bit
  1495.         cmp     al,5
  1496.         je      special_address_type_32bit
  1497.         ja      invalid_address_type
  1498.         test    al,1
  1499.         jnz     invalid_address_type
  1500.         shl     al,5
  1501.         jmp     address_symbol_ok
  1502.       invalid_address_type:
  1503.         call    recoverable_misuse
  1504.       special_address_type_32bit:
  1505.         mov     al,40h
  1506.       address_symbol_ok:
  1507.         mov     ah,[address_size]
  1508.         or      [address_size],al
  1509.         shr     al,4
  1510.         or      ah,ah
  1511.         jz      address_size_ok
  1512.         cmp     al,ah
  1513.         je      address_size_ok
  1514.         cmp     ax,0408h
  1515.         je      address_sizes_mixed
  1516.         cmp     ax,0804h
  1517.         jne     address_sizes_do_not_agree
  1518.       address_sizes_mixed:
  1519.         cmp     [value_type],4
  1520.         jne     address_sizes_mixed_type_ok
  1521.         mov     [value_type],2
  1522.       address_sizes_mixed_type_ok:
  1523.         mov     eax,[edi]
  1524.         cdq
  1525.         cmp     edx,[edi+4]
  1526.         je      address_size_ok
  1527.         cmp     [error_line],0
  1528.         jne     address_size_ok
  1529.         call    recoverable_overflow
  1530.       address_size_ok:
  1531.         xor     ebx,ebx
  1532.         xor     ecx,ecx
  1533.         mov     cl,[value_type]
  1534.         shl     ecx,16
  1535.         mov     ch,[address_size]
  1536.         cmp     word [edi+8],0
  1537.         je      check_immediate_address
  1538.         mov     al,[edi+8]
  1539.         mov     dl,[edi+10]
  1540.         call    get_address_register
  1541.         mov     al,[edi+9]
  1542.         mov     dl,[edi+11]
  1543.         call    get_address_register
  1544.         mov     ax,bx
  1545.         shr     ah,4
  1546.         shr     al,4
  1547.         or      bh,bh
  1548.         jz      check_address_registers
  1549.         or      bl,bl
  1550.         jz      check_address_registers
  1551.         cmp     al,ah
  1552.         jne     check_vsib
  1553.       check_address_registers:
  1554.         or      al,ah
  1555.         cmp     al,0Ch
  1556.         jae     check_vsib
  1557.         cmp     al,6
  1558.         je      check_vsib
  1559.         cmp     al,7
  1560.         je      check_vsib
  1561.         mov     ah,[address_size]
  1562.         and     ah,0Fh
  1563.         jz      address_registers_sizes_ok
  1564.         cmp     al,ah
  1565.         jne     invalid_address
  1566.       address_registers_sizes_ok:
  1567.         cmp     al,4
  1568.         je      sib_allowed
  1569.         cmp     al,8
  1570.         je      sib_allowed
  1571.         cmp     al,9
  1572.         je      check_ip_relative_address
  1573.         cmp     cl,1
  1574.         ja      invalid_address
  1575.         cmp     [free_address_range],0
  1576.         jne     check_qword_value
  1577.         jmp     check_word_value
  1578.       address_sizes_do_not_match:
  1579.         cmp     al,0Fh
  1580.         jne     invalid_address
  1581.         mov     al,bh
  1582.         and     al,0Fh
  1583.         cmp     al,ah
  1584.         jne     invalid_address
  1585.       check_ip_relative_address:
  1586.         or      bl,bl
  1587.         jnz     invalid_address
  1588.         cmp     bh,98h
  1589.         je      check_rip_relative_address
  1590.         cmp     bh,94h
  1591.         jne     invalid_address
  1592.         cmp     [free_address_range],0
  1593.         je      check_dword_value
  1594.         mov     eax,[edi]
  1595.         mov     edx,[edi+4]
  1596.         ret
  1597.       check_rip_relative_address:
  1598.         mov     eax,[edi]
  1599.         cdq
  1600.         cmp     edx,[edi+4]
  1601.         jne     range_exceeded
  1602.         cmp     dl,[edi+13]
  1603.         jne     range_exceeded
  1604.         ret
  1605.       get_address_register:
  1606.         or      al,al
  1607.         jz      address_register_ok
  1608.         cmp     dl,1
  1609.         jne     scaled_register
  1610.         or      bh,bh
  1611.         jnz     scaled_register
  1612.         mov     bh,al
  1613.       address_register_ok:
  1614.         ret
  1615.       scaled_register:
  1616.         or      bl,bl
  1617.         jnz     invalid_address
  1618.         mov     bl,al
  1619.         mov     cl,dl
  1620.         jmp     address_register_ok
  1621.       sib_allowed:
  1622.         or      bh,bh
  1623.         jnz     check_index_with_base
  1624.         cmp     cl,3
  1625.         je      special_index_scale
  1626.         cmp     cl,5
  1627.         je      special_index_scale
  1628.         cmp     cl,9
  1629.         je      special_index_scale
  1630.         cmp     cl,2
  1631.         jne     check_index_scale
  1632.         cmp     bl,45h
  1633.         jne     special_index_scale
  1634.         cmp     [code_type],64
  1635.         je      special_index_scale
  1636.         cmp     [segment_register],4
  1637.         jne     special_index_scale
  1638.         cmp     [value_type],0
  1639.         jne     check_index_scale
  1640.         mov     al,[edi]
  1641.         cbw
  1642.         cwde
  1643.         cmp     eax,[edi]
  1644.         jne     check_index_scale
  1645.         cdq
  1646.         cmp     edx,[edi+4]
  1647.         jne     check_immediate_address
  1648.       special_index_scale:
  1649.         mov     bh,bl
  1650.         dec     cl
  1651.       check_immediate_address:
  1652.         cmp     [free_address_range],0
  1653.         jne     check_qword_value
  1654.         mov     al,[address_size]
  1655.         and     al,0Fh
  1656.         cmp     al,2
  1657.         je      check_word_value
  1658.         cmp     al,4
  1659.         je      check_dword_value
  1660.         cmp     al,8
  1661.         je      check_qword_value
  1662.         or      al,al
  1663.         jnz     invalid_value
  1664.         cmp     [code_type],64
  1665.         jne     check_dword_value
  1666.         jmp     check_qword_value
  1667.       check_index_with_base:
  1668.         cmp     cl,1
  1669.         jne     check_index_scale
  1670.         cmp     bl,44h
  1671.         je      swap_base_with_index
  1672.         cmp     bl,84h
  1673.         je      swap_base_with_index
  1674.         cmp     [code_type],64
  1675.         je      check_for_rbp_base
  1676.         cmp     bl,45h
  1677.         jne     check_for_ebp_base
  1678.         cmp     [segment_register],3
  1679.         je      swap_base_with_index
  1680.         jmp     check_immediate_address
  1681.       check_for_ebp_base:
  1682.         cmp     bh,45h
  1683.         jne     check_immediate_address
  1684.         cmp     [segment_register],4
  1685.         jne     check_immediate_address
  1686.       swap_base_with_index:
  1687.         xchg    bl,bh
  1688.         jmp     check_immediate_address
  1689.       check_for_rbp_base:
  1690.         cmp     bh,45h
  1691.         je      swap_base_with_index
  1692.         cmp     bh,85h
  1693.         je      swap_base_with_index
  1694.         jmp     check_immediate_address
  1695.       check_index_scale:
  1696.         test    cl,not 1111b
  1697.         jnz     invalid_address
  1698.         mov     al,cl
  1699.         dec     al
  1700.         and     al,cl
  1701.         jz      check_immediate_address
  1702.         jmp     invalid_address
  1703.       check_vsib:
  1704.         xor     ah,ah
  1705.       check_vsib_base:
  1706.         test    bh,bh
  1707.         jz      check_vsib_index
  1708.         mov     al,bh
  1709.         shr     al,4
  1710.         cmp     al,4
  1711.         je      check_vsib_base_size
  1712.         cmp     [code_type],64
  1713.         jne     swap_vsib_registers
  1714.         cmp     al,8
  1715.         jne     swap_vsib_registers
  1716.       check_vsib_base_size:
  1717.         mov     ah,[address_size]
  1718.         and     ah,0Fh
  1719.         jz      check_vsib_index
  1720.         cmp     al,ah
  1721.         jne     invalid_address
  1722.       check_vsib_index:
  1723.         mov     al,bl
  1724.         and     al,0E0h
  1725.         cmp     al,0C0h
  1726.         jae     check_index_scale
  1727.         cmp     al,60h
  1728.         je      check_index_scale
  1729.         jmp     invalid_address
  1730.       swap_vsib_registers:
  1731.         xor     ah,-1
  1732.         jz      invalid_address
  1733.         cmp     cl,1
  1734.         ja      invalid_address
  1735.         xchg    bl,bh
  1736.         mov     cl,1
  1737.         jmp     check_vsib_base
  1738.  
  1739. calculate_relative_offset:
  1740.         cmp     [value_undefined],0
  1741.         jne     relative_offset_ok
  1742.         test    bh,bh
  1743.         setne   ch
  1744.         cmp     bx,[ds:ebp+10h]
  1745.         je      origin_registers_ok
  1746.         xchg    bh,bl
  1747.         xchg    ch,cl
  1748.         cmp     bx,[ds:ebp+10h]
  1749.         jne     invalid_value
  1750.       origin_registers_ok:
  1751.         cmp     cx,[ds:ebp+10h+2]
  1752.         jne     invalid_value
  1753.         mov     bl,[address_sign]
  1754.         add     eax,[ds:ebp]
  1755.         adc     edx,[ds:ebp+4]
  1756.         adc     bl,[ds:ebp+8]
  1757.         sub     eax,edi
  1758.         sbb     edx,0
  1759.         sbb     bl,0
  1760.         mov     [value_sign],bl
  1761.         mov     bl,[value_type]
  1762.         mov     ecx,[address_symbol]
  1763.         mov     [symbol_identifier],ecx
  1764.         test    bl,1
  1765.         jnz     relative_offset_unallowed
  1766.         cmp     bl,6
  1767.         je      plt_relative_offset
  1768.         mov     bh,[ds:ebp+9]
  1769.         cmp     bl,bh
  1770.         je      set_relative_offset_type
  1771.         cmp     bx,0402h
  1772.         je      set_relative_offset_type
  1773.       relative_offset_unallowed:
  1774.         call    recoverable_misuse
  1775.       set_relative_offset_type:
  1776.         cmp     [value_type],0
  1777.         je      relative_offset_ok
  1778.         mov     [value_type],0
  1779.         cmp     ecx,[ds:ebp+14h]
  1780.         je      relative_offset_ok
  1781.         mov     [value_type],3
  1782.       relative_offset_ok:
  1783.         ret
  1784.       plt_relative_offset:
  1785.         mov     [value_type],7
  1786.         cmp     byte [ds:ebp+9],2
  1787.         je      relative_offset_ok
  1788.         cmp     byte [ds:ebp+9],4
  1789.         jne     recoverable_misuse
  1790.         ret
  1791.  
  1792. calculate_logical_expression:
  1793.         xor     al,al
  1794.   calculate_embedded_logical_expression:
  1795.         mov     [logical_value_wrapping],al
  1796.         call    get_logical_value
  1797.       logical_loop:
  1798.         cmp     byte [esi],'|'
  1799.         je      logical_or
  1800.         cmp     byte [esi],'&'
  1801.         je      logical_and
  1802.         ret
  1803.       logical_or:
  1804.         inc     esi
  1805.         or      al,al
  1806.         jnz     logical_value_already_determined
  1807.         push    eax
  1808.         call    get_logical_value
  1809.         pop     ebx
  1810.         or      al,bl
  1811.         jmp     logical_loop
  1812.       logical_and:
  1813.         inc     esi
  1814.         or      al,al
  1815.         jz      logical_value_already_determined
  1816.         push    eax
  1817.         call    get_logical_value
  1818.         pop     ebx
  1819.         and     al,bl
  1820.         jmp     logical_loop
  1821.       logical_value_already_determined:
  1822.         push    eax
  1823.         call    skip_logical_value
  1824.         jc      invalid_expression
  1825.         pop     eax
  1826.         jmp     logical_loop
  1827.   get_value_for_comparison:
  1828.         mov     [value_size],8
  1829.         or      [operand_flags],1
  1830.         lods    byte [esi]
  1831.         call    calculate_expression
  1832.         cmp     byte [edi+8],0
  1833.         jne     first_register_size_ok
  1834.         mov     byte [edi+10],0
  1835.       first_register_size_ok:
  1836.         cmp     byte [edi+9],0
  1837.         jne     second_register_size_ok
  1838.         mov     byte [edi+11],0
  1839.       second_register_size_ok:
  1840.         mov     eax,[edi+16]
  1841.         mov     [symbol_identifier],eax
  1842.         mov     al,[edi+13]
  1843.         mov     [value_sign],al
  1844.         mov     bl,[edi+12]
  1845.         mov     eax,[edi]
  1846.         mov     edx,[edi+4]
  1847.         mov     ecx,[edi+8]
  1848.         ret
  1849.   get_logical_value:
  1850.         xor     al,al
  1851.       check_for_negation:
  1852.         cmp     byte [esi],'~'
  1853.         jne     negation_ok
  1854.         inc     esi
  1855.         xor     al,-1
  1856.         jmp     check_for_negation
  1857.       negation_ok:
  1858.         push    eax
  1859.         mov     al,[esi]
  1860.         cmp     al,91h
  1861.         je      logical_expression
  1862.         cmp     al,0FFh
  1863.         je      invalid_expression
  1864.         cmp     al,88h
  1865.         je      check_for_defined
  1866.         cmp     al,8Ah
  1867.         je      check_for_earlier_defined
  1868.         cmp     al,89h
  1869.         je      check_for_used
  1870.         cmp     al,'0'
  1871.         je      given_false
  1872.         cmp     al,'1'
  1873.         je      given_true
  1874.         cmp     al,'('
  1875.         jne     invalid_value
  1876.         call    get_value_for_comparison
  1877.         mov     bh,[value_sign]
  1878.         push    eax edx [symbol_identifier] ebx ecx
  1879.         mov     al,[esi]
  1880.         or      al,al
  1881.         jz      logical_number
  1882.         cmp     al,0Fh
  1883.         je      logical_number
  1884.         cmp     al,92h
  1885.         je      logical_number
  1886.         cmp     al,'&'
  1887.         je      logical_number
  1888.         cmp     al,'|'
  1889.         je      logical_number
  1890.         inc     esi
  1891.         mov     [compare_type],al
  1892.         cmp     byte [esi],'('
  1893.         jne     invalid_value
  1894.         call    get_value_for_comparison
  1895.         cmp     bl,[esp+4]
  1896.         jne     values_not_relative
  1897.         or      bl,bl
  1898.         jz      check_values_registers
  1899.         mov     ebx,[symbol_identifier]
  1900.         cmp     ebx,[esp+8]
  1901.         jne     values_not_relative
  1902.       check_values_registers:
  1903.         cmp     ecx,[esp]
  1904.         je      values_relative
  1905.         ror     ecx,16
  1906.         xchg    ch,cl
  1907.         ror     ecx,16
  1908.         xchg    ch,cl
  1909.         cmp     ecx,[esp]
  1910.         je      values_relative
  1911.       values_not_relative:
  1912.         cmp     [compare_type],0F8h
  1913.         jne     invalid_comparison
  1914.         add     esp,12+8
  1915.         jmp     return_false
  1916.       invalid_comparison:
  1917.         call    recoverable_misuse
  1918.       values_relative:
  1919.         pop     ebx
  1920.         shl     ebx,16
  1921.         mov     bx,[esp]
  1922.         add     esp,8
  1923.         pop     ecx ebp
  1924.         cmp     [compare_type],'='
  1925.         je      check_equal
  1926.         cmp     [compare_type],0F1h
  1927.         je      check_not_equal
  1928.         cmp     [compare_type],0F8h
  1929.         je      return_true
  1930.         test    ebx,0FFFF0000h
  1931.         jz      check_less_or_greater
  1932.         call    recoverable_misuse
  1933.       check_less_or_greater:
  1934.         cmp     [compare_type],'>'
  1935.         je      check_greater
  1936.         cmp     [compare_type],'<'
  1937.         je      check_less
  1938.         cmp     [compare_type],0F2h
  1939.         je      check_not_less
  1940.         cmp     [compare_type],0F3h
  1941.         je      check_not_greater
  1942.         jmp     invalid_expression
  1943.       check_equal:
  1944.         cmp     bh,[value_sign]
  1945.         jne     return_false
  1946.         cmp     eax,ebp
  1947.         jne     return_false
  1948.         cmp     edx,ecx
  1949.         jne     return_false
  1950.         jmp     return_true
  1951.       check_greater:
  1952.         cmp     bh,[value_sign]
  1953.         jg      return_true
  1954.         jl      return_false
  1955.         cmp     edx,ecx
  1956.         jb      return_true
  1957.         ja      return_false
  1958.         cmp     eax,ebp
  1959.         jb      return_true
  1960.         jae     return_false
  1961.       check_less:
  1962.         cmp     bh,[value_sign]
  1963.         jg      return_false
  1964.         jl      return_true
  1965.         cmp     edx,ecx
  1966.         jb      return_false
  1967.         ja      return_true
  1968.         cmp     eax,ebp
  1969.         jbe     return_false
  1970.         ja      return_true
  1971.       check_not_less:
  1972.         cmp     bh,[value_sign]
  1973.         jg      return_true
  1974.         jl      return_false
  1975.         cmp     edx,ecx
  1976.         jb      return_true
  1977.         ja      return_false
  1978.         cmp     eax,ebp
  1979.         jbe     return_true
  1980.         ja      return_false
  1981.       check_not_greater:
  1982.         cmp     bh,[value_sign]
  1983.         jg      return_false
  1984.         jl      return_true
  1985.         cmp     edx,ecx
  1986.         jb      return_false
  1987.         ja      return_true
  1988.         cmp     eax,ebp
  1989.         jb      return_false
  1990.         jae     return_true
  1991.       check_not_equal:
  1992.         cmp     bh,[value_sign]
  1993.         jne     return_true
  1994.         cmp     eax,ebp
  1995.         jne     return_true
  1996.         cmp     edx,ecx
  1997.         jne     return_true
  1998.         jmp     return_false
  1999.       logical_number:
  2000.         pop     ecx ebx eax edx eax
  2001.         or      bl,bl
  2002.         jnz     invalid_logical_number
  2003.         or      cx,cx
  2004.         jz      logical_number_ok
  2005.       invalid_logical_number:
  2006.         call    recoverable_misuse
  2007.       logical_number_ok:
  2008.         test    bh,bh
  2009.         jnz     return_true
  2010.         or      eax,edx
  2011.         jnz     return_true
  2012.         jmp     return_false
  2013.       check_for_earlier_defined:
  2014.         or      bh,-1
  2015.         jmp     check_if_expression_defined
  2016.       check_for_defined:
  2017.         xor     bh,bh
  2018.       check_if_expression_defined:
  2019.         or      bl,-1
  2020.         lods    word [esi]
  2021.         cmp     ah,'('
  2022.         jne     invalid_expression
  2023.       check_expression:
  2024.         lods    byte [esi]
  2025.         or      al,al
  2026.         jz      defined_string
  2027.         cmp     al,'.'
  2028.         je      defined_fp_value
  2029.         cmp     al,')'
  2030.         je      expression_checked
  2031.         cmp     al,'!'
  2032.         je      invalid_expression
  2033.         cmp     al,0Fh
  2034.         je      check_expression
  2035.         cmp     al,10h
  2036.         je      defined_register
  2037.         cmp     al,11h
  2038.         je      check_if_symbol_defined
  2039.         cmp     al,80h
  2040.         jae     check_expression
  2041.         movzx   eax,al
  2042.         add     esi,eax
  2043.         jmp     check_expression
  2044.       defined_register:
  2045.         inc     esi
  2046.         jmp     check_expression
  2047.       defined_fp_value:
  2048.         add     esi,12+1
  2049.         jmp     expression_checked
  2050.       defined_string:
  2051.         lods    dword [esi]
  2052.         add     esi,eax
  2053.         inc     esi
  2054.         jmp     expression_checked
  2055.       check_if_symbol_defined:
  2056.         lods    dword [esi]
  2057.         cmp     eax,-1
  2058.         je      invalid_expression
  2059.         cmp     eax,0Fh
  2060.         jb      check_expression
  2061.         je      reserved_word_used_as_symbol
  2062.         test    bh,bh
  2063.         jnz     no_prediction
  2064.         test    byte [eax+8],4
  2065.         jnz     no_prediction
  2066.         test    byte [eax+8],1
  2067.         jz      symbol_predicted_undefined
  2068.         mov     cx,[current_pass]
  2069.         sub     cx,[eax+16]
  2070.         jz      check_expression
  2071.         cmp     cx,1
  2072.         ja      symbol_predicted_undefined
  2073.         or      byte [eax+8],40h+80h
  2074.         jmp     check_expression
  2075.       no_prediction:
  2076.         test    byte [eax+8],1
  2077.         jz      symbol_undefined
  2078.         mov     cx,[current_pass]
  2079.         sub     cx,[eax+16]
  2080.         jz      check_expression
  2081.         jmp     symbol_undefined
  2082.       symbol_predicted_undefined:
  2083.         or      byte [eax+8],40h
  2084.         and     byte [eax+8],not 80h
  2085.       symbol_undefined:
  2086.         xor     bl,bl
  2087.         jmp     check_expression
  2088.       expression_checked:
  2089.         mov     al,bl
  2090.         jmp     logical_value_ok
  2091.       check_for_used:
  2092.         lods    word [esi]
  2093.         cmp     ah,2
  2094.         jne     invalid_expression
  2095.         lods    dword [esi]
  2096.         cmp     eax,0Fh
  2097.         jb      invalid_use_of_symbol
  2098.         je      reserved_word_used_as_symbol
  2099.         inc     esi
  2100.         test    byte [eax+8],8
  2101.         jz      not_used
  2102.         mov     cx,[current_pass]
  2103.         sub     cx,[eax+18]
  2104.         jz      return_true
  2105.         cmp     cx,1
  2106.         ja      not_used
  2107.         or      byte [eax+8],10h+20h
  2108.         jmp     return_true
  2109.       not_used:
  2110.         or      byte [eax+8],10h
  2111.         and     byte [eax+8],not 20h
  2112.         jmp     return_false
  2113.       given_false:
  2114.         inc     esi
  2115.       return_false:
  2116.         xor     al,al
  2117.         jmp     logical_value_ok
  2118.       given_true:
  2119.         inc     esi
  2120.       return_true:
  2121.         or      al,-1
  2122.         jmp     logical_value_ok
  2123.       logical_expression:
  2124.         lods    byte [esi]
  2125.         mov     dl,[logical_value_wrapping]
  2126.         push    edx
  2127.         call    calculate_embedded_logical_expression
  2128.         pop     edx
  2129.         mov     [logical_value_wrapping],dl
  2130.         push    eax
  2131.         lods    byte [esi]
  2132.         cmp     al,92h
  2133.         jne     invalid_expression
  2134.         pop     eax
  2135.       logical_value_ok:
  2136.         pop     ebx
  2137.         xor     al,bl
  2138.         ret
  2139.  
  2140. skip_symbol:
  2141.         lods    byte [esi]
  2142.         or      al,al
  2143.         jz      nothing_to_skip
  2144.         cmp     al,0Fh
  2145.         je      nothing_to_skip
  2146.         cmp     al,1
  2147.         je      skip_instruction
  2148.         cmp     al,2
  2149.         je      skip_label
  2150.         cmp     al,3
  2151.         je      skip_label
  2152.         cmp     al,4
  2153.         je      skip_special_label
  2154.         cmp     al,20h
  2155.         jb      skip_assembler_symbol
  2156.         cmp     al,'('
  2157.         je      skip_expression
  2158.         cmp     al,'['
  2159.         je      skip_address
  2160.       skip_done:
  2161.         clc
  2162.         ret
  2163.       skip_label:
  2164.         add     esi,2
  2165.       skip_instruction:
  2166.         add     esi,2
  2167.       skip_assembler_symbol:
  2168.         inc     esi
  2169.         jmp     skip_done
  2170.       skip_special_label:
  2171.         add     esi,4
  2172.         jmp     skip_done
  2173.       skip_address:
  2174.         mov     al,[esi]
  2175.         and     al,11110000b
  2176.         cmp     al,60h
  2177.         jb      skip_expression
  2178.         cmp     al,70h
  2179.         ja      skip_expression
  2180.         inc     esi
  2181.         jmp     skip_address
  2182.       skip_expression:
  2183.         lods    byte [esi]
  2184.         or      al,al
  2185.         jz      skip_string
  2186.         cmp     al,'.'
  2187.         je      skip_fp_value
  2188.         cmp     al,')'
  2189.         je      skip_done
  2190.         cmp     al,']'
  2191.         je      skip_done
  2192.         cmp     al,'!'
  2193.         je      skip_expression
  2194.         cmp     al,0Fh
  2195.         je      skip_expression
  2196.         cmp     al,10h
  2197.         je      skip_register
  2198.         cmp     al,11h
  2199.         je      skip_label_value
  2200.         cmp     al,80h
  2201.         jae     skip_expression
  2202.         movzx   eax,al
  2203.         add     esi,eax
  2204.         jmp     skip_expression
  2205.       skip_label_value:
  2206.         add     esi,3
  2207.       skip_register:
  2208.         inc     esi
  2209.         jmp     skip_expression
  2210.       skip_fp_value:
  2211.         add     esi,12
  2212.         jmp     skip_done
  2213.       skip_string:
  2214.         lods    dword [esi]
  2215.         add     esi,eax
  2216.         inc     esi
  2217.         jmp     skip_done
  2218.       nothing_to_skip:
  2219.         dec     esi
  2220.         stc
  2221.         ret
  2222.  
  2223. expand_path:
  2224.         lods    byte [esi]
  2225.         cmp     al,'%'
  2226.         je      environment_variable
  2227.         stos    byte [edi]
  2228.         or      al,al
  2229.         jnz     expand_path
  2230.         cmp     edi,[memory_end]
  2231.         ja      out_of_memory
  2232.         ret
  2233.       environment_variable:
  2234.         mov     ebx,esi
  2235.       find_variable_end:
  2236.         lods    byte [esi]
  2237.         or      al,al
  2238.         jz      not_environment_variable
  2239.         cmp     al,'%'
  2240.         jne     find_variable_end
  2241.         mov     byte [esi-1],0
  2242.         push    esi
  2243.         mov     esi,ebx
  2244.         call    get_environment_variable
  2245.         pop     esi
  2246.         mov     byte [esi-1],'%'
  2247.         jmp     expand_path
  2248.       not_environment_variable:
  2249.         mov     al,'%'
  2250.         stos    byte [edi]
  2251.         mov     esi,ebx
  2252.         jmp     expand_path
  2253. get_include_directory:
  2254.         lods    byte [esi]
  2255.         cmp     al,';'
  2256.         je      include_directory_ok
  2257.         stos    byte [edi]
  2258.         or      al,al
  2259.         jnz     get_include_directory
  2260.         dec     esi
  2261.         dec     edi
  2262.       include_directory_ok:
  2263.         cmp     byte [edi-1],'/'
  2264.         je      path_separator_ok
  2265.         cmp     byte [edi-1],'\'
  2266.         je      path_separator_ok
  2267.         mov     al,'/'
  2268.         stos    byte [edi]
  2269.       path_separator_ok:
  2270.         ret
  2271.