(Lispex)sicp.io
제5장 · 점검

상태와 제어와 복귀 경로를 모두 드러내세요.

정본 수업 프로그램 열한 개로 레지스터와 pc, 스택, 컴파일, 선택적 보존, 어휘 주소, 힙 도달 가능성, 레이블, 컨트롤러 실행, 계측, 공유 서브루틴 연결을 다시 연결합니다.

점검 질문

유한한 기계 실행의 모든 값과 다음 명령, 저장된 continuation, 명시적인 작업 계수기를 설명할 수 있나요?

  • 바뀌는 레지스터 값을 하나의 상태로 나타내기
  • pc로 다음 명령 고르기
  • 미뤄 둔 곱셈을 명시적인 스택에 저장하기
  • 식 데이터를 별도 실행 전에 명령열로 컴파일하기
  • 레지스터 계약에 필요한 save와 restore만 넣기
  • 프레임 깊이와 바인딩 오프셋으로 값 가져오기
  • 루트에서 힙 참조를 추적하고 도달 불가능한 할당 분류하기
  • 컨트롤러 레이블을 숫자 명령 위치로 바꾸기
  • 해석된 assign, test, branch, goto, halt 실행하기
  • 가져온 명령 수, push 수, 최대 스택 깊이 세기
  • 명시적인 continuation으로 공유·중첩 서브루틴에서 복귀하기

레지스터와 pc는 바뀌는 값과 다음 명령을 드러냅니다. 스택은 다른 컨트롤러 경로를 거치는 동안 살아 있어야 하는 미완료 작업이나 복귀 정보를 저장합니다.

컴파일과 보존 계약, 어휘 주소, 레이블 해석은 실행 전에 소스 구조의 정보를 기계가 바로 사용할 명령과 인덱스로 옮깁니다.

힙 추적과 계측은 서로 다른 실행 이력을 보여 줍니다. 하나는 루트에서 도달 가능한 참조를, 다른 하나는 가져온 명령과 전체 save와 최대 스택 깊이를 기록합니다.

서브루틴 프로그램은 continue에 서로 다른 복귀 주소를 넣어 같은 컨트롤러 구간을 재사용합니다. 중첩 호출은 안쪽 continue를 대입하기 전에 바깥 값을 저장하고 원래 호출자로 돌아가기 전에 복원합니다.

리스펙스 · SICP 코드SICP에 필요한 Scheme 호환 문법을 리스펙스 SICP 프로필로 실행합니다.
(begin
  (define (step state)
    (let ((a (car state))
          (b (cadr state))
          (steps (caddr state)))
      (if (= b 0)
          state
          (list b (remainder a b) (+ steps 1)))))
  (define (run state)
    (if (= (cadr state) 0)
        state
        (run (step state))))
  (run (list 206 40 0)))
리스펙스 학습용 런타임리스펙스 SICP 프로필 1.0.0
리스펙스 SICP 런타임 불러오는 중
리스펙스 · SICP 코드UTF-8 316 / 1,048,576바이트
예제
결과
출력
진단
보이는 실행 흐름0 / 0 개의 실행 이벤트
    이 브라우저 결과는 리스펙스 바우치나 권한이 아닙니다.wasm —
    예상 관찰

    각 프로그램은 대응하는 제5장 수업의 첫 예상 관찰을 반환합니다. 계측 프로그램은 (6 27 4 4 0)을 반환하고 공유 서브루틴 프로그램은 (16 (3 7) (0 1 2 9 10 3 4 5 6 9 10 7 8))을 반환합니다.

    실행 흐름에서 볼 점

    레지스터 상태, pc, stack, compile, save/restore, lexical-ref, heap traversal, label table, controller fetch, 계측 카운터, continue 대입, goto-register 복귀, 중첩 호출의 continuation 보존을 순서대로 찾으세요.

    답을 보기 전에 설명하기

    기계를 생각하는 질문 열한 개

    계산을 다시 이어 가려면 어떤 정보가 상태에 있어야 할까요?

    run does not contain the arithmetic rule itself. It asks whether b is zero and otherwise repeats step, so the transition rule and the controller remain separate.

    전이 프로시저 하나가 여러 기계 명령을 어떻게 나타낼까요?

    Instruction 0 tests b and either enters the remainder cycle or jumps to halt at pc 5. The other instructions move values through temp before returning control to the test.

    기계가 재귀 문제 안으로 내려가는 동안 무엇을 저장해야 할까요?

    During return, each transition pops one saved multiplier and updates value. An empty stack means no suspended multiplication remains, so value is the final answer.

    표현식 트리는 어떻게 선형 명령열이 될까요?

    execute pushes constants. An arithmetic instruction pops the right and left values, combines them, and pushes the result. When no code remains, the stack top is the program value.

    두 명령열 사이에서 컴파일러는 언제 레지스터를 보존해야 할까요?

    The wrapped first sequence now needs the register in order to save it and no longer exposes that register as modified after restore. If either side of the conflict is absent, composition emits no stack instructions.

    컴파일할 때 환경에 관해 어떤 지식을 런타임 조회 밖으로 옮길 수 있을까요?

    find-address performs the name search against the compiler environment, whose frames contain variable names. Once it produces (1 0) for x, the runtime can use that address to fetch 42 from matching value frames. The example makes the compiler and machine agree on one frame layout.

    참조가 그래프를 이룰 때 저장소 관리자는 어떤 할당을 보존해야 할까요?

    The second heap contains a cycle from a through b and c back to a. contains? stops the revisit, while mark-roots starts a second traversal from x. unreachable then scans every allocation and classifies only dead outside the marked set. This lesson models tracing and classification, not memory reclamation itself.

    기계가 숫자 위치를 필요로 하기 전까지 컨트롤러가 읽기 쉬운 레이블을 쓰려면 어떻게 해야 할까요?

    assemble skips label symbols and asks resolve to replace only branch and goto targets. Ordinary instructions remain unchanged. The returned sequence is assembled controller data with numeric targets; this lesson does not execute that sequence or prove a complete machine assembler.

    숫자 프로그램 카운터 하나가 대입과 검사와 제어 이동을 어떻게 조정할까요?

    The first program executes the complete controller from n equal to 2 and leaves product equal to 2. The second records pc, n, product, and flag after every non-halt instruction while starting from n equal to 1. Both runs have a 40-step guard. This executor models only its listed instruction shapes and does not implement an arbitrary assembler, stack, or machine language.

    마지막 레지스터 값만으로는 알 수 없는 어떤 일을 컨트롤러 수준 계수기가 보여 줄까요?

    With n equal to 1, the branch jumps directly to the base assignment and reaches halt after five fetched instructions with no stack use. With n equal to 3, the controller saves continue and n at two recursive levels, so it performs four pushes, reaches depth four, and fetches 27 instructions before halting with value 6 and an empty stack. These numbers describe this exact controller, input, and counting convention. They are not elapsed time, CPU instructions, allocation cost, or a general profiler.

    레지스터 기계는 명령을 복사하지 않고 공유하거나 중첩한 서브루틴에서 어떻게 돌아올까요?

    두 번째 컨트롤러는 double-then-add-one 서브루틴을 부르고 그 서브루틴이 다시 double을 부릅니다. 안쪽 호출도 continue를 써야 하므로 바깥 서브루틴은 원래 호출자의 값을 먼저 저장합니다. double이 돌아오면 restore로 원래 주소를 복원하고 add1을 끝낸 뒤 main으로 복귀합니다. 이 유한 실행기는 명시적인 연결과 스택 한 칸을 모형화할 뿐 일반 조립기나 호출 규약 또는 하드웨어 서브루틴의 증명은 아닙니다.