From a36294a80bbe4b660146a1f98f8e2c64f1c4cc24 Mon Sep 17 00:00:00 2001 From: Nikita Kydlai <335058@niuitmo.ru> Date: Tue, 17 Jan 2023 15:00:12 +0000 Subject: [PATCH] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B2=D0=B0=D1=8F=20=D0=B2?= =?UTF-8?q?=D0=B5=D1=80=D1=81=D0=B8=D1=8F=20=D0=B3=D0=BE=D1=82=D0=BE=D0=B2?= =?UTF-8?q?=D0=BE=D0=B9=20=D0=BB=D0=B0=D0=B1=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib.inc | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 182 insertions(+), 19 deletions(-) diff --git a/lib.inc b/lib.inc index bdb5c33..ec75abb 100755 --- a/lib.inc +++ b/lib.inc @@ -3,49 +3,126 @@ section .text ; Принимает РєРѕРґ возврата Рё завершает текущий процесс exit: - xor rax, rax, + mov rax, 60 ;sys_exit + syscall ret ; Принимает указатель РЅР° нуль-терминированную строку, возвращает её длину string_length: - xor rax, rax + xor rax, rax +.loop: + cmp byte [rdi+rax], 0 + je .end + inc rax + jmp .loop +.end: ret ; Принимает указатель РЅР° нуль-терминированную строку, выводит её РІ stdout print_string: xor rax, rax + push rdi + call string_length + pop rdi + mov rdx, rax + mov rax, 1 + mov rsi, rdi + mov rdi, 1 + syscall ret ; Принимает РєРѕРґ символа Рё выводит его РІ stdout print_char: - xor rax, rax + push rdi + mov rax, 1 + mov rsi, rsp + mov rdi, 1 + mov rdx, 1 + syscall + pop rdi ret ; Переводит строку (выводит СЃРёРјРІРѕР» СЃ РєРѕРґРѕРј 0xA) print_newline: - xor rax, rax + mov rdi, 0xA + call print_char ret ; Выводит беззнаковое 8-байтовое число РІ десятичном формате ; Совет: выделите место РІ стеке Рё храните там результаты деления ; РќРµ забудьте перевести цифры РІ РёС… ASCII РєРѕРґС‹. print_uint: - xor rax, rax - ret + push r11 + push r12 + mov r11, 0xA ;10 + mov r12, rsp ;сохраняем rsp + push 0 + mov rax, rdi +.loop: + xor rdx, rdx + xor dl, dl + div r11 ;цел - rax, РѕСЃС‚ - rdx + add rdx, '0' ;перевод РІ ASCII + dec rsp + mov byte[rsp], dl + cmp rax, 0 + je .end + jmp .loop +.end: + mov rdi, rsp + call print_string + mov rsp, r12 ;возврат rsp + pop r12 + pop r11 + ret ; Выводит знаковое 8-байтовое число РІ десятичном формате print_int: xor rax, rax - ret + cmp rdi, 0 + jge .plus + jmp .minus +.minus: + push rdi + mov rdi, '-' + call print_char + pop rdi + neg rdi + jmp print_uint +.plus: + jmp print_uint ; Принимает РґРІР° указателя РЅР° нуль-терминированные строки, возвращает 1 если РѕРЅРё равны, 0 иначе string_equals: xor rax, rax - ret + xor rdx, rdx + xor r8, r8 + xor r9, r9 +.loop: + mov r8b, byte[rdi+rdx] + mov r9b, byte[rsi+rdx] + cmp r8b, r9b + jne .false + cmp r9b, 0 + je .true + inc rdx + jmp .loop +.true: + mov rax, 1 + ret +.false: + mov rax, 0 + ret ; Читает РѕРґРёРЅ СЃРёРјРІРѕР» РёР· stdin Рё возвращает его. Возвращает 0 если достигнут конец потока read_char: xor rax, rax + push 0 + xor rdi, rdi + mov rsi, rsp + mov rdx, 1 + syscall + pop rax ret ; Принимает: адрес начала буфера, размер буфера @@ -57,8 +134,45 @@ read_char: ; Рта функция должна дописывать Рє слову нуль-терминатор read_word: - ret - + xor rax, rax + xor rcx, rcx +.loop: + push rcx + push rsi + push rdi + call read_char + pop rdi + pop rsi + pop rcx + cmp rax, 0 + je .end + cmp rax, 0xA + je .skip + cmp rax, 0x9 + je .skip + cmp rax, 0x20 + je .skip + mov [rdi+rcx], rax + inc rcx + cmp rcx, rsi + je .false + jmp .loop +.skip: + cmp rcx, 0 + je .loop + jmp .end +.false: + xor rax, rax + xor rcx, rcx + jmp .stop +.end: + xor rax, rax + mov [rdi+rcx], rax + mov rax, rdi + mov rdx, rcx + jmp .stop +.stop: + ret ; Принимает указатель РЅР° строку, пытается ; прочитать РёР· её начала беззнаковое число. @@ -66,23 +180,72 @@ read_word: ; rdx = 0 если число прочитать РЅРµ удалось parse_uint: xor rax, rax + xor rcx, rcx + mov r8, 10 +.loop: + movzx r9, byte[rdi+rcx] + cmp r9, 0 + je .end + cmp r9b, '0' + jl .end + cmp r9b, '9' + jg .end + mul r8 + sub r9b, '0' + add rax, r9 + inc rcx + jmp .loop +.end: + mov rdx, rcx ret - - - ; Принимает указатель РЅР° строку, пытается ; прочитать РёР· её начала знаковое число. ; Если есть знак, пробелы между РЅРёРј Рё числом РЅРµ разрешены. ; Возвращает РІ rax: число, rdx : его длину РІ символах (включая знак, если РѕРЅ был) ; rdx = 0 если число прочитать РЅРµ удалось parse_int: - xor rax, rax - ret - -; Принимает указатель РЅР° строку, указатель РЅР° буфер Рё длину буфера -; Копирует строку РІ буфер + xor rax, rax + xor rdx, rdx + mov rcx, rdi + cmp byte[rcx], '-' + je .minus + jmp .plus +.minus: + inc rcx + mov rdi, rcx + push rcx + call parse_uint + pop rcx + neg rax + inc rdx + ret +.plus: + mov rdi, rcx + jmp parse_uint + +; Принимает указатель РЅР° строку, указатель РЅР° буфер Рё длину буфера +; Копирует строку РІ буфер ; Возвращает длину строки если РѕРЅР° умещается РІ буфер, иначе 0 string_copy: - xor rax, rax + xor rcx, rcx + call string_length + push r11 + mov r11, rax + cmp rdx, r11 + jl .false +.loop: + cmp rcx, r11 + jg .end + mov r8, [rdi+rcx] + mov [rsi+rcx], r8 + inc rcx + jmp .loop +.false: + mov rax, 0 + pop r11 + ret +.end: + mov rax, r11 + pop r11 ret -- GitLab