study_public/nasm.asm
2020-09-12 23:20:34 +03:00

205 lines
3.9 KiB
NASM
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

; 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