Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
en:multiasm:papc:chapter_6_8 [2025/11/24 12:07] – [Calling the system functions] ktokarzen:multiasm:papc:chapter_6_8 [2025/11/25 12:46] (current) – [Calling the system functions] ktokarz
Line 75: Line 75:
  
 ===== Calling the system functions ===== ===== Calling the system functions =====
-The operating systems offer a set of functions which help write an application. These functions include reading characters and text from standard input, usually the keyboard, displaying characters or text on standard output, usually the monitor, handling files, data streams and many others. In previous generations of operating systems, the software interrupt mechanism was used. In Microsoft DOS, it was **int 21h** while in 32-bit versions of Linux it was **int 80h**. Calling the system function required preparing the arguments in scratch registers and signalling the software interrupt.+The operating systems offer a set of functions which help write an application. These functions include reading characters and text from standard input, usually the keyboard, displaying characters or text on standard output, usually the monitor, handling files, data streams and many others. In previous generations of operating systems, the software interrupt mechanism was used. In Microsoft DOS, it was **int 21h** while in 32-bit versions of Linux it was **int 80h** (or in the C-style hex notation int 0x80). Calling the system function required preparing the arguments in scratch registers and signalling the software interrupt.
 <note> <note>
 You can still find many examples using the software interrupt system call on the Internet. In Linux, they should work properly, although they are slower than the new method. In 64-bit Windows, the **int 21** method is no longer supported. You can still find many examples using the software interrupt system call on the Internet. In Linux, they should work properly, although they are slower than the new method. In 64-bit Windows, the **int 21** method is no longer supported.
Line 81: Line 81:
 Modern 64-bit operating systems use alternative methods for calling system functions. They significantly differ between Linux and Windows, so we'll briefly summarise both. Modern 64-bit operating systems use alternative methods for calling system functions. They significantly differ between Linux and Windows, so we'll briefly summarise both.
  
-===== Callig Windows system function =====+===== Callig Windows system functions =====
 The Microsoft Windows operating system implements functions visible to programmers in the API (Application Programming Interface). Functions are identifiable by names, and they can be called as any other function in the program. Windows API functions for 32 and 64-bit Windows are documented on the Microsoft website ((https://learn.microsoft.com/en-us/windows/win32/apiindex/api-index-portal)). The Microsoft Windows operating system implements functions visible to programmers in the API (Application Programming Interface). Functions are identifiable by names, and they can be called as any other function in the program. Windows API functions for 32 and 64-bit Windows are documented on the Microsoft website ((https://learn.microsoft.com/en-us/windows/win32/apiindex/api-index-portal)).
 +Let's see the Hello World example written in the Windows API.
 +<code asm>
 +; include the library with system functions
 +includelib kernel32.lib
  
 +; define function names as external symbols
 +EXTERN GetStdHandle: PROC
 +EXTERN WriteConsoleA: PROC
  
 +; data section with constants and variables definitions
 +.DATA
 +
 +STD_OUTPUT_HANDLE = -11
 +stdout_handle     dq 0
 +hello_msg         db "Hello World", 0
 +dummy             dq 0
 +
 +; code section
 +.CODE 
 +MyAssemblerFunction PROC
 +
 +; the stack must be aligned to an address divisible by 16 - mod(16)
 +; after the function call is aligned to mod(8)
 +; the Windows requires the shadow space on the stack
 +    push  rbp        ; push rpb to the stack
 +    mov   rbp, rsp   ; store rsp to rbp
 +    sub   rsp, 48    ; shadow space (32 bytes) and stack alignment (additional 8 bytes)
 +
 +; we need the handle of the console window
 +    mov   rcx, STD_OUTPUT_HANDLE
 +    call  GetStdHandle
 +    mov   stdout_handle, rax
 +
 +; display the text in the console window
 +    mov   rcx, stdout_handle
 +    mov   rdx, offset hello_msg
 +    mov   r8,  sizeof hello_msg
 +    mov   r9,  dummy
 +    call  WriteConsoleA
 +
 +; restore the stack pointer and rbp
 +    mov   rsp, rbp
 +    pop   rbp
 +
 +; return from the function
 +    ret
 +MyAssemblerFunction ENDP
 +END
 +</code>
 +
 +===== Callig Linux system functions =====
 +The Linux operating system still supports the traditional calling of system functions using software interrupts. It is based on the **int 0x80** interrupt, which recognises the number of the function in the EAX register and up to six arguments in EBX, ECX, EDX, ESI, EDI, and EBP. 
 +The example of the Hello World program in Linux interrupt-based system call is shown in the following code.
 +
 +<code asm>
 +section   .text
 +global    _start
 +_start:    
 +; write function
 +     mov   ebx, 1    ; first argument - stdio
 +     mov   ecx, msg  ; second argument - text buffer
 +     mov   edx, len  ; third argument - text length
 +     mov   eax, 4    ; function number - write
 +     int   0x80
 +
 +; exit from program
 +     mov   eax, 1    ; function number - exit
 +     int   0x80
 +
 +section    .data
 +msg  db    "Hello World!", 10
 +len  equ   $ - msg
 +</code>
 +
 +Modern processors have new instructions especially designed for calling system functions. They are supported in the Linux operating system. The **syscall** instruction doesn't use the interrupt mechanism. It uses registers only to provide the address of the function, store the return address and flags register, and load the instruction pointer. This makes the **syscall** instruction execution significantly faster than **int 80h**, and is the preferred mechanism for system calls in 64-bit Linux systems. The RIP is stored in RCX, and RFLAGS is stored in R11. The RIP is loaded with the content of the special register IA32_LSTAR MSR, which is an element of Architectural Model-Specific Registers, implemented starting from certain models of 32-bit processors. The Linux system sets this register, and the programmer selects the function using the RAX register, as in the previous model of system calls.
 +
 +<code asm>
 +global _start
 +section .text
 +
 +_start:
 +
 +; write function
 +     mov   rdi, 1    ; first argument of the function - stdout
 +     mov   rsi, msg  ; second argument - text buffer
 +     mov   rdx, len  ; third argument - number of characters
 +     mov   rax, 1    ; write function
 +     syscall
 +
 +; exit from program
 +     mov   rdi, 0    ; result code of the program
 +     mov   rax, 60   ; exit function
 +     syscall
 +
 +msg: db    "Hello World!", 10
 +len  equ   $ - msg
 +</code>
en/multiasm/papc/chapter_6_8.1763986077.txt.gz · Last modified: 2025/11/24 12:07 by ktokarz
CC Attribution-Share Alike 4.0 International
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0