Первая версия готовой лабы

parent f85c8ca4
No related merge requests found
Pipeline #41171 passed with stage
in 12 seconds
......@@ -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
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