Subversion Repositories Kolibri OS

Rev

Rev 4478 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

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