Subversion Repositories Kolibri OS

Rev

Rev 3011 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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