Advertisement
Guest User

Untitled

a guest
Apr 9th, 2020
190
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.23 KB | None | 0 0
  1. #define ASM     1
  2. #include "sys_calls_asm.h"
  3. #include "x86_desc.h"
  4.  
  5. .text
  6.  
  7. .globl sys_call_asm
  8. .globl execute_asm
  9. .globl halt_asm
  10. .globl sys_call_test
  11.  
  12. .align 4
  13.  
  14. sys_call_asm:
  15.     # Create the stackframe
  16.     pushl   %ebp                      # Push the base pointer contents onto the stack
  17.     movl    %esp,%ebp                 # Change the base pointer to have it contain the old base pointer
  18.     pushl   %ebx                      # Push remaining callee-saved registers onto stack
  19.     pushl   %esi
  20.     pushl   %edi
  21.  
  22.     cmpl    $1,%eax                   # Set flags to see if call number < 1
  23.     je      halt_checker              # System call is 1 (halt), verify if we are allowed to halt
  24.     jb      sys_error                 # Jump to handle the case where call number < 1
  25.     cmpl    $6,%eax                   # Set flags to see if call number > 6
  26.     ja      sys_error                 # Jump to handle the case where call number > 6
  27.  
  28. sys_call_run:
  29.     # Push registers onto stack to prepare for C function call
  30.     pushl   %ebp
  31.     pushl   %edi
  32.     pushl   %esi
  33.     pushl   %edx
  34.     pushl   %ecx
  35.     pushl   %ebx
  36.  
  37.     # Call appropriate C function
  38.     call    *sys_jump_table(,%eax,4)  # Consult jump table
  39.  
  40.     # Error Check
  41.     cmpl    $-1,%eax                  # Check if system call worked
  42.     je      sys_error                 # Jump to handle the case system called failed
  43.  
  44.     # Restore registers
  45.     popl    %ebx
  46.     popl    %ecx
  47.     popl    %edx
  48.     popl    %esi
  49.     popl    %edi
  50.     popl    %ebp
  51.  
  52.     # Clear off the stackframe we did with the callee-save at the beginning
  53.     popl    %edi
  54.     popl    %esi
  55.     popl    %ebx
  56.     leave
  57.     iret
  58.  
  59. sys_error:
  60.     movl    $-1,%eax        # Return -1 if call number < 1 or call number > 6
  61.  
  62.     # Clear off the stackframe we did with the callee-save at the beginning
  63.     popl    %edi
  64.     popl    %esi
  65.     popl    %ebx
  66.     leave
  67.     iret
  68.  
  69. halt_checker:
  70.     pushl   %eax
  71.     call    get_halt_blocker
  72.     cmpl    $0, %eax
  73.     popl    %eax
  74.     je      sys_call_run
  75.     jmp     sys_error
  76.  
  77. # TODO: Load EFLAGS
  78. # This function performs the context switch using IRET. IRET automatically does this for
  79. # us, we just have to do a few things.
  80. # 1) Load the CS register with USER_CS
  81. # 2) Load the SS register with USER_DS
  82. # 3) Load the DS register with USER_DS
  83. # 4) Load the EFLAGS with Interrupts on
  84. # 5) Load the EIP with the function argument (The starting instruction of the program)
  85. # 6) Set the ESP to the bottom of user stack in vmem.  
  86.  
  87. # The registers (from bottom to top): SS, ESP, EFLAGS, CS, EIP
  88. execute_asm:
  89.     cli
  90.     # We used call, so setup the stack frame
  91.     pushl   %ebp
  92.     movl    %esp, %ebp
  93.  
  94.     # Set the DS register
  95.     movw $USER_DS, %ax  
  96.     movw %ax, %ds
  97.    
  98.  
  99.     # First set SS to USER_DS and push
  100.     xorl %esi, %esi
  101.     movl $USER_DS, %esi
  102.     pushl %esi
  103.  
  104.     # Next, push the ESP. This is the ESP of the user stack
  105.     movl 12(%ebp), %esi
  106.     pushl %esi
  107.  
  108.     # Next, we need to grab the EFLAGS and turn interrupts on.
  109.     pushfl
  110.     popl %esi
  111.    
  112.     # We need to set the 9th bit high
  113.     orl $0x200, %esi
  114.     pushl %esi
  115.  
  116.     # Push the CS register
  117.     xorl %esi, %esi
  118.     movl $USER_CS, %esi
  119.     pushl %esi
  120.  
  121.     # Push EIP
  122.     pushl 8(%ebp)
  123.  
  124.     # Update the PCB's pointers here
  125.     pushl %esp
  126.     pushl %ebp
  127.  
  128.     call set_pcb
  129.  
  130.     # Remove set_pcb arguments from stack
  131.     addl $8, %esp
  132.  
  133.     iret   # \(°o°)/
  134.  
  135. continue_execute:
  136.     # Handle finishing execute here
  137.     popl %ebx
  138.     movl %ebx, %eax
  139.    
  140.     leave
  141.     ret
  142.  
  143.     # Call sys_handler_finisher
  144.  
  145. sys_jump_table:
  146. .long 0x0, halt, execute, read, write, open, close
  147.  
  148. # TODO: Implement this program
  149. # This function performs the context switch using IRET. We just have to do a few things:
  150. # 1) Load the CS register with KERNEL_CS
  151. # 2) Load the SS register with KERNEL_DS
  152. # 3) Load the DS register with KERNEL_DS
  153. # 4) Load the EFLAGS with something
  154. # 5) Load the EIP with the function argument (The starting instruction of the program)
  155. # 6) Set the ESP to the bottom of the kernel stack.  
  156. halt_asm:
  157.     # cli
  158.     # # We used call, so setup the stack frame
  159.     pushl   %ebp
  160.     movl    %esp, %ebp
  161.  
  162.     andl $0x0F, %ebx
  163.     pushl %ebx
  164.  
  165.     jmp continue_execute
  166.  
  167.     leave
  168.     ret
  169. #
  170.     # # Set the DS register
  171.     # movw $USER_DS, %ax  
  172.     # movw %ax, %ds
  173.     #
  174.     #
  175.     # # First set SS to USER_DS and push
  176.     # xorl %esi, %esi
  177.     # movl $USER_DS, %esi
  178.     # pushl %esi
  179. #
  180.     # # Next, push the ESP. This is the ESP of the user stack
  181.     # movl 12(%ebp), %esi
  182.     # pushl %esi
  183. #
  184.     # # Next, we need to grab the EFLAGS and turn interrupts on.
  185.     # pushfl
  186.     # popl %esi
  187.     #
  188.     # # We need to set the 9th bit high
  189.     # orl $0x200, %esi
  190.     # pushl %esi
  191. #
  192.     # # Push the CS register
  193.     # xorl %esi, %esi
  194.     # movl $USER_CS, %esi
  195.     # pushl %esi
  196. #
  197.     # # Push EIP
  198.     # pushl 8(%ebp)
  199. #
  200.     # iret   # \(°o°)/
  201.  
  202. sys_call_test:
  203.     # We used call, so setup the stack frame
  204.     pushl   %ebp
  205.     movl    %esp, %ebp
  206.  
  207.     movl $2, %eax
  208.     movl 8(%ebp), %ebx
  209.  
  210.     int $0x80
  211.  
  212.     leave
  213.     ret
  214.  
  215. /* Name more jump tables here */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement