205 lines
3.9 KiB
NASM
205 lines
3.9 KiB
NASM
; 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
|