pc relative adderssing 의 경우, bne beq 등 branch 명령어에서 쓰이고, PC 에 상대적인 위치를 알려줌. 참고로 lw 등의 load 나 store 의 경우 바이트 단위로, jump 의 경우 word 단위로 씀.
현재 pc 에 있는 주소값에 address 필드에 있는 값을 더해서 그 값을 주소로 하는 메모리에 접근함. 이때 상대주소를 쓰는 이유! 이미 파라미터로 5비트씩 해서 10비트를 썼기 때문에 16비트만으로 메모리 주소를 가리켜야 함. 이를 위해 상대주소를 쓰는 거고, 상대주소를 쓸 수 있는 이유는 locality 지역성 때문인데, 이는 어차피 작은 공간 내에서만 움직이는 것이 확실할 때 상대주소를 사용할 수 있다는 것임.
c 파일을 컴파일하면 c.exe 파일이 됨. 그럼 메모리에서 레지스터로 정보를 옮겨 와야 함. 그게 위에 있는 숨겨진 코드임. lw 해서 메모리의 값들을 레지스터에 저장함. 그 다음에 컴파일러가 왼쪽의 문을 해석 = 파싱하게 됨. 순서는 괄호 1 괄호 2 마이너스 순. 그래서 차례로 어셈블리어로 연산함. 그리고 나서 숨겨진 코드가 하나 더 있는데 바로 레지스터에 저장된 값을 메모리에 store 하는 sw 명령어임. 오른쪽이 컴파일이 완료된 어셈블리어임.
얘도 마찬가지로 숨겨진 코드가 있어서 메모리에서 레지스터로 값을 로드해 옴. 이때 중요한 것은, g 는 store 하는 값이지 load 해오는 값이 아니라는 점이고, A 의 경우에는 그 자체가 첫번째 요소의 주소라는 사실. 그리고 4바이트짜리 데이터를 저장하는 배열이라고 가정했을 때, 먼저 4i 를 만들기 위해서 add 를 두 번 사용을 하고, (변형으로 2바이트 짜리 short 일 경우에는 add 를 한 번만 하면 됨.) A 의 베이스 주소에 4i 를 더하면 A[i] 의 주소가 됨. 그리고 나서 그 A[i] 의 값에 접근하는 0() 함수를 사용한 다음에 그걸 레지스터 t0 으로 로드해서 저장함. 그 다음에 A[i] 를 h 와 더하면 됨. 그리고 마지막으로 숨겨진 코드! sw 를 이용해서 결과값을 메모리에 저장하면 끝!
이것도 마찬가지로 f 빼고 다 로드해 옴. 그리고 bne 사용해서 만약 서로 다르면 else 로 점프하고 같으면 pc 가 그냥 아래로 한 칸 내려가서 더하기 연산 실행함. 만약 다를 경우 else 레이블로 점프해서 빼기로 들어감. 그리고 add 의 경우 끝나면 한 줄 내려와서 exit 으로 점프함. 그리고 exit 뒤에 그 값을 저장하는 sw 명령어가 숨겨져 잇음.
이것도 마찬가지로 save 가 4바이트의 데이터를 저장하는 배열이라고 가정해 봅시다. 그럼 일단 lw 로 로드해 와야겠지. 로드해 오고, save[i] 를 메모리 주소로 접근하려면 현재 데이터 타입이 4바이트를 저장하는 거니까, save + 4i 를 만들어줘야 하니 앞의 add 두 번을 통해 4i 를 만들어 주고, 세 번ㄴ째 add 에서 save[i] 의 주소값을 만들어주고 lw 이용해서 그 주소값의 값을 불러와서 저장한 다음에 save[i] 와 k 가 다른 경우 exit 로 점프하고 같을 경우 add 한 다음 다시 loop 레이블로 점프!! 근데 사실 여기서 마지막 ADD 밑에 sw 명령어가 빠져 잇음. exit 다 하고 한 번만 마지막으로 sw 할 수도 있지만 개발 상황에 따라 i 값을 계속 확인하고 싶을 경우 sw 가 add 밑에 있어야 함.