%define SYS_WRITE	1
%define SYS_EXIT	60

%define STDIN_FILENO	0
%define STDOUT_FILENO	1
%define STDERR_FILENO	2

SECTION .bss
	cbuf: resb 1
	c: resb 1
	buf: resb 32

SECTION .text
putc:
	mov BYTE [cbuf], al	;  void printc(char cbuf <- al)
	mov rax, SYS_WRITE	;  {
	mov rdi, STDOUT_FILENO	;    write(STDOUT_FILENO, &cbuf, 1);
	mov rsi, cbuf		;  }
        mov rdx, 1		;
	syscall
	ret


printnum:
	mov	r15, rax	; r15 = rax; (save number)
	cmp	r15, 100	; if (r15 >= 100)
	jl	.else1
	mov	rbx, 100	; rbx=100
	cqo			; zero out rdx
	div	rbx		; rax = (rdx:rax)/rbx; rdx = (rdx:rax)%rbx
	add	rax, '0'	; rax += '0'
	call	putc		;   putc((n/100)+'0');
	jmp	.tens
.else1:				; else
	mov	al, ' '
	call	putc		;   putc(' ');

.tens:
	cmp	r15, 10
	jl	.else2
	mov	rax, r15
	mov	rbx, 10
	cqo
	div	rbx
	cqo
	idiv	rbx
	mov	rax, rdx
	add	al, '0'
	call	putc
	jmp	.ones
.else2:
	mov	al, ' '
	call	putc

.ones:
	mov	rax, r15
	mov	rbx, 10
	cqo
	div	rbx
	mov	rax, rdx
	add	al, '0'
	call	putc

	ret

printascii:                     ;  void printascii(char r13b) {
	  mov	BYTE [c], r13b	;    char c = r13b
	  mov	al, `\t`
	  call	putc		;    putc('\t');
	  movzx	rax, BYTE [c]
	  call	printnum	;    printnum(c);
	  mov	al, ':'
	  call	putc		;    putc(':');
	  mov	al, ' '
	  call	putc		;    putc(' ');
	  mov	al, `'`
	  call	putc		;    putc('\'');
	  mov	al, [c]
	  cmp	al, 32		;    if (c >= 32 
	  jl	.else             
	  cmp	al, 127		;	         && c < 127)
	  jge	.else
	  call	putc		;      putc(c);
	  jmp	.end
.else:				;    else
	  mov al, '.'
	  call putc		;      putc('.');

.end:
	  mov al, `'`
	  call putc		;   putc('\'');
	  ret			; return;

GLOBAL _start
_start:

	mov r12, 0		;  i = 0;
.loop:				;  do {
	mov r13, r12		;    c = i;
	call printascii		;    printascii(i);
	add r13, 32		;    i += 32;
	call printascii		;    printascii(i);
	add r13, 32		;    i += 32;
	call printascii		;    printascii(i);
	add r13, 32		;    i += 32;
	call printascii		;    printascii(i);
	mov al, `\n`
	call putc		;    putc('\n');
	inc r12			;    i++;
	cmp r12, 32
	jl .loop		; } while (i < 32);

	mov rax, SYS_EXIT
	mov rdi, 0
	syscall			; exit(0);
