입력 및 출력

입력 및 출력

은 모든 입력과 출력을 처리합니다. (environment call)은 운영 체제나 시뮬레이터에게 여러분의 어셈블리 코드를 위해 서비스를 수행하도록 요청합니다. 화면과 키보드는 이러한 방식으로 사용할 수 있는 서비스 중 두 가지입니다.

서비스 번호를 a7에, 인수를 a0에 넣은 다음 을 트리거합니다. 이 시뮬레이터가 알고 있는 서비스:

서비스 (a7)
1 # 정수 출력 (a0 = 숫자)
4 # 문자열 출력 (a0 = 텍스트 주소)
5 # 정수 읽기 (결과는 a0으로 반환)
10 # 프로그램 종료
32 # 대기 (a0 = 밀리초)
서비스 호출
program
a71
a0값
ecall
system숫자를 출력합니다

a7 = 1은 출력 서비스를 선택합니다.

모든 서비스는 동일한 두 레지스터 핸드셰이크를 공유합니다. a7은 실행할 서비스를 지정하고, a0은 해당 서비스에 필요한 모든 것(출력할 값, 읽을 주소, 대기 시간)을 전달합니다. 이 목록은 고정되어 있고 짧으며(5개 항목), 이 핸드셰이크를 한 번만 익히면 이 시뮬레이터가 외부 세계와 통신하는 모든 방식을 파악할 수 있습니다. 실제 운영 체제는 동일한 개념을 훨씬 더 긴 목록으로 확장합니다.
숫자를 읽고, 두 배로 곱한 뒤 출력하기
li a7, 5 # 정수 읽기 -> a0
ecall
add a0, a0, a0 # 두 배로 만든다
li a7, 1 # 정수 출력
ecall
li a7, 10
ecall

는 정수 읽기를 선택하고 은 입력을 기다린 뒤 여러분의 숫자를 a0에 반환합니다. 는 a0를 자기 자신에 더해 제자리에서 두 배로 만듭니다. 그런 다음 과 이 결과를 출력하고, 과 이 종료합니다. Run을 하면 시뮬레이터가 입력 상자를 띄웁니다. 숫자를 입력하면 두 배가 되어 돌아오는 것을 볼 수 있습니다.

텍스트 출력

먼저 두 가지 새로운 용어를 설명하겠습니다. 섹션은 프로그램 내의 레이블이 지정된 영역을 말합니다. 명령어는 .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에 넣고, 는 문자열 출력 서비스를 선택하며, 은 해당 주소에서 문자열의 끝에 도달할 때까지 문자들을 출력합니다. 그런 다음 프로그램은 평소처럼 종료됩니다.