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