mret
lyszt.net은 mret 및 기타 RISC-V 명령어를 더 자세히 다룹니다.
설명
mret는 트랩 핸들러에서 반환합니다. 트랩은 프로세서가 실행 중인 프로그램을 중단하여 핸들러가 대신 처리할 수 있게 될 때 발생합니다. 핸들러는 고정 주소에 있는 루틴입니다. 장치가 인터럽트를 발생시키면, 예를 들어 GPIO 보드의 버튼 같은 것이 트랩을 시작합니다. 이 이름은 machine-mode return의 약자입니다.
mret
트랩이 시작되면 프로세서는 중단된 명령어의 주소를 mepc에 저장하고, 원인을 mcause에 기록하며, mstatus의 전역 인터럽트 활성화 비트를 지우고, mtvec에 있는 핸들러 주소로 점프합니다. mret는 이를 되돌립니다. mepc의 주소를 프로그램 카운터에 로드하고, 트랩 시작 시 mstatus가 저장한 인터럽트 활성화 비트를 복원합니다. 중단된 프로그램은 실행하려던 명령어부터 다시 시작합니다.
mret는 피연산자를 받지 않습니다. 이것이 없으면 프로세서는 핸들러의 끝을 지나 뒤따르는 코드로 계속 진행합니다.
인터럽트는 임의의 두 명령어 사이에 도착할 수 있으며, 중단된 프로그램은 이에 대한 준비를 전혀 하지 않았습니다. 따라서 핸들러는 변경하는 모든 레지스터를 저장하고 mret 전에 복원합니다.
버튼 핸들러는 또한 mret 전에 버튼의 보류 비트를 지웁니다. 그 비트가 설정된 채로 남아 있으면, mret가 인터럽트를 다시 켜는 즉시 같은 인터럽트가 다시 발생합니다.
이 예제는 target의 주소를 mepc에 쓰고 mret를 실행하여 그곳으로 점프합니다. 실제 트랩 밖에서는 이것이 점프 자체를 보여줍니다. CSR 쓰기에 대해서는 csrw를 참조하세요.
예시
la t0, target csrw mepc, t0 mret # pc = mepc, so execution continues at target target: nop
