📄 cocall32.asm
字号:
.386
option segment:use16
dseg segment para public 'data'
wp equ <word ptr>
; 32-bit PCB. Note we only keep the L.O. 16 bits of SP since we are
; operating in real mode.
pcb32 struc
regsp word ?
regss word ?
regip word ?
regcs word ?
regeax dword ?
regebx dword ?
regecx dword ?
regedx dword ?
regesi dword ?
regedi dword ?
regebp dword ?
regds word ?
reges word ?
regflags dword ?
pcb32 ends
DefaultPCB pcb32 <>
DefaultCortn pcb32 <>
CurCoroutine dd DefaultCortn ;Points at the currently executing
; coroutine.
dseg ends
cseg segment para public 'slcode'
;============================================================================
;
; Coroutine support.
;
; COINIT- ES:DI contains the address of the current (default) process.
CoInit32 proc far
assume ds:dseg
push ax
push ds
mov ax, dseg
mov ds, ax
mov wp dseg:CurCoroutine, di
mov wp dseg:CurCoroutine+2, es
pop ds
pop ax
ret
CoInit32 endp
; COCALL32- transfers control to a coroutine. ES:DI contains the address
; of the PCB. This routine transfers control to that coroutine and then
; returns a pointer to the caller's PCB in ES:DI.
cocall32 proc far
assume ds:dseg
pushfd
push ds
push es ;Save these for later
push edi
push eax
mov ax, dseg
mov ds, ax
cli ;Critical region ahead.
; Save the current process' state:
les di, dseg:CurCoroutine
pop es:[di].pcb32.regeax
mov es:[di].pcb32.regebx, ebx
mov es:[di].pcb32.regecx, ecx
mov es:[di].pcb32.regedx, edx
mov es:[di].pcb32.regesi, esi
pop es:[di].pcb32.regedi
mov es:[di].pcb32.regebp, ebp
pop es:[di].pcb32.reges
pop es:[di].pcb32.regds
pop es:[di].pcb32.regflags
pop es:[di].pcb32.regip
pop es:[di].pcb32.regcs
mov es:[di].pcb32.regsp, sp
mov es:[di].pcb32.regss, ss
mov bx, es ;Save so we can return in
mov ecx, edi ; ES:DI later.
mov edx, es:[di].pcb32.regedi
mov es, es:[di].pcb32.reges
mov di, dx ;Point es:di at new PCB
mov wp dseg:CurCoroutine, di
mov wp dseg:CurCoroutine+2, es
mov es:[di].pcb32.regedi, ecx ;The ES:DI return values.
mov es:[di].pcb32.reges, bx
; Okay, switch to the new process:
mov ss, es:[di].pcb32.regss
mov sp, es:[di].pcb32.regsp
mov eax, es:[di].pcb32.regeax
mov ebx, es:[di].pcb32.regebx
mov ecx, es:[di].pcb32.regecx
mov edx, es:[di].pcb32.regedx
mov esi, es:[di].pcb32.regesi
mov ebp, es:[di].pcb32.regebp
mov ds, es:[di].pcb32.regds
push es:[di].pcb32.regflags
push es:[di].pcb32.regcs
push es:[di].pcb32.regip
push es:[di].pcb32.regedi
mov es, es:[di].pcb32.reges
pop edi
iret
cocall32 endp
; CoCall32l works just like cocall above, except the address of the pcb
; follows the call in the code stream rather than being passed in ES:DI.
; Note: this code does *not* return the caller's PCB address in ES:DI.
;
cocall32l proc far
assume ds:dseg
push ebp
mov bp, sp
pushfd
push ds
push es
push edi
push eax
mov ax, dseg
mov ds, ax
cli ;Critical region ahead.
; Save the current process' state:
les di, dseg:CurCoroutine
pop es:[di].pcb32.regeax
mov es:[di].pcb32.regebx, ebx
mov es:[di].pcb32.regecx, ecx
mov es:[di].pcb32.regedx, edx
mov es:[di].pcb32.regesi, esi
pop es:[di].pcb32.regedi
pop es:[di].pcb32.reges
pop es:[di].pcb32.regds
pop es:[di].pcb32.regflags
pop es:[di].pcb32.regebp
pop es:[di].pcb32.regip
pop es:[di].pcb32.regcs
mov es:[di].pcb32.regsp, sp
mov es:[di].pcb32.regss, ss
mov dx, es:[di].pcb32.regip ;Get return address (ptr to
mov cx, es:[di].pcb32.regcs ; PCB address.
add es:[di].pcb32.regip, 4 ;Skip ptr on return.
mov es, cx ;Get the ptr to the new pcb
mov di, dx ; address, then fetch the
les di, es:[di] ; pcb val.
mov wp dseg:CurCoroutine, di
mov wp dseg:CurCoroutine+2, es
; Okay, switch to the new process:
mov ss, es:[di].pcb32.regss
mov sp, es:[di].pcb32.regsp
mov eax, es:[di].pcb32.regeax
mov ebx, es:[di].pcb32.regebx
mov ecx, es:[di].pcb32.regecx
mov edx, es:[di].pcb32.regedx
mov esi, es:[di].pcb32.regesi
mov ebp, es:[di].pcb32.regebp
mov ds, es:[di].pcb32.regds
push es:[di].pcb32.regflags
push es:[di].pcb32.regcs
push es:[di].pcb32.regip
push es:[di].pcb32.regedi
mov es, es:[di].pcb32.reges
pop edi
iret
cocall32l endp
cseg ends
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -