Ввод и вывод

Ввод и вывод

обрабатывает весь ввод и вывод. (вызов окружения) просит операционную систему или симулятор выполнить службу для вашего ассемблерного кода. Экран и клавиатура — это две из служб, доступных таким образом.

Поместите номер службы в a7, любой аргумент в a0, затем вызовите . Службы, которые знает этот симулятор:

Услуги (a7)
1 # вывести целое число (a0 = число)
4 # вывести строку (a0 = адрес текста)
5 # считать целое число (результат возвращается в a0)
10 # завершить программу
32 # пауза (a0 = миллисекунды)
Вызов службы
программа
a71
a0значение
ecall
systemвыводит число

a7 = 1 выбирает службу печати.

Каждый сервис использует один и тот же двухрегистровый механизм установления связи. a7 указывает, какой сервис запустить, а a0 передаёт всё, что требуется этому сервису: значение для вывода, адрес для чтения, время ожидания. Список фиксированный и короткий — всего пять элементов, поэтому достаточно один раз освоить этот протокол обмена данными, чтобы понять все способы взаимодействия этого симулятора с внешним миром. Настоящая операционная система расширяет эту же идею до гораздо более длинного списка.
Считать число, умножить его на два, вывести на экран
li a7, 5 # считать целое число -> a0
ecall
add a0, a0, a0 # удвоить его
li a7, 1 # вывести целое число
ecall
li a7, 10
ecall

выбирает чтение целого числа, а приостанавливает выполнение в ожидании ввода, возвращая ваше число в a0. прибавляет a0 к самому себе, удваивая его на месте. Затем и выводят результат, а и завершают программу. Когда вы запустите её, симулятор покажет поле ввода. Введите число и посмотрите, как оно вернётся удвоенным.

Вывод текста

Сначала два новых термина. Раздел — это обозначенная область вашей программы: инструкции находятся в разделе .text, а фиксированные данные, такие как текст, — в разделе .data. А адрес — это просто число, идентифицирующее одну ячейку в памяти. Вместо того чтобы переносить всю строку целиком, регистр может хранить адрес, с которого начинается строка, а служба вывода считывает данные именно оттуда.

Текст размещается в секции данных. Вы привязываете к нему метку, затем используете ("load address"), чтобы загрузить адрес этой метки, и службу 4, чтобы его вывести.

Здравствуйте, RISC-V
.data
msg: .string "Hello, RISC-V!\n"
.text
la a0, msg # a0 = адрес текста
li a7, 4 # вывести строку
ecall
li a7, 10
ecall

В .data директива резервирует место для текста и привязывает метку msg. .string сохраняет символы и добавляет \n — символ новой строки. В .text помещает адрес текста в a0, выбирает службу вывода строки, а выводит символы с этого адреса, пока не достигнет конца строки. Затем программа завершается как обычно.