<- previous    index    next ->

Lecture 12 Linux kernel calls


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 ->

Other links

Go to top