Subversion Repositories Kolibri OS

Rev

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

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