본문 바로가기

study Computer Engineering/컴구학개론

[컴구학개론] 시즌1 2회 : Addressing for Wide Immediates and Addresses

 

1). Wide Immediate Operands

많은 비트가 필요한 즉치값을 이용해서, 주소 지정해서 저장, 로드하려면? 12비트 밖에 못쓰면, 주소 지정, 엄청난 라인을 건너뛰는 브랜치는 어떻게 하자는 건데? => 새로운 인스트럭션 타잎이 필요해

 

다들 immediate 부분은 12비트(4096 => 4메가 정도) 정도 밖에 안되네. 만약 로드, 스토어할 값이 엄청 크다면? 브랜치 할 때 뛰어야할 명령 수가 4메가로는 말도 안되게 부족하다면? => Wide한 즉치값, 주소가 필요한 상황에 대응해보자 !!

 

2). 32비트 상수를 로드하고, 저장하고 해보자

미션 : 즉치값 더하기로, 다음의 64비트 즉치 값을 비어있는 레지스터 16번에 로드해봐

어떻게 할 거 같나요? 어차피 생각 못해내니까 바로 답으로 이야기 할게요. 

 

1). 13번째 비트 ~ 32번째 비트 값을 별도의 인스트럭션으로 로드하기

 

    step1. lui x19,976 (976이 => 저 위 숫자의 13th ~ 32nd 비트를 10진법으로 바꾼 수에요 ^^)

 

2). 나머지는 I-type으로 더하기

 

    step2. addi x19, x19, 1280

 

3). 완성 !! - 이렇게 한다면, 레지스터를 operand로 쓰지 않고도 x16에 32비트 짜리 즉치값을 전달할 수 있었던 것입니다.

 

 

3). Addressing in Branches 분기할 때, 분기할 램 주소 전달해주기

 

    분기 시에 점프할 명령의 주소를 기계어에 전달하는 방식은 "PC-relative addressing" 입니다. jal, jalr, jump를 쓰면 항상 자동으로 PC와 더해진 것으로 분기한다라는 뜻입니다.

 

  PC에는 항상 현재 수행중이던 인스트럭션이 담겨져 있는데요, 분기 시에는(if, for, procedure call) 항상 이 PC를 기준으로 점프합니다.  if, while, for 문 같은 경우는 보통 현재 수행 중이던 곳으로 부터 멀리 뛰지 않기 때문에, PC레지스터 기준으로, "SB"타잎에 나온 것 처럼,  12비트 정도만 있으면 이것이 현재 수행 명령 +- 2^10 = 1024개 정도 뛸 수 있기 때문에 충분합니다. 만약 부족하다면, PC값 자체를 분기 할 명령 수에 더해서 쓸수도 있기 때문에, 사실 문제가될 것은 없습니다.

 

  하지만, 함수 호출의 경우에는 함수의 프로시져가 상당히 멀리 있을 수 있습니다. 함수로 만들어 놓는 게 좋은 것 자체도, 언제나 어디서든 부를 수 있기 때문이죠. 그럴 경우에는 2^64비트 떨어져 있어도(4기가가 2^32니까 ... 64비트면 그 크기가 어느정도인지 알 수 있겠죠?) 그 함수를 부를 수 있으면 좋을 거 같네요.

 

아까 사용한 방법처럼, 어떤 레지스터를 분기할 량을 담을 임시 레지스터로 사용하고, 

 

  1). LUI로 13번째 비트 부터 32비트까지 전달후

  2). jalr 로 그 레지스터의 1 ~ 12비트 까지 추가한 후, 무조건 점프를 해주는 방식으로 하면 +- 2^32 비트 => 2^10 * 2^10 * 2^10 * 2^2 =>    PC로부터 약 4기가 바이트 가량의 공간을 점프할 수 있습니다. 

 

rs2, rs1이 다르다면, PC 기준 +- 최대  2^10 - 1 개의 명령 점프

 

PC기준 +- (2^20 - 1)개 명령 점프 / jal : save pc+4 to x1 and jump to where immediate of 20bit points to. The PC is automatically added.

 

이러한 작업을 컴파일러가 해주는 거니까, 그냥 이러한 방식으로 우리가 짠 함수가, 무리없이 호출되고, if, for, while등이 수행된다고 보시면 될 것 같습니다.

 

 피연산자를 사용하는 방식(Addressing)에 따른 instructions type