I should really brush up on this stuff.. this is some old junk I found laying around. I wish I could write assembler as well as I could in 2016. Maybe a resolution for 2020?

Just seeing int 0x80 below, I’m not sure if this is x64 or x86/32-bit. (Shouldn’t that be syscall?) It is what it is.

hello-world.asm

section .text
global mystart
mystart:
	push	dword	mylen
	push	dword	mymsg
	push	dword	1

	mov	eax,	0x4
	sub	esp,	4
	int	0x80

	add	esp,	16

	push	dword	0

	mov	eax,	0x1
	sub	esp,	4
	int	0x80

section .data

	mymsg	db	"hello, world",	0xa
	mylen	equ	$-mymsg

x64.asm

; /usr/local/bin/nasm -f macho64 64.asm
; && ld -macosx_version_min 10.7.0 -lSystem -o 64 64.o
; && ./64

%include	"x64-lib.asm"

Sub	start

extern	_printf

	String	int_msg,	"%52lu (%16lxh)", 0Ah, 00h

	; __call	_printf, int_msg, 01FFFFFFFFh, 01FFFFFFFFh

	__call	_printf, int_msg, 0ffffffffffffffffh, 0ffffffffffffffffh
	__call	square32, 0ffffffffh
	__call	_printf, int_msg, rax, rax

	__call	_printf, int_msg, 46341, 46341
	__call	square32, 46341
	__call	_printf, int_msg, rax, rax

	__call	_printf, int_msg, -1, -1
	__call	square32, -1
	__call	_printf, int_msg, rax, rax

	__exit	0

EndSub

Sub	square32	;N

	mov	rax, rdi
	mul	rdi

EndSub

x64-lib.asm

section	.data

STDOUT	equ	1


; User-level applications use as integer registers for
; passing the sequence %rdi, %rsi, %rdx, %rcx, %r8 and %r9.
; The kernel interface uses %rdi, %rsi, %rdx, %r10, %r8 and %r9.
; A system-call is done via the syscall instruction. The kernel
; destroys registers %rcx and %r11.
; The number of the syscall has to be passed in register %rax.
; System-calls are limited to six arguments, no argument is passed
; directly on the stack.
; Returning from the syscall, register %rax contains the result of
; the system-call. A value in the range between -4095 and -1 indicates
; an error, it is -errno.
; Only values of class INTEGER or class MEMORY are passed to the kernel.


section .text

global	start


%macro	Sub	1
%1:
	push	rbp
	mov	rbp, rsp		;PROLOGUE
	and	rsp, 0xFFFFFFFFFFFFFFF0

%endmacro

%macro	EndSub	0
.Return:
	mov	rsp, rbp		;EPILOGUE
	pop	rbp
	ret
%endmacro


%macro	String	2+
	section	.data
	%1:
	.	db	%2
	.len	equ	$-.
	section .text
%endmacro

; BSD systems (MacOS X included) use similar system calls,
; but convention to execute them is different. While on Linux
; you pass system call arguments in different registers, on BSD
; systems they are pushed onto stack (except the system call
; number, which is put into eax, the same way as in Linux).
;
; https://en.wikibooks.org/wiki/X86_Assembly/NASM_Syntax

%macro	__syscall0	1
	mov	rax, %1
	syscall
%endmacro
%macro	__syscall1	2
	mov	rdi, %2
	__syscall0	%1
%endmacro
%macro	__syscall2	3
	mov	rsi, %3
	__syscall1	%1, %2
%endmacro
%macro	__syscall3	4
	mov	rdx, %4
	__syscall2	%1, %2, %3
%endmacro
%macro	__syscall4	5
	mov	r10, %3
	__syscall3	%1, %2, %3, %4
%endmacro
%macro	__syscall5	6
	mov	r8, %4
	__syscall4	%1, %2, %3, %4, %5
%endmacro
%macro	__syscall6	7
	mov	r9, %7
	__syscall5	%1, %2, %3, %4, %5, %6
%endmacro
%macro	__write	3
	__syscall3	0x2000004, %1, %2, %3
%endmacro
%macro	__exit	1
	__syscall1	0x2000001, %1
%endmacro

%macro	__call0	1
	and	rsp, 0xFFFFFFFFFFFFFFF0
	call	%1
%endmacro
%macro	__call1	2
	mov	rdi, %2
	__call0	%1
%endmacro
%macro	__call2	3
	mov	rsi, %3
	__call1	%1, %2
%endmacro
%macro	__call3	4
	mov	rdx, %4
	__call2	%1, %2, %3
%endmacro
%macro	__call4	5
	mov	rcx, %5
	__call3	%1, %2, %3, %4
%endmacro
%macro	__call5	6
	mov	r8, %6
	__call4	%1, %2, %3, %4, %5
%endmacro
%macro	__call6	7
	mov	r9, %7
	__call5	%1, %2, %3, %4, %5, %6
%endmacro
%macro	__call	1-7
	%if	%0 == 1
		__call0	%1
	%elif	%0 == 2
		__call1	%1, %2
	%elif	%0 == 3
		__call2	%1, %2, %3
	%elif	%0 == 4
		__call3	%1, %2, %3, %4
	%elif	%0 == 5
		__call4	%1, %2, %3, %4, %5
	%elif	%0 == 6
		__call5	%1, %2, %3, %4, %5, %6
	%elif	%0 == 7
		__call6	%1, %2, %3, %4, %5, %6, %7
	%endif
%endmacro