Subversion Repositories Kolibri OS

Rev

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

  1.  
  2. HEAP_BASE equ 0x00C00000
  3. ;HEAP_SIZE equ 0x01000000
  4.  
  5. struc MEM_BLOCK
  6. {  .next_block  dd ?
  7.    .prev_block  dd ? ;+4
  8.    .list_next   dd ? ;+8
  9.    .list_prev   dd ? ;+12
  10.    .base        dd ? ;+16
  11.    .size        dd ? ;+20
  12.    .flags       dd ? ;+24
  13.    .handle      dd ? ;+28
  14. }
  15.  
  16. FREE_BLOCK      equ  4
  17. USED_BLOCK      equ  8
  18.  
  19. virtual at 0
  20.   MEM_BLOCK MEM_BLOCK
  21. end virtual
  22.  
  23. MEM_BLOCK_SIZE equ 8*4
  24.  
  25. block_next   equ MEM_BLOCK.next_block
  26. block_prev   equ MEM_BLOCK.prev_block
  27. list_next    equ MEM_BLOCK.list_next
  28. list_prev    equ MEM_BLOCK.list_prev
  29. block_base   equ MEM_BLOCK.base
  30. block_size   equ MEM_BLOCK.size
  31. block_flags  equ MEM_BLOCK.flags
  32.  
  33. macro calc_index op
  34. {          shr op, 12
  35.            dec op
  36.            cmp op, 63
  37.            jna @f
  38.            mov op, 63
  39. @@:
  40. }
  41.  
  42. macro remove_from_list op
  43. {          mov edx, [op+list_next]
  44.            mov ecx, [op+list_prev]
  45.            test edx, edx
  46.            jz @f
  47.            mov [edx+list_prev], ecx
  48. @@:
  49.            test ecx, ecx
  50.            jz @f
  51.            mov [ecx+list_next], edx
  52. @@:
  53.            mov [op+list_next],0
  54.            mov [op+list_prev],0
  55. }
  56.  
  57. macro remove_from_free op
  58. {
  59.            remove_from_list op
  60.  
  61.            mov eax, [op+block_size]
  62.            calc_index eax
  63.            cmp [mem_block_list+eax*4], op
  64.            jne @f
  65.            mov [mem_block_list+eax*4], edx
  66. @@:
  67.            cmp [mem_block_list+eax*4], 0
  68.            jne @f
  69.            btr [mem_block_mask], eax
  70. @@:
  71. }
  72.  
  73. macro remove_from_used op
  74. {
  75.            remove_from_list op
  76.            cmp [mem_used_list], op
  77.            jne @f
  78.            mov [mem_used_list], edx
  79. @@:
  80. }
  81.  
  82. align 4
  83. proc init_kernel_heap
  84.  
  85.            mov ecx, 64/4
  86.            mov edi, mem_block_list
  87.            xor eax, eax
  88.            cld
  89.            rep stosd
  90.  
  91.            mov ecx, 512/4
  92.            mov edi, mem_block_map
  93.            not eax
  94.            rep stosd
  95.  
  96.            mov [mem_block_start], mem_block_map
  97.            mov [mem_block_end], mem_block_map+512
  98.            mov [mem_block_arr], HEAP_BASE
  99.  
  100.            stdcall alloc_pages, dword 32
  101.            mov ecx, 32
  102.            mov edx, eax
  103.            mov edi, HEAP_BASE
  104. .l1:
  105.            stdcall map_page,edi,edx,PG_SW
  106.            add edi, 0x1000
  107.            add edx, 0x1000
  108.            dec ecx
  109.            jnz .l1
  110.  
  111.            mov edi, HEAP_BASE
  112.            mov ebx, edi
  113.            add ebx, MEM_BLOCK_SIZE
  114.            xor eax, eax
  115.            mov [edi+block_next], ebx
  116.            mov [edi+block_prev], eax
  117.            mov [edi+list_next], eax
  118.            mov [edi+list_prev], eax
  119.            mov [edi+block_base], HEAP_BASE
  120.            mov [edi+block_size], 4096*MEM_BLOCK_SIZE
  121.            mov [edi+block_flags], USED_BLOCK
  122.  
  123.            mov [ebx+block_next], eax
  124.            mov [ebx+block_prev], eax
  125.            mov [ebx+list_next], eax
  126.            mov [ebx+block_base], HEAP_BASE+4096*MEM_BLOCK_SIZE
  127.  
  128.            mov ecx, [MEM_AMOUNT]
  129.            sub ecx, HEAP_BASE + 4096*MEM_BLOCK_SIZE
  130.            mov [heap_size], ecx
  131.            mov [heap_free], ecx
  132.            mov [ebx+block_size], ecx
  133.            mov [ebx+block_flags], FREE_BLOCK
  134.  
  135.            mov [mem_block_mask], eax
  136.            mov [mem_block_mask+4],0x80000000
  137.  
  138.            mov [mem_used_list], eax
  139.            mov [mem_block_list+63*4], ebx
  140.            mov byte [mem_block_map], 0xFC
  141.            and [heap_mutex], 0
  142.            mov [heap_blocks], 4095
  143.            mov [free_blocks], 4095
  144.            ret
  145. endp
  146.  
  147. align 4
  148. proc get_block stdcall, index:dword
  149.  
  150.            mov eax, 63
  151.            mov ecx, [index]
  152.            cmp ecx, eax
  153.            jna @f
  154.            ;cmova ecx, eax
  155.            mov ecx, eax
  156. @@:
  157.            xor esi, esi
  158.            xor ebx, ebx
  159.            xor edx, edx
  160.            not edx
  161.  
  162.            cmp ecx, 32
  163.            jb .bit_test
  164.  
  165.            sub ecx, 32
  166.            add ebx, 32
  167.            add esi, 4
  168.  
  169. .bit_test:
  170.            shl edx, cl
  171.            and edx, [mem_block_mask+esi]
  172.            jz .high_mask
  173.            bsf eax, edx
  174.            add ebx, eax
  175.            mov eax, [mem_block_list+ebx*4]
  176.            ret
  177.  
  178. .high_mask:
  179.  
  180.            add esi, 4
  181.            add ebx, 32
  182.            test esi, 0xFFFFFFF8
  183.            jnz .big_error
  184.            mov edx, [mem_block_mask+esi]
  185.            and edx, edx
  186.            jz .high_mask
  187.            bsf eax, edx
  188.            add ebx, eax
  189.            mov eax, [mem_block_list+ebx*4]
  190.            ret
  191.  
  192. .big_error:
  193.            xor eax, eax
  194.            ret
  195. endp
  196.  
  197. align 4
  198. proc alloc_mem_block
  199.  
  200.            mov ebx, [mem_block_start]
  201.            mov ecx, [mem_block_end]
  202. .l1:
  203.            bsf eax,[ebx];
  204.            jnz found
  205.            add ebx,4
  206.            cmp ebx, ecx
  207.            jb .l1
  208.            xor eax,eax
  209.            ret
  210.  
  211. found:
  212.            btr [ebx], eax
  213.            mov [mem_block_start],ebx
  214.            sub ebx, mem_block_map
  215.            lea eax,[eax+ebx*8]
  216.            shl eax, 5
  217.            add eax, [mem_block_arr]
  218.            dec [free_blocks]
  219.            ret
  220. endp
  221.  
  222. proc free_mem_block
  223.            sub eax, [mem_block_arr]
  224.            shr eax, 5
  225.  
  226.            mov ebx, mem_block_map
  227.            bts [ebx], eax
  228.            inc [free_blocks]
  229.            shr eax, 3
  230.            and eax, not 3
  231.            add eax, ebx
  232.            cmp [mem_block_start], eax
  233.            ja @f
  234.            ret
  235. @@:
  236.            mov [mem_block_start], eax
  237.            ret
  238. .err:
  239.            xor eax, eax
  240.            ret
  241. endp
  242.  
  243. align 4
  244. proc alloc_kernel_space stdcall, size:dword
  245.            local block_ind:DWORD
  246.  
  247.            mov eax, [size]
  248.            add eax, 4095
  249.            and eax, not 4095
  250.            mov [size], eax
  251.  
  252.            mov ebx, heap_mutex
  253.            call wait_mutex    ;ebx
  254.  
  255.            cmp eax, [heap_free]
  256.            ja .error
  257.  
  258.            shr eax, 12
  259.            sub eax, 1
  260.  
  261.            mov [block_ind], eax
  262.  
  263.            stdcall get_block, eax
  264.            test eax, eax
  265.            jz .error
  266.  
  267.            mov edi, eax           ;edi - pBlock
  268.  
  269.            cmp [edi+block_flags], FREE_BLOCK
  270.            jne .error
  271.  
  272.            mov [block_ind], ebx   ;index of allocated block
  273.  
  274.            mov eax, [edi+block_size]
  275.            cmp eax, [size]
  276.            je .m_eq_size
  277.  
  278.            call alloc_mem_block
  279.            and eax, eax
  280.            jz .error
  281.  
  282.            mov esi, eax           ;esi - splitted block
  283.  
  284.            mov [esi+block_next], edi
  285.            mov eax, [edi+block_prev]
  286.            mov [esi+block_prev], eax
  287.            mov [edi+block_prev], esi
  288.            mov [esi+list_next], 0
  289.            mov [esi+list_prev], 0
  290.            and eax, eax
  291.            jz @f
  292.            mov [eax+block_next], esi
  293. @@:
  294.            mov ebx, [edi+block_base]
  295.            mov [esi+block_base], ebx
  296.            mov edx, [size]
  297.            mov [esi+block_size], edx
  298.            add [edi+block_base], edx
  299.            sub [edi+block_size], edx
  300.  
  301.            mov eax, [edi+block_size]
  302.            shr eax, 12
  303.            sub eax, 1
  304.            cmp eax, 63
  305.            jna @f
  306.            mov eax, 63
  307. @@:
  308.            cmp eax, [block_ind]
  309.            je .m_eq_ind
  310.  
  311.            remove_from_list edi
  312.  
  313.            mov ecx, [block_ind]
  314.            mov [mem_block_list+ecx*4], edx
  315.  
  316.            test edx, edx
  317.            jnz @f
  318.            btr [mem_block_mask], ecx
  319. @@:
  320.            mov edx, [mem_block_list+eax*4]
  321.            mov [edi+list_next], edx
  322.            test edx, edx
  323.            jz @f
  324.            mov [edx+list_prev], edi
  325. @@:
  326.            mov [mem_block_list+eax*4], edi
  327.            bts [mem_block_mask], eax
  328. .m_eq_ind:
  329.            mov ebx, [mem_used_list]
  330.            mov [esi+list_next], ebx
  331.            test ebx, ebx
  332.            jz @f
  333.            mov [ebx+list_prev], esi
  334. @@:
  335.            mov [esi+block_flags], USED_BLOCK
  336.            mov [mem_used_list], esi
  337.            mov eax, [esi+block_base]
  338.            mov ebx, [size]
  339.            sub [heap_free], ebx
  340.            and [heap_mutex], 0
  341.            ret
  342. .m_eq_size:
  343.            remove_from_list edi
  344.            mov [mem_block_list+ebx*4], edx
  345.            and edx, edx
  346.            jnz @f
  347.            btr [mem_block_mask], ebx
  348. @@:
  349.            mov ecx, [mem_used_list]
  350.            mov [edi+list_next], ecx
  351.            test ecx, ecx
  352.            jnz @f
  353.            mov [ecx+list_prev], edi
  354. @@:
  355.            mov [mem_used_list], edi
  356.            mov [edi+block_flags], USED_BLOCK
  357.            mov eax, [edi+block_base]
  358.            mov ebx, [size]
  359.            sub [heap_free], ebx
  360.            and [heap_mutex], 0
  361.            ret
  362. .error:
  363.            xor eax, eax
  364.            mov [heap_mutex], eax
  365.            ret
  366. endp
  367.  
  368. align 4
  369. proc free_kernel_space stdcall uses ebx ecx edx esi edi, base:dword
  370.  
  371.            mov ebx, heap_mutex
  372.            call wait_mutex    ;ebx
  373.  
  374.            mov eax, [base]
  375.            mov esi, [mem_used_list]
  376. @@:
  377.            test esi, esi
  378.            jz .fail
  379.  
  380.            cmp [esi+block_base], eax
  381.            je .found
  382.            mov esi, [esi+list_next]
  383.            jmp @b
  384. .found:
  385.            cmp [esi+block_flags], USED_BLOCK
  386.            jne .fail
  387.  
  388.            mov eax, [esi+block_size]
  389.            add [heap_free], eax
  390.  
  391.            mov edi, [esi+block_next]
  392.            test edi, edi
  393.            jz .prev
  394.  
  395.            cmp [edi+block_flags], FREE_BLOCK
  396.            jne .prev
  397.  
  398.            remove_from_free edi
  399.  
  400.            mov edx, [edi+block_next]
  401.            mov [esi+block_next], edx
  402.            test edx, edx
  403.            jz @f
  404.  
  405.            mov [edx+block_prev], esi
  406. @@:
  407.            mov ecx, [edi+block_size]
  408.            add [esi+block_size], ecx
  409.  
  410.            mov eax, edi
  411.            call free_mem_block
  412. .prev:
  413.            mov edi, [esi+block_prev]
  414.            test edi, edi
  415.            jz .insert
  416.  
  417.            cmp [edi+block_flags], FREE_BLOCK
  418.            jne .insert
  419.  
  420.            remove_from_used esi
  421.  
  422.            mov edx, [esi+block_next]
  423.            mov [edi+block_next], edx
  424.            test edx, edx
  425.            jz @f
  426.            mov [edx+block_prev], edi
  427. @@:
  428.            mov eax, esi
  429.            call free_mem_block
  430.  
  431.            mov ecx, [edi+block_size]
  432.            mov eax, [esi+block_size]
  433.            add eax, ecx
  434.            mov [edi+block_size], eax
  435.  
  436.            calc_index eax
  437.            calc_index ecx
  438.            cmp eax, ecx
  439.            je .m_eq
  440.  
  441.            push ecx
  442.            remove_from_list edi
  443.            pop ecx
  444.  
  445.            cmp [mem_block_list+ecx*4], edi
  446.            jne @f
  447.            mov [mem_block_list+ecx*4], edx
  448. @@:
  449.            cmp [mem_block_list+ecx*4], 0
  450.            jne @f
  451.            btr [mem_block_mask], ecx
  452. @@:
  453.            mov esi, [mem_block_list+eax*4]
  454.            mov [mem_block_list+eax*4], edi
  455.            mov [edi+list_next], esi
  456.            test esi, esi
  457.            jz @f
  458.            mov [esi+list_prev], edi
  459. @@:
  460.            bts [mem_block_mask], eax
  461. .m_eq:
  462.            xor eax, eax
  463.            mov [heap_mutex], eax
  464.            dec eax
  465.            ret
  466. .insert:
  467.            remove_from_used esi
  468.  
  469.            mov eax, [esi+block_size]
  470.            calc_index eax
  471.  
  472.            mov edi, [mem_block_list+eax*4]
  473.            mov [mem_block_list+eax*4], esi
  474.            mov [esi+list_next], edi
  475.            test edi, edi
  476.            jz @f
  477.            mov [edi+list_prev], esi
  478. @@:
  479.            bts [mem_block_mask], eax
  480.            mov [esi+block_flags],FREE_BLOCK
  481.            xor eax, eax
  482.            mov [heap_mutex], eax
  483.            dec eax
  484.            ret
  485. .fail:
  486.            xor eax, eax
  487.            mov [heap_mutex], eax
  488.            ret
  489. endp
  490.  
  491. align 4
  492. proc kernel_alloc stdcall, size:dword
  493.            locals
  494.              lin_addr    dd ?
  495.              pages_count dd ?
  496.            endl
  497.  
  498.            mov eax, [size]
  499.            add eax, 4095
  500.            and eax, not 4095;
  501.            mov [size], eax
  502.            and eax, eax
  503.            jz .error
  504.            mov ebx, eax
  505.            shr ebx, 12
  506.            mov [pages_count], ebx
  507.  
  508.            stdcall alloc_kernel_space, eax
  509.            and eax, eax
  510.            jz .error
  511.            mov [lin_addr], eax
  512.  
  513.            mov ecx, [pages_count]
  514.            mov edx, eax
  515.            mov ebx, ecx
  516.  
  517.            shr ecx, 3
  518.            jz .next
  519.  
  520.            and ebx, not 7
  521.            push ebx
  522.            stdcall alloc_pages, ebx
  523.            pop ecx                   ; yes ecx!!!
  524.            and eax, eax
  525.            jz .error
  526.  
  527.            mov edi, eax
  528.            mov edx, [lin_addr]
  529. @@:
  530.            stdcall map_page,edx,edi,dword PG_SW
  531.            add edx, 0x1000
  532.            add edi, 0x1000
  533.            dec ecx
  534.            jnz @B
  535. .next:
  536.            mov ecx, [pages_count]
  537.            and ecx, 7
  538.            jz .end
  539.  
  540. @@:        push ecx
  541.            call alloc_page
  542.            pop ecx
  543.            test eax, eax
  544.            jz .error
  545.  
  546.            stdcall map_page,edx,eax,dword PG_SW
  547.            add edx, 0x1000
  548.            dec ecx
  549.            jnz @B
  550. .end:
  551.            mov eax, [lin_addr]
  552.            ret
  553. .error:
  554.            xor eax, eax
  555.            ret
  556. endp
  557.  
  558. align 4
  559. proc kernel_free stdcall, base:dword
  560.            push ebx esi
  561.  
  562.            mov ebx, heap_mutex
  563.            call wait_mutex    ;ebx
  564.  
  565.            mov eax, [base]
  566.            mov esi, [mem_used_list]
  567. @@:
  568.            test esi, esi
  569.            jz .fail
  570.  
  571.            cmp [esi+block_base], eax
  572.            je .found
  573.            mov esi, [esi+list_next]
  574.            jmp @b
  575. .found:
  576.            cmp [esi+block_flags], USED_BLOCK
  577.            jne .fail
  578.  
  579.            and [heap_mutex], 0
  580.  
  581.            push ecx
  582.            mov ecx, [esi+block_size];
  583.            shr ecx, 12
  584.            call release_pages   ;eax, ecx
  585.            pop ecx
  586.            stdcall free_kernel_space, [base]
  587.            pop esi ebx
  588.            ret
  589. .fail:
  590.            and [heap_mutex], 0
  591.            pop esi ebx
  592.            ret
  593. endp
  594.  
  595. restore block_next
  596. restore block_prev
  597. restore block_list
  598. restore block_base
  599. restore block_size
  600. restore block_flags
  601.  
  602. ;;;;;;;;;;;;;;      USER     ;;;;;;;;;;;;;;;;;
  603.  
  604. HEAP_TOP  equ 0x5FC00000
  605.  
  606. align 4
  607. proc init_heap
  608.  
  609.            mov ebx,[CURRENT_TASK]
  610.            shl ebx,8
  611.            mov eax, [PROC_BASE+APPDATA.heap_top+ebx]
  612.            test eax, eax
  613.            jz @F
  614.            sub eax,[PROC_BASE+APPDATA.heap_base+ebx]
  615.            sub eax, 4096
  616.            ret
  617. @@:
  618.            mov esi, [PROC_BASE+APPDATA.mem_size+ebx]
  619.            add esi, 4095
  620.            and esi, not 4095
  621.            mov [PROC_BASE+APPDATA.mem_size+ebx], esi
  622.            mov eax, HEAP_TOP
  623.            mov [PROC_BASE+APPDATA.heap_base+ebx], esi
  624.            mov [PROC_BASE+APPDATA.heap_top+ebx], eax
  625.  
  626.            sub eax, esi
  627.            add esi, new_app_base
  628.            shr esi, 10
  629.            mov ecx, eax
  630.            sub eax, 4096
  631.            or ecx, FREE_BLOCK
  632.            mov [pages_tab+esi], ecx
  633.            ret
  634. .exit:
  635.            xor eax, eax
  636.            ret
  637. endp
  638.  
  639. align 4
  640. proc user_alloc stdcall, alloc_size:dword
  641.  
  642.            mov ecx, [alloc_size]
  643.            add ecx, (4095+4096)
  644.            and ecx, not 4095
  645.  
  646.            mov ebx, [CURRENT_TASK]
  647.            shl ebx, 8
  648.            mov esi, dword [ebx+PROC_BASE+APPDATA.heap_base]; heap_base
  649.            mov edi, dword [ebx+PROC_BASE+APPDATA.heap_top]; heap_top
  650.            add esi, new_app_base
  651.            add edi, new_app_base
  652. l_0:
  653.            cmp esi, edi
  654.            jae m_exit
  655.  
  656.            mov ebx, esi
  657.            shr ebx, 12
  658.            mov eax, [pages_tab+ebx*4]
  659.            test eax, FREE_BLOCK
  660.            jz test_used
  661.            and eax, 0xFFFFF000
  662.            cmp eax, ecx    ;alloc_size
  663.            jb  m_next
  664.            jz  @f
  665.  
  666.            mov edx, esi
  667.            add edx, ecx
  668.            sub eax, ecx;
  669.            or eax, FREE_BLOCK
  670.            shr edx, 12
  671.            mov [pages_tab+edx*4], eax
  672.  
  673. @@:
  674.            or ecx, USED_BLOCK
  675.            mov [pages_tab+ebx*4], ecx
  676.            shr ecx, 12
  677.            dec ecx
  678.            inc ebx
  679. @@:
  680.            mov dword [pages_tab+ebx*4], 2
  681.            inc ebx
  682.            dec ecx
  683.            jnz @B
  684.  
  685.         mov     edx, [CURRENT_TASK]
  686.         shl     edx, 8
  687.         mov     ebx, [alloc_size]
  688.         add     ebx, 0xFFF
  689.         and     ebx, not 0xFFF
  690.         add     ebx, [PROC_BASE+APPDATA.mem_size+edx]
  691.         call    update_mem_size
  692.  
  693.            mov eax, esi
  694.            add eax, 4096
  695.            sub eax, new_app_base
  696.            ret
  697. m_next:
  698.            add esi, eax
  699.            jmp l_0
  700. test_used:
  701.            test eax, USED_BLOCK
  702.            jz m_exit
  703.  
  704.            and eax, 0xFFFFF000
  705.            add esi, eax
  706.            jmp l_0
  707. m_exit:
  708.            xor eax, eax
  709.            ret
  710. endp
  711.  
  712. align 4
  713. proc user_free stdcall, base:dword
  714.  
  715.            mov esi, [base]
  716.            test esi, esi
  717.            jz .exit
  718.  
  719.            xor ebx, ebx
  720.            sub esi, 4096
  721.            shr esi, 12
  722.            mov eax, [pages_tab+esi*4]
  723.            test eax, USED_BLOCK
  724.            jz .not_used
  725.  
  726.            and eax, not 4095
  727.            mov ecx, eax
  728.            or eax, FREE_BLOCK
  729.            mov [pages_tab+esi*4], eax
  730.            inc esi
  731.            sub ecx, 4096
  732.            shr ecx, 12
  733.            mov ebx, ecx
  734. .release:
  735.            xor eax, eax
  736.            xchg eax, [pages_tab+esi*4]
  737.            test eax, 1
  738.            jz @F
  739.            call free_page
  740. @@:
  741.            inc esi
  742.            dec ecx
  743.            jnz .release
  744. .not_used:
  745.            mov edx, [CURRENT_TASK]
  746.            shl edx, 8
  747.            mov esi, dword [edx+PROC_BASE+APPDATA.heap_base]; heap_base
  748.            mov edi, dword [edx+PROC_BASE+APPDATA.heap_top]; heap_top
  749.            sub ebx, [edx+PROC_BASE+APPDATA.mem_size]
  750.            neg ebx
  751.            call update_mem_size
  752.            add esi, new_app_base
  753.            add edi, new_app_base
  754.            shr esi, 12
  755.            shr edi, 12
  756. @@:
  757.            mov eax, [pages_tab+esi*4]
  758.            test eax, USED_BLOCK
  759.            jz .test_free
  760.            shr eax, 12
  761.            add esi, eax
  762.            jmp @B
  763. .test_free:
  764.            test eax, FREE_BLOCK
  765.            jz .err
  766.            mov edx, eax
  767.            shr edx, 12
  768.            add edx, esi
  769.            cmp edx, edi
  770.            jae .exit
  771.  
  772.            mov ebx, [pages_tab+edx*4]
  773.            test ebx, USED_BLOCK
  774.            jz .next_free
  775.  
  776.            shr ebx, 12
  777.            add edx, ebx
  778.            mov esi, edx
  779.            jmp @B
  780. .next_free:
  781.            test ebx, FREE_BLOCK
  782.            jz .err
  783.            and dword [pages_tab+edx*4], 0
  784.            add eax, ebx
  785.            and eax, not 4095
  786.            or eax, FREE_BLOCK
  787.            mov [pages_tab+esi*4], eax
  788.            jmp @B
  789. .exit:
  790.            xor eax, eax
  791.            inc eax
  792.            ret
  793. .err:
  794.            xor eax, eax
  795.            ret
  796. endp
  797.  
  798. if 0
  799. align 4
  800. proc alloc_dll
  801.            pushf
  802.            cli
  803.            bsf eax, [dll_map]
  804.            jnz .find
  805.            popf
  806.            xor eax, eax
  807.            ret
  808. .find:
  809.            btr [dll_map], eax
  810.            popf
  811.            shl eax, 5
  812.            add eax, dll_tab
  813.            ret
  814. endp
  815.  
  816. align 4
  817. proc alloc_service
  818.            pushf
  819.            cli
  820.            bsf eax, [srv_map]
  821.            jnz .find
  822.            popf
  823.            xor eax, eax
  824.            ret
  825. .find:
  826.            btr [srv_map], eax
  827.            popf
  828.            shl eax,0x02
  829.            lea eax,[srv_tab+eax+eax*8]   ;srv_tab+eax*36
  830.            ret
  831. endp
  832.  
  833. end if
  834.