Subversion Repositories Kolibri OS

Rev

Rev 172 | Rev 192 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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