⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fastinterlck_asm.s

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 S
📖 第 1 页 / 共 2 页
字号:
.global @InterlockedPushEntrySList@8
@InterlockedPushEntrySList@8:

    /* Save registers */
    push ebx
    push ebp

    /* Pointer to list */
    mov ebp, ecx
    mov ebx, edx

    /* Get sequence number and link pointer */
    mov edx, [ebp+4]
    mov eax, [ebp]

1:
    /* Set link pointer */
    mov [ebx], eax

    /* Copy sequence number and adjust it */
    lea ecx, [edx+0x10001]

    /* Do the exchange */
    LOCK cmpxchg8b [ebp]
    jnz 1b

    /* Restore registers and return */
2:
    pop ebp
    pop ebx
    ret

/*PSINGLE_LIST_ENTRY
 *FASTCALL
 *ExInterlockedFlushSList(IN PSINGLE_LIST_ENTRY ListHead)
 */
.global @ExInterlockedFlushSList@4
@ExInterlockedFlushSList@4:

    /* Save registers */
    push ebx
    push ebp

    /* Clear ebx */
    xor ebx, ebx

    /* Pointer to list */
    mov ebp, ecx

    /* Get sequence number and link pointer */
    mov edx, [ebp+4]
    mov eax, [ebp]

1:
    /* Check if the list is empty */
    or eax, eax
    jz 2f

    /* Clear sequence and pointer */
    mov ecx, edx
    mov cx, bx

    /* Do the exchange */
    LOCK cmpxchg8b [ebp]
    jnz 1b

    /* Restore registers and return */
2:
    pop ebp
    pop ebx
    ret

/*INTERLOCKED_RESULT
 *FASTCALL
 *Exfi386InterlockedIncrementLong(IN PLONG Addend)
 */
.global @Exfi386InterlockedIncrementLong@4
@Exfi386InterlockedIncrementLong@4:

    /* Do the op */
    LOCK add dword ptr [ecx], 1

    /* Return */
    lahf
    and eax, EFLAG_SELECT
    ret

/*INTERLOCKED_RESULT
 *FASTCALL
 *Exfi386InterlockedDecrementLong(IN PLONG Addend)
 */
.global @Exfi386InterlockedDecrementLong@4
@Exfi386InterlockedDecrementLong@4:

    /* Do the op */
    LOCK sub dword ptr [ecx], 1

    /* Return */
    lahf
    and eax, EFLAG_SELECT
    ret

/*ULONG
 *FASTCALL
 *Exfi386InterlockedExchangeUlong(IN PULONG Taget,
 *                                IN ULONG Value)
 */
.global @Exfi386InterlockedExchangeUlong@8
.global @InterlockedExchange@8
@InterlockedExchange@8:
@Exfi386InterlockedExchangeUlong@8:

#ifdef CONFIG_SMP
    /* On MP, do the exchange */
    xchg [ecx], edx
    mov eax, edx
#else
    /* On UP, use cmpxchg */
    mov eax, [ecx]
1:
    cmpxchg [ecx], edx
    jnz 1b
#endif

    /* Return */
    ret

/*ULONG
 *FASTCALL
 *InterlockedIncrement(IN PLONG Addend)
 */
.global @InterlockedIncrement@4
@InterlockedIncrement@4:

    /* Do the op */
    mov eax, 1
    LOCK xadd dword ptr [ecx], eax

    /* Return */
    inc eax
    ret

/*ULONG
 *FASTCALL
 *InterlockedDecrement(IN PLONG Addend)
 */
.global @InterlockedDecrement@4
@InterlockedDecrement@4:

    /* Do the op */
    mov eax, -1
    LOCK xadd dword ptr [ecx], eax

    /* Return */
    dec eax
    ret

/*PVOID
 *FASTCALL
 *InterlockedCompareExchange(IN OUT PVOID *Destination,
 *                           IN PVOID Exchange,
 *                           IN PVOID Comperand)
 */
.global @InterlockedCompareExchange@12
@InterlockedCompareExchange@12:

    /* Get comperand */
    mov eax, [esp+4]

    /* Do the op */
    LOCK cmpxchg dword ptr [ecx], edx

    /* Return */
    ret 4

/*PVOID
 *FASTCALL
 *ExfInterlockedCompareExchange64(IN PLONGLONG Destination,
 *                                IN PLONGLONG Exchange,
 *                                IN PLONGLONG Comperand)
 */
.global @ExfInterlockedCompareExchange64@12
@ExfInterlockedCompareExchange64@12:

    /* Save registers */
    push ebx
    push ebp

    /* Get desination pointer, exchange value and comperand value/address */
    mov ebp, ecx
    mov ebx, [edx]
    mov ecx, [edx+4]
    mov edx, [esp+12]
    mov eax, [edx]
    mov edx, [edx+4]

    /* Do the op */
    LOCK cmpxchg8b [ebp]

    /* Restore volatiles */
    pop ebp
    pop ebx

    /* Return */
    ret 4

/*PVOID
 *FASTCALL
 *ExfInterlockedCompareExchange64(IN PLONGLONG Destination,
 *                                IN PLONGLONG Exchange,
 *                                IN PLONGLONG Comperand,
 *                                IN PKSPIN_LOCK Lock)
 */
.global @ExInterlockedCompareExchange64@16
@ExInterlockedCompareExchange64@16:

    /* Save registers */
    push ebp
    push ebp

    /* Get desination pointer, exchange value and comperand value/address */
    mov ebp, ecx
    mov ebx, [edx]
    mov ecx, [edx+4]
    mov edx, [esp+12]
    mov eax, [edx]
    mov edx, [edx+4]

    /* Do the op */
    LOCK cmpxchg8b [ebp]

    /* Restore volatiles */
    pop ebp
    pop ebx

    /* Return */
    ret 8

/*PVOID
 *FASTCALL
 *InterlockedExchangeAdd(IN OUT PLONG Addend,
 *                       IN LONG Increment)
 */
.global @InterlockedExchangeAdd@8
@InterlockedExchangeAdd@8:

    /* Do the op */
    LOCK xadd dword ptr [ecx], edx

    /* Return */
    mov eax, edx
    ret

/*** Non-586 functions ***/

/*PSINGLE_LIST_ENTRY
 *FASTCALL
 *ExfInterlockedPopEntrySList(IN PSINGLE_LIST_ENTRY ListHead,
 *                            IN PKSPIN_LOCK Lock)
 */
.global @ExfInterlockedPopEntrySList@8
@ExfInterlockedPopEntrySList@8:

    /* Save flags */
.starta:
    pushfd

    /* Disable interrupts */
    cli

    /* Acquire lock */
    ACQUIRE_SPINLOCK(edx, .spina)

    /* Get the next link and check if it's empty */
    mov eax, [ecx]
    or eax, eax
    jz 1f

    /* Get address of the next link and store it */
    push [eax]
    pop [ecx]

    /* Decrement list depth */
    dec dword ptr [ecx+4]

1:
#ifdef CONFIG_SMP
    /* Release spinlock */
    RELEASE_SPINLOCK(edx)
#endif

    /* Restore flags and return */
    popfd
    ret 0

#ifdef CONFIG_SMP
.spina:
    /* Restore flags and spin */
    popfd
    SPIN_ON_LOCK(edx, .starta)
#endif

/*PSINGLE_LIST_ENTRY
 *FASTCALL
 *ExfInterlockedPushEntrySList(IN PSINGLE_LIST_ENTRY ListHead,
 *                             IN PSINGLE_LIST_ENTRY ListEntry,
 *                             IN PKSPIN_LOCK Lock)
 */
.global @ExfInterlockedPushEntrySList@12
@ExfInterlockedPushEntrySList@12:

    /* Save flags */
.startb:
    pushfd

    /* Disable interrupts */
    cli

    /* Acquire lock */
#ifndef CONFIG_SMP
    mov eax, [esp+8]
    ACQUIRE_SPINLOCK(eax, .spinb)
#endif

    /* Get the next link and check if it's empty */
    push [ecx]

    /* Get address of the next link and store it */
    pop [edx]
    mov [ecx], edx

    /* Increment list depth */
    inc dword ptr [ecx+4]

#ifdef CONFIG_SMP
    /* Release spinlock */
    RELEASE_SPINLOCK(eax)
#endif

    /* Restore flags and return */
    popfd
    ret 4

#ifdef CONFIG_SMP
.spinb:
    /* Restore flags and spin */
    popfd
    SPIN_ON_LOCK(eax, .startb)
#endif

/*PVOID
 *FASTCALL
 *ExpInterlockedCompareExchange64(IN PLONGLONG Destination,
 *                                IN PLONGLONG Exchange,
 *                                IN PLONGLONG Comperand,
 *                                IN PKSPIN_LOCK Lock)
 */
.global @ExpInterlockedCompareExchange64@16
@ExpInterlockedCompareExchange64@16:

    /* Save registers */
    push ebp
    push ebp

    /* Get desination pointer, exchange value and comperand value/address */
    mov ebp, ecx
    mov ebx, [edx]
    mov ecx, [edx+4]
    mov edx, [esp+12]
    mov eax, [edx]
    mov edx, [edx+4]

#ifdef CONFIG_SMP
    /* Save ESI so we can store KSPINLOCK in it */
    push esi

    /* Save flags and lock, and disable interrupts */
    pushfd
    mov esi, [esp+24]
    cli

    /* Acquire the spinlock */
    ACQUIRE_SPINLOCK(esi, .spinc)
#else
    /* Save flags and disable interrupts */
    pushfd
    cli
#endif

    /* Compare bottom */
    cmp eax, [ebp]
    jne NoMatch

    /* Compare top */
    cmp edx, [ebp+4]
    jne NoMatch

    /* Save new value */
    mov [ebp], ebx
    mov [ebp+4], ecx

AfterSave:
#ifdef CONFIG_SMP
    /* Release lock, restore volatiles and flags */
    RELEASE_SPINLOCK(esi)
    popfd
    pop esi
#else
    popfd
#endif

    /* Restore the other volatiles and return */
    pop ebp
    pop ebx

    /* Return */
    ret 8

NoMatch:
    /* Return the current value */
    mov eax, [ebp]
    mov edx, [ebp+4]
    jmp AfterSave

#ifdef CONFIG_SMP
.spinc:
    /* Restore flags and spin */
    popfd
    pushfd
    SPIN_ON_LOCK(esi, .startc)
#endif
/* EOF */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -