Subversion Repositories Kolibri OS

Rev

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