Introduction

In this section, we will delve into the concepts of interrupts and system calls, which are crucial for understanding how assembly language interacts with the hardware and the operating system. By the end of this module, you will have a solid understanding of how interrupts and system calls work, and how to use them in your assembly programs.

What are Interrupts?

Interrupts are signals sent to the CPU by external devices or software to indicate that an event needs immediate attention. They temporarily halt the current CPU operations, save the state, and execute a function called an interrupt handler or interrupt service routine (ISR).

Types of Interrupts

  1. Hardware Interrupts: Generated by hardware devices (e.g., keyboard, mouse) to signal the CPU.
  2. Software Interrupts: Generated by software instructions to request services from the operating system.

How Interrupts Work

  1. Interrupt Request (IRQ): An interrupt signal is sent to the CPU.
  2. Interrupt Acknowledgment: The CPU acknowledges the interrupt and saves the current state.
  3. Interrupt Handling: The CPU executes the ISR.
  4. Return from Interrupt: The CPU restores the saved state and resumes normal execution.

Example: Handling a Keyboard Interrupt

section .data
    msg db 'Key pressed!', 0

section .bss

section .text
    global _start

_start:
    ; Enable keyboard interrupts
    mov al, 0x01
    out 0x21, al

    ; Infinite loop to keep the program running
    jmp $

keyboard_interrupt:
    ; Print message
    mov edx, len msg
    mov ecx, msg
    mov ebx, 1
    mov eax, 4
    int 0x80

    ; Acknowledge the interrupt
    mov al, 0x20
    out 0x20, al

    ; Return from interrupt
    iret

Explanation

  • Enable keyboard interrupts: The out instruction is used to enable keyboard interrupts.
  • Infinite loop: Keeps the program running to wait for interrupts.
  • Interrupt handler: Prints a message when a key is pressed and acknowledges the interrupt.

What are System Calls?

System calls are mechanisms that allow user-space programs to request services from the kernel (operating system). They provide an interface for performing operations like file manipulation, process control, and communication.

Common System Calls

  1. read: Reads data from a file descriptor.
  2. write: Writes data to a file descriptor.
  3. open: Opens a file.
  4. close: Closes a file descriptor.
  5. exit: Terminates a process.

How System Calls Work

  1. System Call Invocation: The program invokes a system call using a software interrupt (e.g., int 0x80 in Linux).
  2. Kernel Mode: The CPU switches to kernel mode to execute the system call.
  3. System Call Handling: The kernel performs the requested operation.
  4. Return to User Mode: The CPU switches back to user mode and returns the result.

Example: Using the write System Call

section .data
    msg db 'Hello, World!', 0xA
    len equ $ - msg

section .text
    global _start

_start:
    ; Write message to stdout
    mov eax, 4          ; syscall number for sys_write
    mov ebx, 1          ; file descriptor 1 (stdout)
    mov ecx, msg        ; pointer to message
    mov edx, len        ; message length
    int 0x80            ; invoke system call

    ; Exit program
    mov eax, 1          ; syscall number for sys_exit
    xor ebx, ebx        ; exit code 0
    int 0x80            ; invoke system call

Explanation

  • Write message to stdout: The write system call is invoked to print the message to the standard output.
  • Exit program: The exit system call is invoked to terminate the program.

Practical Exercises

Exercise 1: Handling a Timer Interrupt

Task: Write an assembly program that handles a timer interrupt and prints a message every second.

Solution:

section .data
    msg db 'Timer interrupt!', 0xA
    len equ $ - msg

section .bss

section .text
    global _start

_start:
    ; Enable timer interrupts
    mov al, 0x01
    out 0x21, al

    ; Infinite loop to keep the program running
    jmp $

timer_interrupt:
    ; Print message
    mov edx, len
    mov ecx, msg
    mov ebx, 1
    mov eax, 4
    int 0x80

    ; Acknowledge the interrupt
    mov al, 0x20
    out 0x20, al

    ; Return from interrupt
    iret

Exercise 2: Using the read System Call

Task: Write an assembly program that reads input from the user and prints it back to the screen.

Solution:

section .bss
    buffer resb 128

section .text
    global _start

_start:
    ; Read input from stdin
    mov eax, 3          ; syscall number for sys_read
    mov ebx, 0          ; file descriptor 0 (stdin)
    mov ecx, buffer     ; pointer to buffer
    mov edx, 128        ; buffer size
    int 0x80            ; invoke system call

    ; Write input to stdout
    mov eax, 4          ; syscall number for sys_write
    mov ebx, 1          ; file descriptor 1 (stdout)
    mov ecx, buffer     ; pointer to buffer
    mov edx, 128        ; buffer size
    int 0x80            ; invoke system call

    ; Exit program
    mov eax, 1          ; syscall number for sys_exit
    xor ebx, ebx        ; exit code 0
    int 0x80            ; invoke system call

Common Mistakes and Tips

  • Forgetting to Acknowledge Interrupts: Always acknowledge hardware interrupts to avoid repeated handling of the same interrupt.
  • Incorrect System Call Numbers: Ensure you use the correct syscall numbers for the intended operations.
  • Buffer Overflows: Be cautious with buffer sizes to prevent overflows and potential security vulnerabilities.

Conclusion

In this section, we covered the fundamentals of interrupts and system calls in assembly language. We explored how interrupts work, how to handle them, and how to use system calls to interact with the operating system. By practicing the provided exercises, you should now have a solid understanding of these concepts and be prepared to apply them in more complex assembly programs.

© Copyright 2024. All rights reserved