section .data
msg_input db 'Введите выражение (пример: 3+4*2): ', 0
msg_result db 10, 'Результат: ', 0
msg_error db 10, 'Ошибка!', 0
msg_div_zero db 'Деление на ноль', 0
buffer times 256 db 0
num_stack times 20 dq 0 ; Стек для чисел
op_stack times 20 db 0 ; Стек для операторов
num_top dq 0 ; Вершина стека чисел
op_top dq 0 ; Вершина стека операторов
section .text
global _start
_start:
; Вывод приглашения
mov rax, 1
mov rdi, 1
mov rsi, msg_input
mov rdx, 35
syscall
; Чтение ввода
mov rax, 0
mov rdi, 0
mov rsi, buffer
mov rdx, 255
syscall
; Инициализация
mov rsi, buffer ; Указатель на ввод
mov qword [num_top], 0 ; Стек чисел пуст
mov qword [op_top], 0 ; Стек операторов пуст
; Главный цикл разбора
process_char:
mov al, [rsi] ; Читаем символ
inc rsi
cmp al, 10 ; Конец строки (LF)
je process_remaining_ops
cmp al, ' ' ; Пропускаем пробелы
je process_char
; Если цифра
cmp al, '0'
jb not_digit
cmp al, '9'
ja not_digit
; Преобразуем символ в число
sub al, '0'
mov rbx, rax ; Сохраняем цифру в RBX
; Читаем остальные цифры числа
read_number:
mov al, [rsi]
cmp al, '0'
jb push_number
cmp al, '9'
ja push_number
; RBX = RBX * 10 + новая цифра
imul rbx, 10
sub al, '0'
add rbx, rax
inc rsi
jmp read_number
push_number:
; Помещаем число в стек
mov rax, [num_top]
mov [num_stack + rax*8], rbx
inc qword [num_top]
jmp process_char
not_digit:
; Обработка операторов
cmp al, '+'
je process_op
cmp al, '-'
je process_op
cmp al, '*'
je process_op
cmp al, '/'
je process_op
jmp input_error ; Неизвестный символ
process_op:
; Обработка приоритетов
cmp qword [op_top], 0
je push_op ; Стек операторов пуст
; Сравниваем приоритеты
mov rbx, [op_top]
dec rbx
mov cl, [op_stack + rbx] ; Верхний оператор в стеке
; Приоритет текущего оператора (AL)
call get_priority
mov dl, al
; Приоритет оператора в стеке (CL)
mov al, cl
call get_priority
; Если приоритет в стеке >= текущего, выполняем операцию
cmp al, dl
jge apply_operation
jmp push_op
apply_operation:
call do_operation
jmp process_op
push_op:
; Добавляем оператор в стек
mov rbx, [op_top]
mov [op_stack + rbx], al
inc qword [op_top]
jmp process_char
process_remaining_ops:
; Выполняем оставшиеся операции
cmp qword [op_top], 0
je print_result
call do_operation
jmp process_remaining_ops
print_result:
; Вывод результата
mov rax, 1
mov rdi, 1
mov rsi, msg_result
mov rdx, 12
syscall
mov rax, [num_stack] ; Результат в вершине стека
call print_number
; Перенос строки
mov rax, 1
mov rdi, 1
mov rsi, 10
push rsi
mov rsi, rsp
mov rdx, 1
syscall
pop rsi
mov rax, 60
xor rdi, rdi
syscall
; --- Процедуры ---
get_priority:
; Возвращает приоритет оператора в AL
cmp al, '+'
je .low
cmp al, '-'
je .low
cmp al, '*'
je .high
cmp al, '/'
je .high
mov al, 0
ret
.low:
mov al, 1
ret
.high:
mov al, 2
ret
do_operation:
; Извлекаем оператор
dec qword [op_top]
mov rbx, [op_top]
mov al, [op_stack + rbx]
; Извлекаем операнды
dec qword [num_top]
mov rbx, [num_top]
mov rcx, [num_stack + rbx*8] ; Правый операнд
dec qword [num_top]
mov rbx, [num_top]
mov rax, [num_stack + rbx*8] ; Левый операнд
; Выполняем операцию
cmp al, '+'
je .add
cmp al, '-'
je .sub
cmp al, '*'
je .mul
cmp al, '/'
.add:
add rax, rcx
jmp .store_result
.sub:
sub rax, rcx
jmp .store_result
.mul:
imul rcx
jmp .store_result
cmp rcx, 0
je division_error
cqo
idiv rcx
.store_result:
mov [num_stack + rbx*8], rax
inc qword [num_top]
ret
print_number:
; Вывод числа из RAX
mov rbx, 10
xor rcx, rcx ; Счётчик цифр
.div_loop:
xor rdx, rdx
add dl, '0'
push rdx
inc rcx
test rax, rax
jnz .div_loop
.print_loop:
pop rdx
mov [msg_result + 12], dl ; Используем буфер для вывода
mov rax, 1
mov rdi, 1
mov rsi, msg_result + 12
mov rdx, 1
syscall
loop .print_loop
ret
division_error:
mov rax, 1
mov rdi, 1
mov rsi, msg_error
mov rdx, 8
syscall
mov rax, 1
mov rdi, 1
mov rsi, msg_div_zero
mov rdx, 14
syscall
input_error:
mov rax, 1
mov rdi, 1
mov rsi, msg_error
mov rdx, 8
syscall
c2VjdGlvbiAuZGF0YQogICAgbXNnX2lucHV0ICAgZGIgJ9CS0LLQtdC00LjRgtC1INCy0YvRgNCw0LbQtdC90LjQtSAo0L/RgNC40LzQtdGAOiAzKzQqMik6ICcsIDAKICAgIG1zZ19yZXN1bHQgIGRiIDEwLCAn0KDQtdC30YPQu9GM0YLQsNGCOiAnLCAwCiAgICBtc2dfZXJyb3IgICBkYiAxMCwgJ9Ce0YjQuNCx0LrQsCEnLCAwCiAgICBtc2dfZGl2X3plcm8gZGIgJ9CU0LXQu9C10L3QuNC1INC90LAg0L3QvtC70YwnLCAwCiAgICBidWZmZXIgICAgICB0aW1lcyAyNTYgZGIgMAogICAgbnVtX3N0YWNrICAgdGltZXMgMjAgZHEgMCAgIDsg0KHRgtC10Log0LTQu9GPINGH0LjRgdC10LsKICAgIG9wX3N0YWNrICAgIHRpbWVzIDIwIGRiIDAgICA7INCh0YLQtdC6INC00LvRjyDQvtC/0LXRgNCw0YLQvtGA0L7QsgogICAgbnVtX3RvcCAgICAgZHEgMCAgICAgICAgICAgIDsg0JLQtdGA0YjQuNC90LAg0YHRgtC10LrQsCDRh9C40YHQtdC7CiAgICBvcF90b3AgICAgICBkcSAwICAgICAgICAgICAgOyDQktC10YDRiNC40L3QsCDRgdGC0LXQutCwINC+0L/QtdGA0LDRgtC+0YDQvtCyCgpzZWN0aW9uIC50ZXh0CiAgICBnbG9iYWwgX3N0YXJ0Cgpfc3RhcnQ6CiAgICA7INCS0YvQstC+0LQg0L/RgNC40LPQu9Cw0YjQtdC90LjRjwogICAgbW92IHJheCwgMQogICAgbW92IHJkaSwgMQogICAgbW92IHJzaSwgbXNnX2lucHV0CiAgICBtb3YgcmR4LCAzNQogICAgc3lzY2FsbAogICAgCiAgICA7INCn0YLQtdC90LjQtSDQstCy0L7QtNCwCiAgICBtb3YgcmF4LCAwCiAgICBtb3YgcmRpLCAwCiAgICBtb3YgcnNpLCBidWZmZXIKICAgIG1vdiByZHgsIDI1NQogICAgc3lzY2FsbAogICAgCiAgICA7INCY0L3QuNGG0LjQsNC70LjQt9Cw0YbQuNGPCiAgICBtb3YgcnNpLCBidWZmZXIgICAgICAgICAgICA7INCj0LrQsNC30LDRgtC10LvRjCDQvdCwINCy0LLQvtC0CiAgICBtb3YgcXdvcmQgW251bV90b3BdLCAwICAgICA7INCh0YLQtdC6INGH0LjRgdC10Lsg0L/Rg9GB0YIKICAgIG1vdiBxd29yZCBbb3BfdG9wXSwgMCAgICAgIDsg0KHRgtC10Log0L7Qv9C10YDQsNGC0L7RgNC+0LIg0L/Rg9GB0YIKCiAgICA7INCT0LvQsNCy0L3Ri9C5INGG0LjQutC7INGA0LDQt9Cx0L7RgNCwCnByb2Nlc3NfY2hhcjoKICAgIG1vdiBhbCwgW3JzaV0gICAgICAgICAgICAgIDsg0KfQuNGC0LDQtdC8INGB0LjQvNCy0L7QuwogICAgaW5jIHJzaQogICAgCiAgICBjbXAgYWwsIDEwICAgICAgICAgICAgICAgICA7INCa0L7QvdC10YYg0YHRgtGA0L7QutC4IChMRikKICAgIGplIHByb2Nlc3NfcmVtYWluaW5nX29wcwogICAgY21wIGFsLCAnICcgICAgICAgICAgICAgICAgOyDQn9GA0L7Qv9GD0YHQutCw0LXQvCDQv9GA0L7QsdC10LvRiwogICAgamUgcHJvY2Vzc19jaGFyCiAgICAKICAgIDsg0JXRgdC70Lgg0YbQuNGE0YDQsAogICAgY21wIGFsLCAnMCcKICAgIGpiIG5vdF9kaWdpdAogICAgY21wIGFsLCAnOScKICAgIGphIG5vdF9kaWdpdAogICAgCiAgICA7INCf0YDQtdC+0LHRgNCw0LfRg9C10Lwg0YHQuNC80LLQvtC7INCyINGH0LjRgdC70L4KICAgIHN1YiBhbCwgJzAnCiAgICBtb3YgcmJ4LCByYXggICAgICAgICAgICAgICA7INCh0L7RhdGA0LDQvdGP0LXQvCDRhtC40YTRgNGDINCyIFJCWAogICAgCiAgICA7INCn0LjRgtCw0LXQvCDQvtGB0YLQsNC70YzQvdGL0LUg0YbQuNGE0YDRiyDRh9C40YHQu9CwCnJlYWRfbnVtYmVyOgogICAgbW92IGFsLCBbcnNpXQogICAgY21wIGFsLCAnMCcKICAgIGpiIHB1c2hfbnVtYmVyCiAgICBjbXAgYWwsICc5JwogICAgamEgcHVzaF9udW1iZXIKICAgIAogICAgOyBSQlggPSBSQlggKiAxMCArINC90L7QstCw0Y8g0YbQuNGE0YDQsAogICAgaW11bCByYngsIDEwCiAgICBzdWIgYWwsICcwJwogICAgYWRkIHJieCwgcmF4CiAgICBpbmMgcnNpCiAgICBqbXAgcmVhZF9udW1iZXIKICAgIApwdXNoX251bWJlcjoKICAgIDsg0J/QvtC80LXRidCw0LXQvCDRh9C40YHQu9C+INCyINGB0YLQtdC6CiAgICBtb3YgcmF4LCBbbnVtX3RvcF0KICAgIG1vdiBbbnVtX3N0YWNrICsgcmF4KjhdLCByYngKICAgIGluYyBxd29yZCBbbnVtX3RvcF0KICAgIGptcCBwcm9jZXNzX2NoYXIKICAgIApub3RfZGlnaXQ6CiAgICA7INCe0LHRgNCw0LHQvtGC0LrQsCDQvtC/0LXRgNCw0YLQvtGA0L7QsgogICAgY21wIGFsLCAnKycKICAgIGplIHByb2Nlc3Nfb3AKICAgIGNtcCBhbCwgJy0nCiAgICBqZSBwcm9jZXNzX29wCiAgICBjbXAgYWwsICcqJwogICAgamUgcHJvY2Vzc19vcAogICAgY21wIGFsLCAnLycKICAgIGplIHByb2Nlc3Nfb3AKICAgIGptcCBpbnB1dF9lcnJvciAgICAgICAgICAgIDsg0J3QtdC40LfQstC10YHRgtC90YvQuSDRgdC40LzQstC+0LsKICAgIApwcm9jZXNzX29wOgogICAgOyDQntCx0YDQsNCx0L7RgtC60LAg0L/RgNC40L7RgNC40YLQtdGC0L7QsgogICAgY21wIHF3b3JkIFtvcF90b3BdLCAwCiAgICBqZSBwdXNoX29wICAgICAgICAgICAgICAgICA7INCh0YLQtdC6INC+0L/QtdGA0LDRgtC+0YDQvtCyINC/0YPRgdGCCiAgICAKICAgIDsg0KHRgNCw0LLQvdC40LLQsNC10Lwg0L/RgNC40L7RgNC40YLQtdGC0YsKICAgIG1vdiByYngsIFtvcF90b3BdCiAgICBkZWMgcmJ4CiAgICBtb3YgY2wsIFtvcF9zdGFjayArIHJieF0gICA7INCS0LXRgNGF0L3QuNC5INC+0L/QtdGA0LDRgtC+0YAg0LIg0YHRgtC10LrQtQogICAgCiAgICA7INCf0YDQuNC+0YDQuNGC0LXRgiDRgtC10LrRg9GJ0LXQs9C+INC+0L/QtdGA0LDRgtC+0YDQsCAoQUwpCiAgICBjYWxsIGdldF9wcmlvcml0eQogICAgbW92IGRsLCBhbAogICAgCiAgICA7INCf0YDQuNC+0YDQuNGC0LXRgiDQvtC/0LXRgNCw0YLQvtGA0LAg0LIg0YHRgtC10LrQtSAoQ0wpCiAgICBtb3YgYWwsIGNsCiAgICBjYWxsIGdldF9wcmlvcml0eQogICAgCiAgICA7INCV0YHQu9C4INC/0YDQuNC+0YDQuNGC0LXRgiDQsiDRgdGC0LXQutC1ID49INGC0LXQutGD0YnQtdCz0L4sINCy0YvQv9C+0LvQvdGP0LXQvCDQvtC/0LXRgNCw0YbQuNGOCiAgICBjbXAgYWwsIGRsCiAgICBqZ2UgYXBwbHlfb3BlcmF0aW9uCiAgICBqbXAgcHVzaF9vcAogICAgCmFwcGx5X29wZXJhdGlvbjoKICAgIGNhbGwgZG9fb3BlcmF0aW9uCiAgICBqbXAgcHJvY2Vzc19vcAogICAgCnB1c2hfb3A6CiAgICA7INCU0L7QsdCw0LLQu9GP0LXQvCDQvtC/0LXRgNCw0YLQvtGAINCyINGB0YLQtdC6CiAgICBtb3YgcmJ4LCBbb3BfdG9wXQogICAgbW92IFtvcF9zdGFjayArIHJieF0sIGFsCiAgICBpbmMgcXdvcmQgW29wX3RvcF0KICAgIGptcCBwcm9jZXNzX2NoYXIKICAgIApwcm9jZXNzX3JlbWFpbmluZ19vcHM6CiAgICA7INCS0YvQv9C+0LvQvdGP0LXQvCDQvtGB0YLQsNCy0YjQuNC10YHRjyDQvtC/0LXRgNCw0YbQuNC4CiAgICBjbXAgcXdvcmQgW29wX3RvcF0sIDAKICAgIGplIHByaW50X3Jlc3VsdAogICAgY2FsbCBkb19vcGVyYXRpb24KICAgIGptcCBwcm9jZXNzX3JlbWFpbmluZ19vcHMKICAgIApwcmludF9yZXN1bHQ6CiAgICA7INCS0YvQstC+0LQg0YDQtdC30YPQu9GM0YLQsNGC0LAKICAgIG1vdiByYXgsIDEKICAgIG1vdiByZGksIDEKICAgIG1vdiByc2ksIG1zZ19yZXN1bHQKICAgIG1vdiByZHgsIDEyCiAgICBzeXNjYWxsCiAgICAKICAgIG1vdiByYXgsIFtudW1fc3RhY2tdICAgICAgIDsg0KDQtdC30YPQu9GM0YLQsNGCINCyINCy0LXRgNGI0LjQvdC1INGB0YLQtdC60LAKICAgIGNhbGwgcHJpbnRfbnVtYmVyCiAgICAKICAgIDsg0J/QtdGA0LXQvdC+0YEg0YHRgtGA0L7QutC4CiAgICBtb3YgcmF4LCAxCiAgICBtb3YgcmRpLCAxCiAgICBtb3YgcnNpLCAxMAogICAgcHVzaCByc2kKICAgIG1vdiByc2ksIHJzcAogICAgbW92IHJkeCwgMQogICAgc3lzY2FsbAogICAgcG9wIHJzaQogICAgCmV4aXQ6CiAgICBtb3YgcmF4LCA2MAogICAgeG9yIHJkaSwgcmRpCiAgICBzeXNjYWxsCgo7IC0tLSDQn9GA0L7RhtC10LTRg9GA0YsgLS0tCgpnZXRfcHJpb3JpdHk6CiAgICA7INCS0L7Qt9Cy0YDQsNGJ0LDQtdGCINC/0YDQuNC+0YDQuNGC0LXRgiDQvtC/0LXRgNCw0YLQvtGA0LAg0LIgQUwKICAgIGNtcCBhbCwgJysnCiAgICBqZSAubG93CiAgICBjbXAgYWwsICctJwogICAgamUgLmxvdwogICAgY21wIGFsLCAnKicKICAgIGplIC5oaWdoCiAgICBjbXAgYWwsICcvJwogICAgamUgLmhpZ2gKICAgIG1vdiBhbCwgMAogICAgcmV0Ci5sb3c6CiAgICBtb3YgYWwsIDEKICAgIHJldAouaGlnaDoKICAgIG1vdiBhbCwgMgogICAgcmV0Cgpkb19vcGVyYXRpb246CiAgICA7INCY0LfQstC70LXQutCw0LXQvCDQvtC/0LXRgNCw0YLQvtGACiAgICBkZWMgcXdvcmQgW29wX3RvcF0KICAgIG1vdiByYngsIFtvcF90b3BdCiAgICBtb3YgYWwsIFtvcF9zdGFjayArIHJieF0KICAgIAogICAgOyDQmNC30LLQu9C10LrQsNC10Lwg0L7Qv9C10YDQsNC90LTRiwogICAgZGVjIHF3b3JkIFtudW1fdG9wXQogICAgbW92IHJieCwgW251bV90b3BdCiAgICBtb3YgcmN4LCBbbnVtX3N0YWNrICsgcmJ4KjhdIDsg0J/RgNCw0LLRi9C5INC+0L/QtdGA0LDQvdC0CiAgICAKICAgIGRlYyBxd29yZCBbbnVtX3RvcF0KICAgIG1vdiByYngsIFtudW1fdG9wXQogICAgbW92IHJheCwgW251bV9zdGFjayArIHJieCo4XSA7INCb0LXQstGL0Lkg0L7Qv9C10YDQsNC90LQKICAgIAogICAgOyDQktGL0L/QvtC70L3Rj9C10Lwg0L7Qv9C10YDQsNGG0LjRjgogICAgY21wIGFsLCAnKycKICAgIGplIC5hZGQKICAgIGNtcCBhbCwgJy0nCiAgICBqZSAuc3ViCiAgICBjbXAgYWwsICcqJwogICAgamUgLm11bAogICAgY21wIGFsLCAnLycKICAgIGplIC5kaXYKICAgIAouYWRkOgogICAgYWRkIHJheCwgcmN4CiAgICBqbXAgLnN0b3JlX3Jlc3VsdAouc3ViOgogICAgc3ViIHJheCwgcmN4CiAgICBqbXAgLnN0b3JlX3Jlc3VsdAoubXVsOgogICAgaW11bCByY3gKICAgIGptcCAuc3RvcmVfcmVzdWx0Ci5kaXY6CiAgICBjbXAgcmN4LCAwCiAgICBqZSBkaXZpc2lvbl9lcnJvcgogICAgY3FvCiAgICBpZGl2IHJjeAogICAgCi5zdG9yZV9yZXN1bHQ6CiAgICBtb3YgW251bV9zdGFjayArIHJieCo4XSwgcmF4CiAgICBpbmMgcXdvcmQgW251bV90b3BdCiAgICByZXQKCnByaW50X251bWJlcjoKICAgIDsg0JLRi9Cy0L7QtCDRh9C40YHQu9CwINC40LcgUkFYCiAgICBtb3YgcmJ4LCAxMAogICAgeG9yIHJjeCwgcmN4ICAgICAgICAgICAgOyDQodGH0ZHRgtGH0LjQuiDRhtC40YTRgAogICAgCi5kaXZfbG9vcDoKICAgIHhvciByZHgsIHJkeAogICAgZGl2IHJieAogICAgYWRkIGRsLCAnMCcKICAgIHB1c2ggcmR4CiAgICBpbmMgcmN4CiAgICB0ZXN0IHJheCwgcmF4CiAgICBqbnogLmRpdl9sb29wCiAgICAKLnByaW50X2xvb3A6CiAgICBwb3AgcmR4CiAgICBtb3YgW21zZ19yZXN1bHQgKyAxMl0sIGRsICA7INCY0YHQv9C+0LvRjNC30YPQtdC8INCx0YPRhNC10YAg0LTQu9GPINCy0YvQstC+0LTQsAogICAgbW92IHJheCwgMQogICAgbW92IHJkaSwgMQogICAgbW92IHJzaSwgbXNnX3Jlc3VsdCArIDEyCiAgICBtb3YgcmR4LCAxCiAgICBzeXNjYWxsCiAgICBsb29wIC5wcmludF9sb29wCiAgICByZXQKCmRpdmlzaW9uX2Vycm9yOgogICAgbW92IHJheCwgMQogICAgbW92IHJkaSwgMQogICAgbW92IHJzaSwgbXNnX2Vycm9yCiAgICBtb3YgcmR4LCA4CiAgICBzeXNjYWxsCiAgICAKICAgIG1vdiByYXgsIDEKICAgIG1vdiByZGksIDEKICAgIG1vdiByc2ksIG1zZ19kaXZfemVybwogICAgbW92IHJkeCwgMTQKICAgIHN5c2NhbGwKICAgIGptcCBleGl0CiAgICAKaW5wdXRfZXJyb3I6CiAgICBtb3YgcmF4LCAxCiAgICBtb3YgcmRpLCAxCiAgICBtb3YgcnNpLCBtc2dfZXJyb3IKICAgIG1vdiByZHgsIDgKICAgIHN5c2NhbGwKICAgIGptcCBleGl0