BetterOS.org : An attempt to make computer machines run better


HOME | BETTER LINUX | GAMES | SOFTWARE | TUTORIALS | ABOUT | REFERENCES | FORUM | WEB LOG |

Reference Material: INDEX | SYSCALLS | CALLING CONVENTIONS | AMD64 INSTRUCTIONS | X11 | REUSABLE CODE |

Reference Material

INTRODUCTION:
Here you should be able to find some code I have written that I find myself regularly reusing. Since I find it useful, maybe you will too.


DOWNLOAD:
Here you can download all the code.
gzipped tarball


AMD64 LINUX LIBC REPLACEMENT GLUE:
I am particularly fond of the glue code that I use to enable me to write C programs without the need to link with any standard C library. This allows me to write very small static applications in C, which run on all amd64 Linux platforms, regardless of what C library the user has installed. I mentioned this code before, but since I come here when I need to use it, expect this to be the most up to date version of it.

This is the startup code:
;crt.s v1
;
;This is the C runtime for programs that do not need the C library. It 
;makes arguments available and aligns the stack, then calls main directly
;
;This is the first version
;Todo: Make environment variables available

section .text
	global _start
	extern main

	_start:
		xor		rbp,rbp			;AMD64 ABI Requirement
		pop		rdi				;Get argument count
		mov		rsi,rsp			;Get argument array
		and		rsp,-16			;Align stack pointer
		call	main			;Execute C code

								;End Program
		mov 	rax,60			;SYS_exit
		syscall					;

		ret						;Never Reached


This are functions for making syscalls under Linux.
;amd64_syscalls v2
;
;This is assembly glue to allow C programs to call syscalls without 
;needing a C library to help
;
;v2 resolves the issue of needing to call 6 argument syscalls like mmap
;using an array of longs, instead, syscall6 can be called
;please note that __syscall can not be used with 6 argument syscalls

section .text
	global __syscall, syscall0, syscall1, syscall2, syscall3, syscall4, syscall5, syscall6

	syscall0:
		mov			rax,rdi			;syscall number
		syscall						;
		ret							;

	syscall1:
		mov			rax,rdi			;syscall number
		mov			rdi,rsi			;arg1
		mov			rsi,rdx			;arg2
		syscall						;
		ret							;

	syscall2:
		mov			rax,rdi			;syscall number
		mov			rdi,rsi			;arg1
		mov			rsi,rdx			;arg2
		syscall						;
		ret							;

	syscall3:
		mov			rax,rdi			;syscall number
		mov			rdi,rsi			;arg1
		mov			rsi,rdx			;arg2
		mov			rdx,rcx			;arg3
		syscall						;
		ret							;

	syscall4:
		mov			rax,rdi			;syscall number
		mov			rdi,rsi			;arg1
		mov			rsi,rdx			;arg2
		mov			rdx,rcx			;arg3
		mov			r10,r8			;arg4
		syscall						;
		ret							;

	syscall5:
	__syscall:
		mov			rax,rdi			;syscall number
		mov			rdi,rsi			;arg1
		mov			rsi,rdx			;arg2
		mov			rdx,rcx			;arg3
		mov			r10,r8			;arg4
		mov			r8,r9			;arg5
		syscall						;
		ret							;

	syscall6:
		mov			rax,rdi			;syscall number
		mov			rdi,rsi			;arg1
		mov			rsi,rdx			;arg2
		mov			rdx,rcx			;arg3
		mov			r10,r8			;arg4
		mov			r8,r9			;arg5
		mov			r9,[rsp+8]		;arg6
		syscall						;
		ret							;


AMD64 MATH ROUTINES:
These are some of the math routines I have written. Please note that these are significantly inferior to some of the other implementations available, either due to use of naive methods or coprocessor usage. However, I wrote them all and they work without needing to be linked to any other libraries. As an added bonus, these mainly do not make syscalls, so they might work on other systems besides Linux. Remember, use these only if you have to chose between these and calling an external library, if you are already linking with libm, it's not worth it.
;math.s v1
;
;Very simple math library. Only a few math functions are implemented
;and most use the inefficient FPU co-processor
;sin, cos, and atan2 are implemented because they were needed
;sincos is implemented because some GCC optimizations assume it exists
;sgn is implemented because its real simple
;
;This is the initial version
;Todo: implement more and better

section .text
	global sin, cos, sincos, atan2, sgn

	sin:
		sub	rsp,16					; Make room for the value
		movsd	QWORD [rsp],xmm0	;
		fld	QWORD [rsp]				; ST0
		fsin						;
		fstp	QWORD [rsp]			; ST0
		movsd	xmm0,QWORD [rsp]	;
		add	rsp,16					;
		ret							;

	cos:
		sub	rsp,16					;
		movsd	QWORD [rsp],xmm0	;
		fld	QWORD [rsp]				;
		fcos						;
		fstp	QWORD [rsp]			;
		movsd	xmm0,QWORD [rsp]	;
		add	rsp,16					;
		ret

	sincos:
		sub	rsp,16					;
		movsd	QWORD [rsp],xmm0	;
		fld	QWORD [rsp]				;
		fsincos						;
		fstp	QWORD [rsi]			;
		fstp	QWORD [rdi]			;
		add	rsp,16					;
		ret							;

	sgn:
		cmp	edi,0					;
		jg	.GT						;
		jl	.LT						;
		mov	rax,0					;
		ret							;
	.GT:	mov	rax,1				;
		ret							;
	.LT:	mov	rax,-1				;
		ret							;

	atan2:
		sub	rsp,16					;
		movsd	QWORD [rsp],xmm0	;
		fld	QWORD [rsp]				;
		movsd	QWORD [rsp],xmm1	;
		fld	QWORD [rsp]				;
		fpatan						;
		fstp	QWORD [rsp]			;
		movsd	xmm0,QWORD [rsp]	;
		add	rsp,16					;
		ret							;

This is some simple code I wrote to handle big number math. Currently, only addition is implemented. My plan is to only implement enough to get a working RSA implementation.
;bigmath.s v1
;
;This is some assembly for big number arithmetic
;
;This is the first version
;Todo: more functions

section .text
	global big_add


	big_add:
		xor		rax,rax					; zero return value

		mov		r10,[rdi]				; load first 8 bytes
		add		r10,[rdx]				; add first 8 bytes
		mov		[r8],r10				; save result

		big_add_loop:
		inc 	rax						; increment return value
		dec		rsi						; decrement counters
		dec		rcx						;
		jz		big_add_end				; end if at end of number

		lea		rdi,[rdi+8]				; move to next uint64
		lea		rdx,[rdx+8]				;
		lea		r8,[r8+8]				;

		mov		r10,[rdi]				; load next 8 bytes
		adc		r10,[rdx]				; add 8 bytes and carry bit
		mov		[r8],r10				;
		jmp		big_add_loop			;

		big_add_end:
		mov		[r9],rax				; save length of result
		ret								;