ISA와 어셈블리

RISC-V에서 자기 자신을 호출하는 재귀 함수를 작성할 때 ra를 스택에 저장하는 것을 잊으면 어떻게 되는가?

  1. A안쪽 호출에서 ra가 덮어써져 바깥쪽 함수가 올바른 호출 원본으로 복귀하지 못하게 된다
  2. BCPU가 자동으로 ra를 저장하므로 아무 문제도 일어나지 않는다
  3. C재귀의 깊이와 관계없이 계산 결과가 2배가 된다
정답과 해설 보기

정답: A. 안쪽 호출에서 ra가 덮어써져 바깥쪽 함수가 올바른 호출 원본으로 복귀하지 못하게 된다

재귀 호출의 jal은 ra를 '자신 안의 호출 다음 명령어'로 덮어씁니다. 저장하지 않으면 바깥쪽 함수가 ret할 때 원래 호출 원본이 아니라 자신 안으로 되돌아가 버려 같은 곳을 반복하거나 오동작합니다. 그래서 다른 함수를 호출하는 함수는 프롤로그에서 ra를 스택에 저장하고 에필로그에서 되돌리는 것이 규칙입니다.

이 분야 연습하기 분야로 돌아가기

ISA와 어셈블리의 다른 문제

  1. 리틀 엔디안 RISC-V에서 0x12345678이 들어 있는 레지스터를 'sw'로 주소 0x100에 썼다. 그 후 'lbu'로 주소 0x101의 1바이트를 읽으면 값은 얼마인가?
  2. RISC-V에서 4바이트를 읽는 lw 명령어의 주소가 4의 배수가 아닐 때(경계가 맞지 않을 때) 일어날 수 있는 일로 올바른 것은?
  3. RISC-V 명령어 'slli t0, a0, 3'의 결과 t0는 a0 값의 몇 배가 되는가? (오버플로는 고려하지 않음)
  4. a0에 int형(4바이트) 배열 a의 시작 주소, a1에 첨자 i가 들어 있다. 위의 코드가 a2에 읽어 들이는 것으로 올바른 것은?
  5. x86의 명령어 'add eax, [rbx]'처럼 연산 명령어가 메모리 상의 값을 직접 사용할 수 있는 방식에 대해 올바른 것은?