1. non-leaf procedure
    1. 함수가 다른 함수를 또 호출하는 함수! (그게 꼭 자기 자신이 아니더라도!)
    2. 대표적인 예로는 재귀함수가 있음! (얘는 자기 자신을 호출하는 함수)
    3. 이런 함수 콜이 연속되는 함수의 경우 caller 함수가 다음의 것들을 스택에 저장하고 있어야 함!
      1. RA 라고 불리는, 돌아갈 주소의 값 (호출 한 칸 아래)
      2. 콜이 된 이후에 필요한 인자라든지 변수들!! (리턴값도 여기에 포함이 되는 것인지..?ㅇㅇ 당연 그래야 레지스터로 가져가서 연산하지! x10 번 레지스터에 그 값이 저장된다는 것도 잊지 말자 여기는 파라미터와 리턴 값 둘 다 저장할 수 잇는 공간임!!)
    4. 모든 과정이 끝이 나면, 스택에서 지워지게 됨!!
  2. 재귀함수 호출 과정
  3. 문자열 데이터의 저장 과정!
    1. c 에서 봤듯이 1바이트 = 8 비트이고 총 256개의 데이터를 저장할 수 있음. 아스키코드가 대표적
    2. 반면 유니코드는 32비트 이므로 2^32 개의 데이터를 저장할 수 있음.
    3. 이 두 개는 서로 혼용이 안됨. 가끔 문서 파일 깨지는 이유가, 받은 파일은 유니코드인데 컴퓨터가 아스키코드로 읽으면 쓰레기 값이 읽혀서 그럼!!
  4. RISC-V 의 레지스터의 명령어는 32비트! 즉 메모리에는 32비트의 기계어가 명령어가 되어서 그게 ALU 에 전해지면 ALU 가 연산을 하는 거!! 그리고 레지스터 한 줄에는 32비트의 기계어를 저장할 수가 있음! 근데 만약에 만약에 immediate 값으로 훨씬 큰 수를 주고 싶다거나 레지스터에 훨씬 큰 수를 저장하고 싶다면 어떻게 해야 할까??
    1. LUI 를 사용하면 된다! load upper immediate 라고 하는 것!
      1. 총 20비트!! 의 상수를 레지스터의 12번에서 31번 자리에 넣음으로써 로드할 수 있게 된다!
        1. 이 더하는 과정을 잠시 설명해 보자면
        2. 먼저 addi 는 뒷 12 비트가 immediate 를 나타내기 때문에, 32비트에 몽땅 어떤 수를 넣고 싶다면, lui 가 필요함
        3. lui 는 32비트에서 왼쪽 20개의 비트를 가져와서 레지스터의 앞쪽 20비트에 채워넣는다. 그 다음에 addi 를 써주면 32비트에 완전히 다 값만 들어가게 된다!
  5. 브랜치에서의 주소!
    1. 브랜치는 주소에다가 immediate 값을 더해서 피융 하고 이동시키는 명령어!
    2. 그래서 immediate 에는 늘 주소값이 저장됨!
      1. 주소값은 워드 단위 즉 4바이트 단위이기 때문에, 모든 주소의 뒷 두 자리는 항상 00이 되게 됨! (2진수로 바꾸면)
      2. 따라서 00은 굳이 저장하지 않아도 된다!
      3. 근데 우리는 또 친절하게 두 번째 0은 저장하고, 맨 마지막 0만 안 저장함.
    3. 그래서 결국 우리가 가게 되는 주소는 PC + 2 * immediate 가 되는 것임!
  6. 무조건적 jump and link instruction jal
    1. 얘는 묻지도 따지지도 않고 그냥 jump! 무조건 jump 하는 애!
    2. 얘도 마찬가지로 맨 오른쪽 0은 버려버림!
    3. 여기서는 기존 레지스터가 담고 있던 32비트 즉 메모리 주소를 더하는 것이 아니라!! 레지스터 번호를 알려주면 pc 가 그 레지스터 번호에 있는 값에 더하게 된다!!
  7. 이렇듯 PC relative Addressing 에서는 32비트를 다 가리킬 수가 없어 한계가 있다!
    1. branch 에서는 상하 2^12 바이트, jal 에서는 2^20 바이트가 최대이다. (물론 위, 아래가 다 있기 때문에 가리킬 수 있는 것의 총 개수는 *2 를 해준 2^13, 2^21 이다.)
  8. R type, I type, S Type 등 타입에 해당하는 명령어가 무엇인지 알아야 하고, 외울 필요는 없다.
  9. 컴파일러 최적화의 효과
    1. 좋아진다. 성능이 모든 면에서!
    2. 오해
      1. 강한 인스트럭션 이를테면 곱하기를 쓰면 성능이 무조건 좋아지는 건 아니다. 필요한 인스트럭션의 수는 줄 수 있지만 곱하기 자체를 구현하는 데 시간이 만ㅇ히 걸린다.
      2. 꼭 어셈블리 코드를 써야 하는 건 아니다. 모던 프로세서에 더 잘 적응하고 있다. 현재 컴파일러는!
      3. Backward compatibility 는 무슨 말인지 모르겠다.. 질문!