Add new file

parent 67a4bdc6
global exit
global string_length
global print_string
global print_char
global print_newline
global print_uint
global print_int
global string_equals
global read_char
global read_word
global read_line
global parse_uint
global parse_int
global string_copy
section .text
; Принимает код возврата и завершает текущий процесс
exit:
mov rax, 60 ;sys_exit
syscall
ret
; Принимает указатель на нуль-терминированную строку, возвращает её длину
string_length:
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:
push rdi
mov rax, 1
mov rsi, rsp
mov rdi, 1
mov rdx, 1
syscall
pop rdi
ret
; Переводит строку (выводит символ с кодом 0xA)
print_newline:
mov rdi, 0xA
call print_char
ret
; Выводит беззнаковое 8-байтовое число в десятичном формате
; Совет: выделите место в стеке и храните там результаты деления
; Не забудьте перевести цифры в их ASCII коды.
print_uint:
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
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
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
; Принимает: адрес начала буфера, размер буфера
; Читает в буфер слово из stdin, пропуская пробельные символы в начале, .
; Пробельные символы это пробел 0x20, табуляция 0x9 и перевод строки 0xA.
; Останавливается и возвращает 0 если слово слишком большое для буфера
; При успехе возвращает адрес буфера в rax, длину слова в rdx.
; При неудаче возвращает 0 в rax
; Эта функция должна дописывать к слову нуль-терминатор
read_word:
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
; Принимает указатель на строку, пытается
; прочитать из её начала беззнаковое число.
; Возвращает в rax: число, rdx : его длину в символах
; 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
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 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
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment