<- previous index next ->
To understand Linux System Calls, learn from the UMBC Expert: Gary Burt.
Note, philosophy still good, all registers starting "e" change to "r".
CMSC 313 -- System Calls
For modern 64-bit computers:
The system call numbers are the same, %eax becomes %rax, %ebx becomes %rbx, etc.
"unsigned int" becomes "unsigned long int", size_t is 64-bit, etc.
System Call Table
Another web site http://asm.sourceforge.net/syscall.html
When making Linux kernel calls from a "C" program, you will need
#include <unistd.h>
A tiny sample, using only system calls, that prints a heading
syscall0_64.asm
; syscall0_64.asm demonstrate system, kernel, calls
; Compile: nasm -f elf64 syscall0_64.asm
; Link gcc -m64 -o syscall0_64 syscall0_64.o
; Run: ./syscall0_64
;
section .data
msg: db "syscall0_64.asm running",10 ; the string to print, 10=crlf
len: equ $-msg ; "$" means here, len is a value, not an address
global main
section .text
main:
; header msg ; these 5 lines are like printf
mov rdx,len ; arg3, length of string to print
mov rcx,msg ; arg2, pointer to string
mov rbx,1 ; arg1, where to write, screen
mov rax,4 ; write command to int 80 hex
int 0x80 ; interrupt 80 hex, call kernel
mov rbx,0 ; exit code, 0=normal
mov rax,1 ; exit command to kernel
int 0x80 ; interrupt 80 hex, call kernel
Another tiny sample, using only system calls, that prints a heading
using ld rather than gcc also _start rather than main
syscall0s_64.asm
; syscall0s_64.asm demonstrate system, kernel, calls
; Compile: nasm -f elf64 syscall0s_64.asm
; Link ld -m64 -o syscall0s_64 syscall0s_64.o
; Run: ./syscall0s_64
;
section .data
msg: db "syscall0s_64.asm running",10 ; the string to print, 10=crlf
len: equ $-msg ; "$" means here, len is a value, not an address
global _start
section .text
_start: ; using ld in place of gcc
; header msg ; these 5 lines are like printf
mov rdx,len ; arg3, length of string to print
mov rcx,msg ; arg2, pointer to string
mov rbx,1 ; arg1, where to write, screen
mov rax,4 ; write command to int 80 hex
int 0x80 ; interrupt 80 hex, call kernel
mov rbx,0 ; exit code, 0=normal
mov rax,1 ; exit command to kernel
int 0x80 ; interrupt 80 hex, call kernel
A sample syscall1_64.asm
demonstrates file open, file read (in hunks of 8192)
and file write (the whole file!)
This program reads and prints itself:
; syscall1_64.asm demonstrate system, kernel, calls
; Compile: nasm -f elf64 syscall1_64.asm
; Link gcc -m64 -o syscall1_64 syscall1_64.o
; Run: ./syscall1_64
;
section .data
msg: db "syscall1_64.asm running",10 ; the string to print, 10=crlf
len: equ $-msg ; "$" means here, len is a value, not an address
msg2: db "syscall1_64.asm finished",10
len2: equ $-msg2
msg3: db "syscall1_64.asm opened",10
len3: equ $-msg3
msg4: db "syscall1_64.asm read",10
len4: equ $-msg4
msg5: db "syscall1_64.asm open fail",10
len5: equ $-msg5
msg6: db "syscall1_64.asm another open fail",10
len6: equ $-msg6
msg7: db "syscall1_64.asm read fail",10
len7: equ $-msg7
name: db "syscall1_64.asm",0 ; "C" string also used by OS
fd: dq 0 ; file descriptor
flags: dq 0 ; hopefully read-only
section .bss
line: resb 8193 ; read/write buffer 16 sectors of 512
lenbuf: resq 1 ; number of bytes read
extern open
global main
section .text
main:
push rbp ; set up stack frame
; header msg
mov rdx,len ; arg3, length of string to print
mov rcx,msg ; arg2, pointer to string
mov rbx,1 ; arg1, where to write, screen
mov rax,4 ; write command to int 80 hex
int 0x80 ; interrupt 80 hex, call kernel
open1:
mov rdx,0 ; mode
mov rcx,0 ; flags, 'r' equivalent O_RDONLY
mov rbx,name ; file name to open
mov rax,5 ; open command to int 80 hex
int 0x80 ; interrupt 80 hex, call kernel
mov [fd],rax ; save fd
cmp rax,2 ; test for fail
jg read ; file open
; file open failed msg5
mov rdx,len5 ; arg3, length of string to print
mov rcx,msg5 ; arg2, pointer to string
mov rbx,1 ; arg1, where to write, screen
mov rax,4 ; write command to int 80 hex
int 0x80 ; interrupt 80 hex, call kernel
read:
; file opened msg3
mov rdx,len3 ; arg3, length of string to print
mov rcx,msg3 ; arg2, pointer to string
mov rbx,1 ; arg1, where to write, screen
mov rax,4 ; write command to int 80 hex
int 0x80 ; interrupt 80 hex, call kernel
doread:
mov rdx,8192 ; max to read
mov rcx,line ; buffer
mov rbx,[fd] ; fd
mov rax,3 ; read command to int 80 hex
int 0x80 ; interrupt 80 hex, call kernel
mov [lenbuf],rax ; number of characters read
cmp rax,0 ; test for fail
jg readok ; some read
; read failed msg7
mov rdx,len7 ; arg3, length of string to print
mov rcx,msg7 ; arg2, pointer to string
mov rbx,1 ; arg1, where to write, screen
mov rax,4 ; write command to int 80 hex
int 0x80 ; interrupt 80 hex, call kernel
jmp fail ; nothing read
; file read msg4
readok:
mov rdx,len4 ; arg3, length of string to print
mov rcx,msg4 ; arg2, pointer to string
mov rbx,1 ; arg1, where to write, screen
mov rax,4 ; write command to int 80 hex
int 0x80 ; interrupt 80 hex, call kernel
write:
mov rdx,[lenbuf] ; length of string to print
mov rcx,line ; pointer to string
mov rbx,1 ; where to write, screen
mov rax,4 ; write command to int 80 hex
int 0x80 ; interrupt 80 hex, call kernel
fail:
; finished msg2
mov rdx,len2 ; arg3, length of string to print
mov rcx,msg2 ; arg2, pointer to string
mov rbx,1 ; arg1, where to write, screen
mov rax,4 ; write command to int 80 hex
int 0x80 ; interrupt 80 hex, call kernel
mov rbx,0 ; exit code, 0=normal
mov rax,1 ; exit command to kernel
int 0x80 ; interrupt 80 hex, call kernel
Now, a little help with project 2
Arrays are pass by address and stored as address
mov rax, [x] ; put address of x into rax
mov rbx, [y] ; put address of y into rbx
mov rcx, [z] ; put address of z into rcx
Have "C" indices in registers, must be computed and stored
mov r8, [m]
mov r9, [j]
mov r10, [k]
Now in m loop ; z[m] = 0.0;
fld qword [zero]
fstp qword [rcx+8*r8]
in nested loops ; z[m] = z[m] + x[j]*y[k];
fld qword [rax+8*r9] x[j]
fmul qword [rbx+8*r10] y[k]
fadd qword [rcx+8*r8] z[m]
fstp qword [rcx+8*r8]
You are translating "C" code to assembly language
Proj2
<- previous index next ->