; demo data for (2c – d/3) / (b – a/4):

; 1. a = 12, b = 7, c = 7, d = 18
; (2 * 7 - 18 / 3) / (7 - 12 / 4) = (14 - 6) / (7 - 3) = 8 / 4 = 2

; 2. a = 180, b = 50, c = 100, d = 30
; (2 * 100 - 30 / 3) / (50 - 180 / 4) = (200 - 10) / (50 - 45) = 190 / 5 = 38

; 3. a = 10, b = 6, c = 2, d = 11
; (2 * 2 - 11 / 3) / (6 - 10 / 4) = (4 - 3) / (6 - 2) = 1 / 4 = 0
    
section .data
    GREETING: db '(2c – d / 3) / (b – a / 4)', 10
    GREETING_LEN: equ $-GREETING 
    LIM: db 'Limitations: 6c >= d, 4b >= a, b - a / 4 != 0, division is integer, all variables are integers', 10
    LIM_LEN: equ $-LIM
    ENTER_A: db 'Enter a (0 <= a <= 255): '
    ENTER_B: db 'Enter b (0 <= b <= 255): '
    ENTER_C: db 'Enter c (0 <= c <= 255): '
    ENTER_D: db 'Enter d (0 <= d <= 255): '
    RES_STR: db '(2c – d/3) / (b – a/4) = '
    RES_STR_LEN: equ $-RES_STR
    NEWLINE: db 10
section .bss
    num_buf: resb 4
    a: resb 1
    b: resb 1
    c: resb 1
    d: resb 1
    res: resb 1
    t1: resb 1
    t2: resb 1
section .text
    global _start
    
%macro print 2
    mov ecx, %1
    mov edx, %2
    mov eax, 4
    mov ebx, 1
    int 80h
%endmacro

%macro print_int 1
; prints integer without leading 0
; arg is a memory address of an 3 char max int as a string
    mov eax, 3
    cmp byte [%1], 48
    jne %%done
    dec eax
    cmp byte [%1 + 1], 48
    jne %%done
    dec eax

%%done:
    mov ebx, 3
    sub ebx, eax
    mov edx, %1
    add edx, ebx
    
    mov ecx, edx
    mov edx, eax
    mov eax, 4
    mov ebx, 1
    int 80h
%endmacro

%macro inttostr 2
; CONVERTING NUMBER TO STRING
    xor eax, eax
    mov al, [%1]
    mov cx, 10 ; divider
    
    mov dx, 0
    div cx ; divides edx:eax by arg stores result in eax and remainder in edx
    add dx, 48
    mov [%2 + 2], dl
    
    mov dx, 0
    div cx
    add dx, 48
    mov [%2 + 1], dl
    
    mov dx, 0
    div cx 
    add dx, 48
    mov [%2], dl
%endmacro

%macro readln_int 1
    mov eax, 3
    mov ebx, 2
    mov ecx, num_buf
    mov edx, 4
    int 80h
    
    mov byte [num_buf + 3], 10 ; manually set end of line (user can try to input 1234)
    
    mov ebx, 0
    mov edx, num_buf
%%int_len:
    xor eax, eax ; ~ mov eax, 0
    mov al, byte [edx]
    push eax
    inc edx
    inc ebx
    cmp al, 10
    jne %%int_len
    
    pop eax ; removing \n from the stack
    dec ebx ; \n is not the digit
; now ebx contains amount of digits in number and stack contains all the digits as chars

    xor ecx, ecx
    cmp ebx, 0 ; if 0 digits => done
    je %%done

    pop ecx
    sub ecx, 48 ; converting from char to int, that it represent
    cmp ebx, 1 ; if 1 digit
    je %%done
    
    pop eax
    sub eax, 48
    mov edx, 10
    mul dl ; mul multiplies eax by arg and stores res in eax
    add ecx, eax
    cmp ebx, 2 ; if 2 digits
    je %%done
    
    pop eax
    sub eax, 48
    mov edx, 100
    mul dl
    add ecx, eax
%%done: 
; now ecx contains the number

    mov [%1], cl ; storing first byte of it to the memory
%endmacro
    
_start:
    print GREETING, GREETING_LEN
    print LIM, LIM_LEN
    
    print ENTER_A, 25
    readln_int a
    
    print ENTER_B, 25
    readln_int b
    
    print ENTER_C, 25
    readln_int c
    
    print ENTER_D, 25
    readln_int d
    
    ; t1 = (2c – d/3)
    xor eax, eax
    mov al, [c]
    mov ecx, 2
    mul cx
    mov [t1], al
    
    xor eax, eax
    mov al, [d]
    mov ecx, 3
    div cx
    mov [t2], al
    
    xor eax, eax
    xor ebx, ebx
    mov al, [t1]
    mov bl, [t2]
    sub eax, ebx
    mov [t1], al
    
    ; t2 = (b – a/4)
    xor eax, eax
    mov al, [a]
    mov ecx, 4
    div cx
    xor ebx, ebx
    mov bl, [b]
    sub ebx, eax
    mov [t2], bl
    
    ; res = (t1 / t2) = (2c – d/3) / (b – a/4)
    xor eax, eax
    xor ecx, ecx
    xor edx, edx
    mov al, [t1]
    mov cl, [t2]
    div cx
    mov [res], al
    
    print RES_STR, RES_STR_LEN
    inttostr res, num_buf
    print_int num_buf
    print NEWLINE, 1
    
    mov eax, 1
    mov ebx, 0
    int 80h
