Arithmatic Operations:
Memory Operands:
Main memory used for composite data
Load values from memory into registers(load word)
Store result from register to memory(store word)
Memory is byte addressed
레지스터는 메모리보다 접근이 빠르다.
컴파일러는 가능한한 레지스터의 변수를 사용해야한다.
spill to memory: 자주사용하지않는 변수들은 메모리에 저장해놓고 필요할때 메모리에서 가져온다.
C code:
g= h + A[8];
g in $s1, h in $s2 , base address of A in $s3
Compiled code:
lw $t0, 32($s3) # load word
add $s1 , $s2,$t0
C code:
A[12] = h + A[8];
h in $s2 , base address of A in $s3
Compiled code:
lw $t0, 32($s3) # load word
add $t0 , $s2,$t0
sw $t0, 48($s3) # store word
addi $s3 , $s3, 4
The Constant zero:
- 32개의 레지스터 중 가장 왼쪽 레지스터에는 0만 저장되어있다. ($zero)
add $t2 , $s1 $zero // 0은 항상 자주 쓰이므로 레지스터에 박아놓았다.
명령어들은 기계어로 인코딩된디.
MIPS 명령어들은 32비트 워드로 인코딩된다.
Register numbers: 총 32개이므로, 5비트로 표현가능하다.
- t7 : 8~15
rs는 사용X
레지스터 2개 사용하는 명령어들(immediate arithmetic and load/store instructions)
lw,sw(메모리에 접근하는 명령어) + imm(자주 쓰는 상수를 명령어에 넣어서 레지스터에 접근없이 바로 연산하는 명령어)
16비트로 만들수 있는 상수가 들어갈 수 있다.
직접적으로 명령어에 상수가 들어가있으면 레지스터를 엑세스 하지 않아도 되니 명령어 처리 속도가 더 빨라진다.
I 타입이 쓰이는 가장 중요한 이유: 레지스터가 아닌 메모리에 접근하여 어떤 값을 가져오거나 저장할 때 반드시 필요하다
즉, 직접적으로 주소값(=상수)이 immediate 부분에 와야한다.
하지만 16비트만 가지고 메모리 주소를 다 표현할수없다
여기서 사용하는 방식이 바로 displace addressing(변위 주소 지정) 방식이다.
rs가 가리키는 레지스터는 4바이트이기 때문에 4기가 바이트의 모든 주소에 접근할 수 가 있다.
그렇기 때문에 rs가 가리키는 레지스터의 값(=주소)을 기준으로 해서 immediate의 16비트로 표현할 수 있는 주소만큼 증가하거나 감소하여 변화를 줄수있다.
여기서 16($r18)이 의미하는 것은 $r18에 있는 주소값을 기준으로 16바이트를 더한 주소 값을 말한다.
beq, bne
opcode, two registers, target address
Most branch targets are near branch
- forward or backward
op | address |
---|---|
6bits | 26bits |
ex:
beq $s0,$s1,L1
// eotlsdp
bne $s0,$s1,L2
j L1
L2:
L1: // 16비트를 벗어날정도로 멀리있을때
왜 레지스터의 개수가 32개인지 학습한다.
C code:
int leaf_example(int g,int h,int i,int j){
int f;
f= (g+h)-(i+j);
return f;
}