Subversion Repositories Kolibri OS

Rev

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