Ввод и вывод
обрабатывает весь ввод и вывод. (вызов окружения) просит операционную систему или симулятор выполнить службу для вашего ассемблерного кода. Экран и клавиатура — это две из служб, доступных таким образом.
Поместите номер службы в a7, любой аргумент в a0, затем вызовите . Службы, которые знает этот симулятор:
1 # вывести целое число (a0 = число)4 # вывести строку (a0 = адрес текста)5 # считать целое число (результат возвращается в a0)10 # завершить программу32 # пауза (a0 = миллисекунды)
a7 = 1 выбирает службу печати.
a7 указывает, какой сервис запустить, а a0 передаёт всё, что требуется этому сервису: значение для вывода, адрес для чтения, время ожидания. Список фиксированный и короткий — всего пять элементов, поэтому достаточно один раз освоить этот протокол обмена данными, чтобы понять все способы взаимодействия этого симулятора с внешним миром. Настоящая операционная система расширяет эту же идею до гораздо более длинного списка.li a7, 5 # считать целое число -> a0ecalladd a0, a0, a0 # удвоить егоli a7, 1 # вывести целое числоecallli a7, 10ecall
выбирает чтение целого числа, а приостанавливает выполнение в ожидании ввода, возвращая ваше число в a0. прибавляет a0 к самому себе, удваивая его на месте. Затем и выводят результат, а и завершают программу. Когда вы запустите её, симулятор покажет поле ввода. Введите число и посмотрите, как оно вернётся удвоенным.
Вывод текста
Сначала два новых термина. Раздел — это обозначенная область вашей программы: инструкции находятся в разделе .text, а фиксированные данные, такие как текст, — в разделе .data. А адрес — это просто число, идентифицирующее одну ячейку в памяти. Вместо того чтобы переносить всю строку целиком, регистр может хранить адрес, с которого начинается строка, а служба вывода считывает данные именно оттуда.
Текст размещается в секции данных. Вы привязываете к нему метку, затем используете ("load address"), чтобы загрузить адрес этой метки, и службу 4, чтобы его вывести.
.datamsg: .string "Hello, RISC-V!\n".textla a0, msg # a0 = адрес текстаli a7, 4 # вывести строкуecallli a7, 10ecall
В .data директива резервирует место для текста и привязывает метку msg. .string сохраняет символы и добавляет \n — символ новой строки. В .text помещает адрес текста в a0, выбирает службу вывода строки, а выводит символы с этого адреса, пока не достигнет конца строки. Затем программа завершается как обычно.
