//The heap cache technique I first saw at Ticketmaster. //I don't know who owns it. ALIGN 8,0x90 INIT_MEM:: MOV U4 [MEM_FREE_LIST],0 MOV EBX,U4 [SYS_HEAP_BASE] MOV EAX,U4 [SYS_MEMBLKS] DEC EAX MOV U4 [SYS_HEAP_LIMIT],EAX INC EAX SUB EAX,EBX SHR EAX,PAGE_BITS MOV EDI,U4 [MEM_FREE_LIST] MOV U4 MB_NEXT[EBX],EDI MOV U4 [MEM_FREE_LIST],EBX MOV U4 MB_SIZE[EBX],EAX RET ////**************************PROCEDURE************************* // IN: EAX=NUM PAGES // EDX=Tss // // OUT: ESI=BASE ADDRESS // EAX=Pages allocated // ALIGN 8,0x90 ALLOCATE_MEM_BLKS:: PUSH EBX PUSH ECX PUSH EDI PUSHFD CLI CMP EAX,FREE_PAGE_HASH_SIZE JGE @@10 MOV ESI,U4 FREE_PAGE_HASH[EAX*4] OR ESI,ESI JZ @@200 MOV ECX,U4 MB_NEXT[ESI] MOV U4 FREE_PAGE_HASH[EAX*4],ECX JMP @@205 @@10: BSR ECX,EAX CMP U4 ROUND_UP_TABLE-4[ECX*4],EAX JE @@15 MOV EAX,U4 ROUND_UP_TABLE[ECX*4] MOV ESI,U4 FREE_PAGE_HASH2[ECX*4] OR ESI,ESI JZ @@200 MOV EBX,U4 MB_NEXT[ESI] MOV U4 FREE_PAGE_HASH2[ECX*4],EBX JMP @@205 @@15: MOV ESI,U4 FREE_PAGE_HASH2-4[ECX*4] OR ESI,ESI JZ @@200 MOV EBX,U4 MB_NEXT[ESI] MOV U4 FREE_PAGE_HASH2-4[ECX*4],EBX JMP @@205 @@200: MOV ESI,MEM_FREE_LIST @@201: LEA EBX,U4 MB_NEXT[ESI] MOV ESI,U4 [EBX] OR ESI,ESI JZ @@300 //TODO: Out of mem CMP U4 MB_SIZE[ESI],EAX JB @@201 JNE @@203 MOV EDI,U4 MB_NEXT[ESI] MOV U4 MB_NEXT[EBX],EDI JMP @@205 @@203: SUB U4 MB_SIZE[ESI],EAX //UPDATE FREE ENTRY MOV EDI,U4 MB_SIZE[ESI] SHL EDI,PAGE_BITS ADD ESI,EDI //SET ESI TO @ALLOCATED PAGES @@210: MOV U4 MB_SIZE[ESI],EAX @@205: MOV EDI,U4 TSS_LAST_MEM_BLK[EDX] CALL INSQUE @@300: POPFD POP EDI POP ECX POP EBX RET ////**************************PROCEDURE************************* // IN: ESI=BASE ADDRESS ALIGN 8,0x90 FREE_MEM_BLKS:: OR ESI,ESI JZ @@100 PUSH EAX PUSH EBX PUSH ECX PUSHFD CLI CALL REMQUE MOV EAX,MB_SIZE[ESI] CMP EAX,FREE_PAGE_HASH_SIZE JGE @@5 MOV EBX,U4 FREE_PAGE_HASH[EAX*4] MOV U4 MB_NEXT[ESI],EBX MOV U4 FREE_PAGE_HASH[EAX*4],ESI JMP @@101 @@5: BSR ECX,EAX MOV EBX,U4 FREE_PAGE_HASH2-4[ECX*4] MOV U4 MB_NEXT[ESI],EBX MOV U4 FREE_PAGE_HASH2-4[ECX*4],ESI @@101: POPFD POP ECX POP EBX POP EAX @@100: RET ////**************************PROCEDURE************************* ALIGN 8,0x90 FREE_MEM_BLK_LIST:: PUSH EDX MOV EDX,FS:[TSS_ABSOLUTE_ADDRESS] PUSH ESI PUSH EDI PUSHFD CLI MOV EDI,EDX ADD EDI,TSS_NEXT_MEM_BLK @@1: MOV ESI,U4 MB_NEXT[EDI] CMP ESI,EDI JE @@100 CALL FREE_MEM_BLKS JMP @@1 @@100: POPFD POP EDI POP ESI POP EDX RET ////**************************PROCEDURE************************* // IN: EAX=NUM U1S // OUT: ESI=BASE ADDRESS // ALIGN 8,0x90 ROUND_UP_TABLE: DU4 2,4,8,16,32,64,128,256,512,1024,2048,4096,8192; DU4 0x4000,0x8000,0x10000,0x20000,0x40000,0x80000; DU4 0x100000,0x200000,0x400000,0x800000,0x1000000; DU4 0x2000000,0x4000000,0x8000000,0x10000000; DU4 0x20000000,0x40000000,0x80000000; ALIGN 8,0x90 CP_MALLOC:: PUSH EBP MOV EBP,ESP PUSH ESI PUSH EDI MOV EAX,SF_PARAM1[EBP] MOV EDX,SF_PARAM2[EBP] OR EDX,EDX JNZ @@30 MOV EDX,U4 FS:[TSS_ABSOLUTE_ADDRESS] @@30: PUSHFD CLI ADD EAX,7 AND EAX,0xFFFFFFFC CMP EAX,UUM_STRUCT_SIZE JGE @@4 MOV EAX,UUM_STRUCT_SIZE @@4: CMP EAX,HEAP_HASH_SIZE JGE @@10 MOV ESI,U4 TSS_HEAP_HASH[EAX+EDX] OR ESI,ESI JZ @@13 MOV ECX,U4 UUM_NEXT[ESI] MOV U4 TSS_HEAP_HASH[EAX+EDX],ECX JMP U4 @@5 @@10: ADD EAX,MB_STRUCT_SIZE+PAGE_SIZE-1 SHR EAX,PAGE_BITS CALL ALLOCATE_MEM_BLKS SHL EAX,PAGE_BITS SUB EAX,MB_STRUCT_SIZE ADD ESI,MB_STRUCT_SIZE JMP @@5 @@13: MOV ESI,EDX ADD ESI,TSS_MALLOC_FREE_LIST @@1: LEA EBX,U4 UUM_NEXT[ESI] MOV ESI,U4 [EBX] OR ESI,ESI JNZ @@2 PUSH EAX //-**** ADD EAX,64*PAGE_SIZE-1 SHR EAX,PAGE_BITS CALL ALLOCATE_MEM_BLKS LEA ESI,U4 MB_STRUCT_SIZE[ESI] SHL EAX,PAGE_BITS SUB EAX,MB_STRUCT_SIZE MOV EDI,U4 TSS_MALLOC_FREE_LIST[EDX] MOV U4 UUM_NEXT[ESI],EDI MOV U4 UUM_SIZE[ESI],EAX MOV U4 TSS_MALLOC_FREE_LIST[EDX],ESI MOV EBX,EDX ADD EBX,TSS_MALLOC_FREE_LIST POP EAX //+**** JMP @@3 @@2: CMP U4 UUM_SIZE[ESI],EAX JL @@1 JNE @@3 @@8: MOV EDI,U4 UUM_NEXT[ESI] MOV U4 UUM_NEXT[EBX],EDI JMP @@5 @@3: SUB U4 UUM_SIZE[ESI],EAX //UPDATE FREE ENTRY CMP U4 UUM_SIZE[ESI],UUM_STRUCT_SIZE JAE @@7 ADD U4 UUM_SIZE[ESI],EAX MOV EAX,U4 UUM_SIZE[ESI] JMP @@8 @@7: MOV EDI,U4 UUM_SIZE[ESI] ADD ESI,EDI //SET ESI TO @ALLOCATED PAGES @@5: MOV U4 [ESI],EAX ADD ESI,4 @@100: POPFD MOV EAX,ESI XOR EDX,EDX POP EDI POP ESI POP EBP RET ////**************************PROCEDURE************************* // IN: ESI=BASE ADDRESS ALIGN 8,0x90 CP_FREE:: PUSH EBP MOV EBP,ESP PUSH ESI PUSH EDI MOV ESI,SF_PARAM1[EBP] OR ESI,ESI JZ @@100 MOV EDX,SF_PARAM2[EBP] OR EDX,EDX JNZ @@30 MOV EDX,U4 FS:[TSS_ABSOLUTE_ADDRESS] @@30: PUSHFD CLI SUB ESI,4 MOV EAX,U4 [ESI] //USED_USER_MEM_SIZE CMP EAX,HEAP_HASH_SIZE JGE @@5 MOV UUM_SIZE[ESI],EAX MOV EBX,U4 TSS_HEAP_HASH[EAX+EDX] MOV U4 UUM_NEXT[ESI],EBX MOV U4 TSS_HEAP_HASH[EAX+EDX],ESI JMP @@101 @@5: SUB ESI,MB_STRUCT_SIZE CALL FREE_MEM_BLKS @@101: POPFD @@100: POP EDI POP ESI POP EBP RET ////**************************PROCEDURE************************* CP_MSIZE:: PUSH EBP MOV EBP,ESP MOV EAX,SF_PARAM1[EBP] OR EAX,EAX JZ @@100 MOV EAX,U4 -4[EAX] SUB EAX,4 @@100: XOR EDX,EDX POP EBP RET