📄 swap.s.386
字号:
/ .file "swap.s.386"/ ident "@(#)cls4:lib/task/task/swap.s.386 1.1"/ ##############################################################################/ / C++ source for the C++ Language System, Release 3.0. This product/ is a new release of the original cfront developed in the computer/ science research center of AT&T Bell Laboratories.// Copyright (c) 1991 AT&T and UNIX System Laboratories, Inc./ Copyright (c) 1984, 1989, 1990 AT&T. All Rights Reserved.// / THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE of AT&T and UNIX System/ / Laboratories, Inc. The copyright notice above does not evidence/ any actual or intended publication of such source code.// / ##############################################################################// swap of DEDICATED/ call swap(*running_task, *to_run_task, is_new_child, running_is_terminated)/ This routine saves the fp in running's t_framep./ If running is a SHARED task, we must save its stack size as well,/ although the stack does not need to be copied out here./ It then restores to_run's t_framep to be the current fp./ If to_run is a new child, it explicitly restores the registers from/ New_task_regs, and returns without restoring the regs saved in the stack./ If to_run is not a new child, it restores all the registers saved in/ the frame on returning./ If running_task is TERMINATED, then we don't need to do a save./ NOTE: assumes all functions return values in eax. .text .globl swapswap: pushl %ebp / save caller's fp movl %esp,%ebp / fp = sp pushl %edi / save all user regs: edi, esi, ebx pushl %esi pushl %ebx movl 12(%ebp),%edx / edx = to_run movl 20(%ebp),%eax / eax = running_is_terminated cmpl $1,%eax / if eax == 1 je .L_RESTORE / skip the save movl 8(%ebp),%eax / eax = running / save state of running task movl %ebp,20(%eax) / running->t_framep = fp (ebp) movl 52(%eax),%ecx / %ecx = running->t_mode cmpw $2,%ecx / if running-t_mode == SHARED jne .L_RESTORE / the code here to save the t_size is the same as for sswap movl 32(%eax),%ecx / ecx = running->t_basep subl %esp,%ecx / ecx = running->t_basep - sp addl $4,%ecx / (size in bytes) shrl $2,%ecx / ecx /= 4 (size in ints) movl %ecx,36(%eax) / running->t_size = ecx.L_RESTORE: movl 16(%ebp),%ecx / ecx = is_new_child / restore state of to_run task movl 20(%edx),%ebp / ebp (fp) = to_run->t_framep / if is_new_child, restore registers jcxz .L_RET / if ecx==0; go to .L_RET / new child task effectively returns from task::task, so we need / to set the return value to "this" movl 24(%edx),%eax / eax = to_run->th leal New_task_regs,%edx / edx = address of New_task_regs movl 0(%edx),%edi movl 4(%edx),%esi movl 8(%edx),%ebx / Note: leave resets sp relative to fp, so don't need to reset sp / for NEW_CHILD case. leave ret.L_RET: / The i386 restores registers relative to sp, so we need to reset / to-runs's sp. We add 3 words (n saved regs) to the fp to get the sp. movl %ebp,%edx sub $12,%edx movl %edx,%esp / restore all user regs: edi, esi, ebx popl %ebx popl %esi popl %edi leave ret/ swap of SHARED/ sswap(*running, *prevOnStack, *to_run, is_new_child, running_is_terminated)/ This routine saves the fp in running's t_framep and the stack size in t_size./ Then it copies out the target stack to prevOnStack's t_savearea./ If to_run is not a new child, it then copies the saved stack of to_run / (from t_savearea) to the target stack, and then restores to_run's t_framep / to be the current fp. We don't need to restore state of a child / to_run object, because it's already in place./ If running_task is TERMINATED, then we don't need to do a save,/ NOTE: assumes all functions return values in eax./ and if running_task is TERMINATED and equals prevOnStack, then we don't/ have to do the stack copy. .text .globl sswapsswap: pushl %ebp / save caller's fp movl %esp,%ebp / fp = sp pushl %edi / save all user regs: edi, esi, ebx pushl %esi pushl %ebx movl 8(%ebp),%eax / eax = running movl 12(%ebp),%edi / edi = prevOnStack movl 24(%ebp),%ecx / ecx = running_is_terminated cmpl $1,%ecx / if ecx == 1 je .L_SKIP / skip the save /save hw state of running movl %ebp,20(%eax) / running->t_framep = fp (ebp) movl 32(%eax),%ecx / ecx = running->t_basep subl %esp,%ecx / ecx = running->t_basep - sp addl $4,%ecx / (size in bytes) shrl $2,%ecx / ecx /= 4 (size in ints) movl %ecx,36(%eax) / running->t_size = ecx jmp .L_SAVE.L_SKIP: /if running is TERMINATED and running == prevOnStack, /then we can skip the stack copy too cmpl %eax,%edi / if running == prevOnStack je .L_REST / skip save.L_SAVE: /copy out target stack to prevOnStack->t_savearea movl 36(%edi),%ecx / ecx = prevOnStack->t_size (count) pushl %ecx / push count arg on stack call swap_call_new / get count bytes of storage popl %ecx / pop arg off stack sall $2,%ecx / scale ecx to bytes addl %ecx,%eax / eax = base of new stack, plus 1 long subl $4,%eax / eax = base of new stack (to) movl %eax,40(%edi) / prevOnStack->t_savearea = eax (to) movl 32(%edi),%esi / esi = prevOnStack->t_basep (from) movl %eax,%edi / edi = to shrl $2,%ecx / ecx /= 4 = size in ints (count) pushf / save old DF std / set DF for copy from hi to lo addr rep; smovl / copy words popf / retore DF.L_REST: movl 20(%ebp),%eax / eax = is_new_child testl %eax,%eax / if is_new_child != 0 jne .L6 / skip the copy-in loop /copy into target stack from to_run->t_savearea movl 16(%ebp),%ebx / ebx = to_run movl 32(%ebx),%eax / eax = to_run->t_basep (to) movl 36(%ebx),%ecx / ecx = to_run->t_size (count) / Kick up the sp if new stack will be taller than current. sall $2,%ecx / ecx = new stack height in bytes subl %ecx,%eax / eax = base - size = target sp (+ 1) subl %esp,%eax / eax = eax - sp testl %eax,%eax jge .L3 / if eax < 0 addl %eax,%esp / kick up sp.L3: movl 32(%ebx),%edi / edi = to_run->t_basep (to) movl 36(%ebx),%ecx / ecx = to_run->t_size (count) movl 40(%ebx),%esi / esi = to_run->t_savearea (from) pushf / save old DF std / set DF for copy from hi to lo addr rep; smovl / copy words popf / retore DF / restore state of to_run movl 20(%ebx),%ebp / fp (a6) = to_run->t_framep / to (edi) points to one word beyond new sp addl $4,%edi movl %edi,%esp / reset sp, so regs can be restored / finally, delete to_run's t_savearea movl 36(%ebx),%ecx / ecx = to_run->t_size sall $2,%ecx / scale size to bytes movl 40(%ebx),%eax / eax = to_run->t_savearea subl %ecx,%eax / get low address of savearea addl $4,%eax pushl %eax / push pointer to savearea on stack call swap_call_delete / delete to_run->t_savearea popl %eax / pop arg off stack movl $0,40(%ebx) / to_run->t_savearea = 0/ sp should be correct here, for both is and is not new child cases.L6: / restore all user regs: edi, esi, ebx popl %ebx popl %esi popl %edi leave ret
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -