Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define ASM 1
- #include "sys_calls_asm.h"
- #include "x86_desc.h"
- .text
- .globl sys_call_asm
- .globl execute_asm
- .globl halt_asm
- .globl sys_call_test
- .align 4
- sys_call_asm:
- # Create the stackframe
- pushl %ebp # Push the base pointer contents onto the stack
- movl %esp,%ebp # Change the base pointer to have it contain the old base pointer
- pushl %ebx # Push remaining callee-saved registers onto stack
- pushl %esi
- pushl %edi
- cmpl $1,%eax # Set flags to see if call number < 1
- je halt_checker # System call is 1 (halt), verify if we are allowed to halt
- jb sys_error # Jump to handle the case where call number < 1
- cmpl $6,%eax # Set flags to see if call number > 6
- ja sys_error # Jump to handle the case where call number > 6
- sys_call_run:
- # Push registers onto stack to prepare for C function call
- pushl %ebp
- pushl %edi
- pushl %esi
- pushl %edx
- pushl %ecx
- pushl %ebx
- # Call appropriate C function
- call *sys_jump_table(,%eax,4) # Consult jump table
- # Error Check
- cmpl $-1,%eax # Check if system call worked
- je sys_error # Jump to handle the case system called failed
- # Restore registers
- popl %ebx
- popl %ecx
- popl %edx
- popl %esi
- popl %edi
- popl %ebp
- # Clear off the stackframe we did with the callee-save at the beginning
- popl %edi
- popl %esi
- popl %ebx
- leave
- iret
- sys_error:
- movl $-1,%eax # Return -1 if call number < 1 or call number > 6
- # Clear off the stackframe we did with the callee-save at the beginning
- popl %edi
- popl %esi
- popl %ebx
- leave
- iret
- halt_checker:
- pushl %eax
- call get_halt_blocker
- cmpl $0, %eax
- popl %eax
- je sys_call_run
- jmp sys_error
- # TODO: Load EFLAGS
- # This function performs the context switch using IRET. IRET automatically does this for
- # us, we just have to do a few things.
- # 1) Load the CS register with USER_CS
- # 2) Load the SS register with USER_DS
- # 3) Load the DS register with USER_DS
- # 4) Load the EFLAGS with Interrupts on
- # 5) Load the EIP with the function argument (The starting instruction of the program)
- # 6) Set the ESP to the bottom of user stack in vmem.
- # The registers (from bottom to top): SS, ESP, EFLAGS, CS, EIP
- execute_asm:
- cli
- # We used call, so setup the stack frame
- pushl %ebp
- movl %esp, %ebp
- # Set the DS register
- movw $USER_DS, %ax
- movw %ax, %ds
- # First set SS to USER_DS and push
- xorl %esi, %esi
- movl $USER_DS, %esi
- pushl %esi
- # Next, push the ESP. This is the ESP of the user stack
- movl 12(%ebp), %esi
- pushl %esi
- # Next, we need to grab the EFLAGS and turn interrupts on.
- pushfl
- popl %esi
- # We need to set the 9th bit high
- orl $0x200, %esi
- pushl %esi
- # Push the CS register
- xorl %esi, %esi
- movl $USER_CS, %esi
- pushl %esi
- # Push EIP
- pushl 8(%ebp)
- # Update the PCB's pointers here
- pushl %esp
- pushl %ebp
- call set_pcb
- # Remove set_pcb arguments from stack
- addl $8, %esp
- iret # \(°o°)/
- continue_execute:
- # Handle finishing execute here
- popl %ebx
- movl %ebx, %eax
- leave
- ret
- # Call sys_handler_finisher
- sys_jump_table:
- .long 0x0, halt, execute, read, write, open, close
- # TODO: Implement this program
- # This function performs the context switch using IRET. We just have to do a few things:
- # 1) Load the CS register with KERNEL_CS
- # 2) Load the SS register with KERNEL_DS
- # 3) Load the DS register with KERNEL_DS
- # 4) Load the EFLAGS with something
- # 5) Load the EIP with the function argument (The starting instruction of the program)
- # 6) Set the ESP to the bottom of the kernel stack.
- halt_asm:
- # cli
- # # We used call, so setup the stack frame
- pushl %ebp
- movl %esp, %ebp
- andl $0x0F, %ebx
- pushl %ebx
- jmp continue_execute
- leave
- ret
- #
- # # Set the DS register
- # movw $USER_DS, %ax
- # movw %ax, %ds
- #
- #
- # # First set SS to USER_DS and push
- # xorl %esi, %esi
- # movl $USER_DS, %esi
- # pushl %esi
- #
- # # Next, push the ESP. This is the ESP of the user stack
- # movl 12(%ebp), %esi
- # pushl %esi
- #
- # # Next, we need to grab the EFLAGS and turn interrupts on.
- # pushfl
- # popl %esi
- #
- # # We need to set the 9th bit high
- # orl $0x200, %esi
- # pushl %esi
- #
- # # Push the CS register
- # xorl %esi, %esi
- # movl $USER_CS, %esi
- # pushl %esi
- #
- # # Push EIP
- # pushl 8(%ebp)
- #
- # iret # \(°o°)/
- sys_call_test:
- # We used call, so setup the stack frame
- pushl %ebp
- movl %esp, %ebp
- movl $2, %eax
- movl 8(%ebp), %ebx
- int $0x80
- leave
- ret
- /* Name more jump tables here */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement