        SYS_EXIT = 0x0000001
        SYS_READ = 0x0000003
        SYS_WRITE = 0x0000004
        STDIN = 0
        STDOUT = 1

.section .data
        .lcomm stack, 88000000
        .lcomm val, 8

.section .text

	.globl _main

_my_exit:
        mov    $SYS_EXIT, %rax
        mov    $0, %rdi # return code
        syscall

_read_char:
        push   %rdi
        push   %rsi
        mov    val@GOTPCREL(%rip), %rsi # where to save read byte
        mov    $1, %rdx # number of bytes to read
        mov    $STDIN, %rdi
        mov    $SYS_READ, %rax
        syscall
        test   %eax, %eax
        jne    .read_char_L0
        mov    $-1, %eax
        pop    %rsi
        pop    %rdi
        ret

.read_char_L0:
        mov    val@GOTPCREL(%rip), %rsi
        mov    (%rsi), %eax
        and    $255, %eax
        pop    %rsi
        pop    %rdi
        ret

_write_char:
        sub    $4, %rdi
        push   %rdi
        push   %rsi
        mov    (%rdi), %eax
        mov    val@GOTPCREL(%rip), %rsi
        mov    %eax, (%rsi)
        mov    $1, %rdx # number of bytes to write
        mov    $STDOUT, %rdi
        mov    $SYS_WRITE, %rax
        syscall
        pop    %rsi
        pop    %rdi
        ret

my_mul:
        sub    $4, %rdi
        mov    (%rdi), %eax
        mov    %rdi, %rcx
        sub    $4, %rcx
        mov    (%rcx), %ebx
        imul   %ebx
        mov    %eax, (%rcx)
        ret

my_div:
        sub    $4, %rdi
        mov    (%rdi), %eax
        cdq # sign extends edx if eax is negative
        mov    %rdi, %rcx
        sub    $4, %rcx
        mov    (%rcx), %ebx
        idiv   %ebx
        mov    %eax, (%rcx)
        ret

my_mod:
        sub    $4, %rdi
        mov    (%rdi), %eax
        cdq # sign extends edx if eax is negative
        mov    %rdi, %rcx
        sub    $4, %rcx
        mov    (%rcx), %ebx
        idiv   %ebx
        mov    %edx, (%rcx)
        ret

my_abs:
        mov    %rdi, %rcx
        sub    $4, %rcx
        mov    (%rcx), %eax
        test   %eax, %eax
        jg     L11
        neg    %eax
        mov    %eax, (%rcx)
L11:
        ret

_main:
        mov    stack@GOTPCREL(%rip), %rax

