본문 바로가기
컴퓨터/컴퓨터구조

[UCB CS61C] Lec08 RISC-V (lw, sw, decision making)

by 봄여름가을 2024. 1. 5.
  • 메모리 주소는 byte 단위로 되어 있다.
  • Little-endian convention에서는 word(4 bytes) 내에서 least-significant byte가 제일 작은 address에 저장된다(e.g. 0x12345678이면 78 56 34 12와 같이 저장). 따라서 Word address는 least-significant byte의 주소와 같다.
  • Little-endian vs Big-endian: 작은 것이 작은 주소로 가느냐 vs 큰 것이 작은 주소로 가느냐

Load from Memory to Register

  • lw : load word로, '오른쪽에서 왼쪽으로' 데이터를 가져온다.
    • 여기서 offset은 바이트 단위로 표현되며, assembly 시점에 알려진 상수여야 한다.
      // C code
      int A[100];
      g = h + A[3];
      //
      

lw x10, 12(x15) // x15는 base register, 12는 offset in bytes
add x11, x12, x10


#### Store from Register to Memory
* `sw`: store word로, '왼쪽에서 오른쪽으로' 데이터를 저장한다.
    * offset은 반드시 4의 배수여야 한다.

// C code
int A[100];
A[10] = h + A[3];

lw x10, 12(x15) // 임시 레지스터인 x10에 A[3]의 값 저장
add x10, x12, x10 // x10에 h + A[3] 저장
sw x10, 40(x15) // x15는 base register, 40은 offset in bytes


#### byte 단위 load, store
* byte단위의 data transfer인 `lb`, `sb`를 지원한다. 

lb x10, 3(x11) // x11로부터 3 바이트 위치에 있는 내용이 x10의 "Low byte position"에 복사된다. 그리고 복사된 바이트의 제일 첫 자리인 sign은 앞의 다른 byte들로 "sign-extend"된다.



#### Decision Making
* conditional branch
    * `beq`: branch if equal
    * `bne`: branch if not equal
    * `blt`: branch if less than
    * `bge`: branch if greater than or equal
    * `bltu, bgeu`: unsigned versions

beq reg1, reg2, L1 // go to statement labeled L1 if (value in reg1) == (value in reg2)

* unconditional branch: always branch
    * `j`: jump

j label


* 예시: beq를 사용하는 대신 조건을 부정문으로 바꾸었다. 왜냐하면 만약 조건에 맞지 않으면 그냥 다음 줄을 실행하면 되기 때문이다.

if (i == j)
f = g + h;

bne x13, x14, Exit
add x10, x11, x12
Exit ...

if (i == j)
f = g + h;
else
f = g - h;

bne x13, x14, Else
add x10, x11, x12
j Exit // 이와 같이 빠져나가게 해 주어야 한다! 그렇지 않으면 Else줄을 실행할 것이다.
Else: sub x10, x11, x12
Exit: ...


* 비교: Less than, greater than or equal to밖에 없다(Less than or equal to 같은 건 없음)

blt reg1, reg2, Label
// if (reg1 < reg2) goto Label;

bltu reg1, reg2, Label
// if (reg1 < reg2) goto Label; 단, reg를 unsigned int로 취급


* 반복문: 종료 조건을 제일 먼저 체크해주는 것이 중요하다. 그리고 우리가 i를 늘려가면서 관리(x11)하고 있지만 이는 종료 조건을 체크하는 데에만 사용되고, A(i+1)의 주소값은 별도로 4씩 늘려가면서 x9에 저장한다는 데 유의하자.

int A[20];
int sum = 0;
for (int i = 0; i < 20; i ++) {
sum += A[i];
}

add x9, x8, x0 # x9 = &A[0]
add x10, x0, x0 # sum
add x11, x0, x0 # i
addi x13, x0, 20 # 종료 조건값 20

Loop:
bge x11, x13, Done // 도달했다면 종료, 아니면 다음 줄로
lw x12, 0(x9) // x12에 A[i]값 가져오기
add x10, x10, x12 # 더하기 연산
addi x9, x9, 4 # &A[i+1]
addi x11, x11, 1 # i++
j Loop

Done:
```

댓글