📄 arch_i386.s
字号:
/*** Copyright 2001, Travis Geiselbrecht. All rights reserved.** Copyright 2002, Michael Noisternig. All rights reserved.** Distributed under the terms of the NewOS License.*/#define FUNCTION(x) .global x; .type x,@function; x.text/* int atomic_add(int *val, int incr) */FUNCTION(atomic_add): movl 4(%esp),%edx movl 8(%esp),%eax lock xaddl %eax,(%edx) ret/* int atomic_and(int *val, int incr) */FUNCTION(atomic_and): movl 4(%esp),%edx_atomic_and1: movl 8(%esp),%ecx movl (%edx),%eax andl %eax,%ecx lock cmpxchgl %ecx,(%edx) jnz _atomic_and1 ret/* int atomic_or(int *val, int incr) */FUNCTION(atomic_or): movl 4(%esp),%edx_atomic_or1: movl 8(%esp),%ecx movl (%edx),%eax orl %eax,%ecx lock cmpxchgl %ecx,(%edx) jnz _atomic_or1 ret/* int atomic_set(int *val, int set_to) */FUNCTION(atomic_set): movl 4(%esp),%edx movl 8(%esp),%eax xchg %eax,(%edx) ret/* int test_and_set(int *val, int set_to, int test_val) */FUNCTION(test_and_set): movl 4(%esp),%edx movl 8(%esp),%ecx movl 12(%esp),%eax lock cmpxchgl %ecx,(%edx) ret/* uint64 i386_rdtsc() */.global i386_rdtsci386_rdtsc: rdtsc ret/* saves the conversion factor needed for system_time */.global cv_factorcv_factor: .word 0FUNCTION(setup_system_time): movl 4(%esp),%eax movl %eax,cv_factor ret/* bigtime_t i386_cycles_to_time(uint64 cycles); */FUNCTION(i386_cycles_to_time): movl 4(%esp),%eax movl 8(%esp),%edx pushl %ebx pushl %ecx movl cv_factor, %ebx movl %edx, %ecx /* save high half */ mull %ebx /* truncate %eax, but keep %edx */ movl %ecx, %eax movl %edx, %ecx /* save high half of low */ mull %ebx /*, %eax*/ /* now compute [%edx, %eax] + [%ecx], propagating carry */ subl %ebx, %ebx /* need zero to propagate carry */ addl %ecx, %eax adc %ebx, %edx popl %ecx popl %ebx ret/* void i386_set_task_switched(void); */FUNCTION(i386_set_task_switched): movl %cr0,%eax or $0x4,%eax movl %eax,%cr0 ret/* void i386_clear_task_switched(void); */FUNCTION(i386_clear_task_switched): movl %cr0,%eax and $0xfffffffb,%eax movl %eax,%cr0 ret/* void arch_cpu_global_TLB_invalidate(); */FUNCTION(arch_cpu_global_TLB_invalidate): movl %cr3,%eax movl %eax,%cr3 ret/* void i386_fsave(void *fpu_state); */FUNCTION(i386_fsave): movl 4(%esp), %eax fsave (%eax) ret/* void i386_fxsave(void *fpu_state); */FUNCTION(i386_fxsave): movl 4(%esp), %eax fxsave (%eax) ret/* void i386_frstor(void *fpu_state); */FUNCTION(i386_frstor): movl 4(%esp), %eax frstor (%eax) ret/* void i386_fxrstor(void *fpu_state); */FUNCTION(i386_fxrstor): movl 4(%esp), %eax fxrstor (%eax) ret/* void i386_fsave_swap(void *old_fpu_state, void *new_fpu_state); */FUNCTION(i386_fsave_swap): movl 4(%esp),%eax fsave (%eax) movl 8(%esp),%eax frstor (%eax) ret/* void i386_fxsave_swap(void *old_fpu_state, void *new_fpu_state); */FUNCTION(i386_fxsave_swap): movl 4(%esp),%eax fxsave (%eax) movl 8(%esp),%eax fxrstor (%eax) ret/* void i386_cpuid(unsigned int selector, unsigned int *data); */FUNCTION(i386_cpuid): pushl %ebx pushl %edi movl 12(%esp),%eax movl 16(%esp),%edi cpuid movl %eax,0(%edi) movl %ebx,4(%edi) movl %ecx,8(%edi) movl %edx,12(%edi) popl %edi popl %ebx ret/* void i386_context_switch(struct arch_thread *old, struct arch_thread *new); */FUNCTION(i386_context_switch): pusha /* pushes 8 words onto the stack */ movl 36(%esp),%eax /* save current_stack */ movl %esp,(%eax) pushl %ss /* push the old ss */ popl %edx /* pop it back off the stack */ movl %edx,4(%eax) /* save it into the arch_thread structure */ movl 40(%esp),%eax /* get new current_stack */ lss (%eax),%esp popa ret/* void i386_swap_pgdir(addr_t new_pgdir); */FUNCTION(i386_swap_pgdir): movl 4(%esp),%eax movl %eax,%cr3 ret/* thread exit stub */ .align 4i386_uspace_exit_stub: pushl %eax movl $1, %ecx lea (%esp), %edx movl $25, %eax; int $99 .align 4i386_uspace_exit_stub_end:/* void i386_enter_uspace(addr_t entry, void *args, addr_t ustack_top); */FUNCTION(i386_enter_uspace): movl 4(%esp),%eax // get entry point movl 8(%esp),%edx // get arguments movl 12(%esp),%ebx // get user stack movw $0x23,%cx movw %cx,%ds movw %cx,%es movw %cx,%fs movw %cx,%gs // copy exit stub to stack movl $i386_uspace_exit_stub_end, %esi_copy_more: lea -4(%esi), %esi lea -4(%ebx), %ebx mov (%esi), %ecx mov %ecx, (%ebx) cmp $i386_uspace_exit_stub, %esi jg _copy_more // push the args onto the user stack movl %edx,-4(%ebx) // args movl %ebx,-8(%ebx) // fake return address to copied exit stub sub $8,%ebx pushl $0x23 // user data segment pushl %ebx // user stack pushl $(1 << 9) | 2 // user flags pushl $0x1b // user code segment pushl %eax // user IP iret/* void i386_switch_stack_and_call(addr_t stack, void (*func)(void *), void *arg); */FUNCTION(i386_switch_stack_and_call): movl 4(%esp),%eax // new stack movl 8(%esp),%ecx // func movl 12(%esp),%edx // args movl %eax,%esp // switch the stack pushl %edx // push the argument call *%ecx // call the target function_loop: jmp _loopnull_idt_descr: .word 0 .word 0,0FUNCTION(reboot): lidt null_idt_descr int $0done: jmp doneFUNCTION(dbg_save_registers): pushl %esi pushl %eax movl 12(%esp), %esi movl %eax, 0(%esi) movl %ebx, 4(%esi) movl %ecx, 8(%esi) movl %edx, 12(%esi) lea 16(%esp), %eax movl %eax, 16(%esi) // caller's %esp movl %ebp, 20(%esi) movl 4(%esp), %eax movl %eax, 24(%esi) // caller's %esi movl %edi, 28(%esi) movl 8(%esp), %eax movl %eax, 32(%esi) // caller's %ebp pushfl popl %eax mov %eax, 36(%esi) movl %cs, 40(%esi) movl %ss, 44(%esi) movl %ds, 48(%esi) movl %es, 52(%esi) popl %eax popl %esi ret
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -