Subversion Repositories Kolibri OS

Rev

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

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