본문 바로가기

카테고리 없음

컴퓨터구조(2) All about Instruction set

728x90
반응형

 

 

1. Introduction to instruction set

 

특정 machine에서 사용하는 어셈블리어, 머신 랭귀지의 어휘를 instruction set이라 한다. Computer language의 종류는 machine의 종류만큼 다양하다. 그러나 computer language들은 공통의 목적으로 만들어졌기에 매우 비슷하다. 공통의 목적이란, 성능(performance)은 최대로 비용(cost)은 최소로 하는 것이다. 최근에는 전력 소비(power consumption)도 주요 요인으로 작용한다. 

 

 

2. Instruction set 

 

(1) MIPS

내용

 

(2) ARM

내용    

 

(3) Three Operands

일반적으로 addition과 같은 artihmetic operations의 operands는 3개다. 2개의 source operands 및 1개의 destination operand로 구성되어 있다. MIPS와 ARN에서는 거의 모든 명령어들이 3개의 explicit operands를 사용한다. Operands는 Register, Memory, Instruction 3곳 중 한 곳에 위치한다. 위치하는 곳에 따라 분류 가능하다.

-> operands의 수가 3개로 고정된 이유는? By principle of hardware design(내용 설명하자 ~~), 하드웨어를 간단하게 하기 위해서다. 

 

(4) Registers

CPU 안에 존재하는 저장 장소(storage element)를 의미한다. Access 속도가 가장 빠른 저장 장소, 제한된 수만큼 존재한다. 명령어에 의해 직접적으로 읽고 쓰기가 가능하다. (Program-visible) 프로그램 수행 중 variables 또는 임시 데이터를 저장하는데 사용된다. 하드웨어 관점에서 레지스터란 래치 또는 플리플롭의 그룹으로 구현된다. register file(register array)란 CPU 안에 있는 여러 개의 register로 구성된 array를 말한다.

 

구분 MIPS ARM
General-purpose registers 32개(r0-r31)의 32-bit register 16개(r0-r15)의 32-bit register
  $s0-$s7 : C 또는 Java와 같은 high-level language에서의 변수에 해당  
  $t0-$t9 : Compile 과정에서의 임시 결과를 저장하기 위한 register  
PC(Program counter) 32bits 32bits, r15가 보통 PC로 사용됨
기타(HI and LO registers) 곱셈 나눗셈 명령어에서 사용됨,
2개의 32-bit special registers 
 

 

위의 표는 MIPS와 ARM의 레지스터에 관한 표다. 32bits는 MIPS architecture에서의 word, ARM architecture에서의 word이다. COmputer가 한 번에 인식하고 처리할 수 있는 bits의 그룹을 word라고 한다.

-> MIPS와 ARM에서 32개의 레지스터만 존재하는 이유는? By Design Principle 2, 레지스터에 대한 access 속도를 빠르게 하기 위해서다. 레지스터 수가 적을수록 하드웨어가 빨라지고, 레지스터 수가 많을수록 프로그래밍이 쉬우므로 적절한 balance를 맞추자. 

-> MIPS는 arithmetic instructions에서 registers operands만을 사용한다. 2개의 source registers로부터 입력(input) operands를 읽은 후, 덧셈 또는 뺄셈 후 그 결과(output) operand를 destination register에 저장한다. 

 

(5) Memory Operands

Structure 또는 array와 같은 복잡한 데이터 구조(data structure)는 Memory에 저장한다. (제한된 수의 레지스터에 이러한 값들을 저장할 수 없다.) Memory란 a sequence i which 8-bit registers are arranged이다. 

각 memory location에 할당된 memory address를 사용하여 memory operands를 access할 수 있다. 2k memory locations를 access하기 위해서는 최소한 k-bit address가 필요하다. 반대로 k-bit address가 존재한다면 2k memory locations까지 access할 수 있다. 즉, Address space가 2k의 크기를 가지는 것이다. 

 

구분 MIPS ARM
address 32-bit address 32-bit address
address space 232 memory locations 232 memory locations

 

Memory address and data

 

Memory Operand의 address에 대해 더 자세히 알아보자. Memory에서 addressing의 기본 단위는 byte이다. multi-byte operand의 address는 Operand를 이루는 byte들 중에서 address 값이 가장 작은 것의 address를 선택한다. 이때 Endian이란 데이터를 메모리에 저장하고 읽는 방식을 나타내는 개념으로 [1] big endian은 시작 주소가 MSB에 저장되어 점점 주소 값이 커지는 형태이고,  [2] little endian은 시작 주소가 LSB에 저장되므로 점점 주소 값이 작아지는 형태다. 

 

 

(6) Data Transfer Instructions

MIPS arithmetic instructions는 registers만을 operands로 사용한다. Memory에 존재하는 operands에 대해 연산을 수행하기 위해서는 memory 및 registers 사이에서 data를 전달해주는 instruction이 필요하다. 오직 data transfer instruction(load와 store)만이 memory를 access할 수 있고, 그 외의 명령어들은 registers 또는 immediate data operands만을 사용하는 것을 load-store architecture라고 한다. 

memory에서 register로 data를 전달하는 것이 Load, register에서 memory로 data를 전달하는 것이 store이다. MIPS에서는 lw, sw 명령어를 사용하고 ARM에서는 LDR, STR 명령어를 사용한다. 

 

(7) Constant(Immediate) Operands

상수의 쓰임은 MIPS와 ARM이 약간 다르다. Design Principle 3에 의해 작동한다. 아래 예시를 보자.

 

구분 MIPS ARM
덧셈(add, ADD) lw $t0, AddrConstant4($s1)
add $s3, $s3, $t0
ADD r3, r3, #4
덧셈(addi) addi $s3, $s3, 4  

 

(8) 진법 체계

우리는 10진법을 사용한다. 십진법에서 100, 101, 102, 103 등을 weight(가중치)라고 한다. 또한 10을 radix(base)라고 한다. 또한 Positional number system은 Weight가 digit의 위치에 의해서 결정되는 숫자 시스템을 의미하는데, 2진법, 8진법, 10진법, 16진법 등이 이에 해당한다. 10진법은 Digital system에서 사용하기 어렵다. 디지털 시스템은 2진수(Binary numbers)로 표현하기 때문이다.

음수를 표현하는 방법은 크게 두 가지가 있다. [1] 1의 보수법은 2진수의 값들을 단순히 반전(inversion)시키면 된다. 00112의 1의 보수는 11002이다. [2] 2의 보수법은 1의 보수법을 시행한 후 12을 더하면 된다. 00112의 2의 보수는 11012이다.  

아래 보수법 표현을 알기 위해선 Signed, Unsigned를 구별할 줄 알아야 한다. Unsigned number는 양수 및 0만을 표현할 수 있다. 즉 nonnegative number만을 표현하는 수를 의미한다. 반대로 양수, 0, 음수를 모두 표현하는 수를 Signed number라고 한다. 밑의 보수법 표현은 모두 Signed number system이다. Signed number를 표시하기 위해선 MSB(most significant bit)가 중요하다. 이 bit가 양음을 나타내는데, MSB = 0이면 양수를, MSB = 1이면 음수를 의미한다. 

-> One's Complement Representation : 2개의 0(00002, 11112). 01112(+7)과 10002(-8) 사이 1개의 불연속 경계. Two's Complement Representation : 1개의 0(00002). 01112(+7)과 10002(-8) 사이 1개의 불연속 경계. Addition/Substraction이 unsigned number와 동일하게 이루어진다.

-> sign extension이란 MSB의 값을 왼쪽으로 무한정 확장하더라도, 그 전체 값은 변하지 않는다는 말이다. 1001도 십진수로 -7이고, 1111001도 십진수로 -7이다. 그 이유는 MSB의 weight만 음수 취급하고, 다른 bit들의 weight는 양수 취급하여 십진수로 변환하기 때문이다. 

 

Comparison of Signed Number systems

 

(9) Shift Operations

정해진 길이의 이진수를 전체적으로 왼쪽 또는 오른쪽으로 이동시키는 것, 보통 3가지의 shift 동작으로 분류된다. [1] Left shift는 수를 전체적으로 왼쪽으로 shift하고, 비워지는 LSB(least significant bit)들을 0으로 채운다. k-bit만큼 left shift하는 것은 2k를 곱하는 것에 해당한다. [2] Logical right shift는 수를 전체적으로 오른쪽으로 shift하고, 비워지는 MSB bit들은 0으로 채운다. k-bit만큼 logical right shift하는 것은 unsigned number를 2k로 나누는 것에 해당한다. [3] Arithmetic right shift는 수를 전체적으로 오른쪽으로 shift하고, 비워지는 MSB bit들은 MSB를 복사해서 채운다. k-bit만큼 arithmetic right shift하는 것은 2의 보수 숫자를 2k로 나누는 것에 해당한다. 

(ex) 11101을 2-bit left shift : 10100

(ex) 10100을 2-bit logical right shift : 00101

(ex) 10100을 2-bit arithmetic right shift : 11101

 

(10) Biased Notation

Biased Notation이란 signed number를 표시하는 또 하나의 방법으로, floating-point 표기법에서 지수(exponent)를 표현할 때 자주 사용된다. +A를 구하고 싶으면 bias + A를, -A를 구하고 싶으면 bias - A를 수행하면 된다. 참고로, bias는 숫자 0의 표현에 해당하는 값이다.  

 

 

3. Instruction formats

 

(1) Stored Program Concept

Instruction들과 data는 memory에 number로 저장된다. Computer에서 number는 on(logic 1, high voltage) 및 off(logic 0, low voltage)의 신호들에 의해서 표현된다. 즉 Computer에서 instruction들은 binary number로 존재한다. 

 

모든 프로그램들, data들은 이진수의 형태로 존재 !

 

(2) Instruction Format

특정 의미를 갖는 machine instruction의 segment를 field라고 한다. Insturction field란 5 또는 6비트로 이루어진 각각의 segment이다. 이렇게 field들로 구성된 instruction의 layout을 instruction format이라고 한다. 

명령어 길이에 따라 크게 두 가지로 분류하는데, [1] Variable-length instruction은 하드웨어가 복잡해지지만 컴팩트한 명령어 세트가 허용된다. [2] Fixed-length instruction은 하드웨어가 간편하지만 Instrution bit의 압박이 있다. MIPS와 ARM, SPARC, PowerPC 등은 모두 [2]에 속한다. 

 

구분 CISC RISC
  Complex Instruction Set Computer Reduced Instruction Set Computer
Insturction length variable-length insturctions fixed-length instructions
Memory access instructions memory operands are
part of any operation
memory operands are
only in loads or stores
Register operands register operands are in many places
in insturction format
registers are located in same place

 

(3) MIPS Instruction Format 

R-Type은 아래와 같다. op는 OP code를, rs는 첫 번째 레지스터, rt는 두 번째 레지스터, rd는 목적 레지스터이다. shamt는 shift한 양을 나타내며(아직은 안 쓰임), funct는 함수 코드를 의미한다. 

 

 

위의 타입만 사용할 경우, 5-bit field를 offset으로 사용할 수 있지만 offset의 크기가 25로 제한된다는 단점이 있다. design principle 4에 의해 Instruction length는 고정시키면서 Instruction format은 여러 가지로 하는 다른 타입도 사용하자. I-Type은 lw, sw, addi 등의 insturction들이 사용하는 format을 보여주는 타입이다. op는 OP code를, rs는 베이스 레지스터, rt는 변형될 레지스터, immediate는 16비트의 상수(in addi) 혹은 address offset(in lw/sw)를 의미한다. 

 

 

(4) ARM Instruction Format 

DP format은 data processing format으로 ADD/SUB 등에 해당하는 타입이다. Cond는 branch instruction에 필요한 condition이고, F는 Instruction format을 지정하는 값, I는 Operand 2가 immediate인지 register인지를 결정한다. S는 Condition code flags를 업데이트할 지를 결정하며, Opcode, Rn은 첫번째 레지스터, Rd는 목적 레지스터다. Operand2는 second register source operand를 의미하며, 두 가지 경우가 가능하다. (표로 설명)

 

구분 I = 0인 경우 I = 1인 경우
  8 bits : 0
4 bits : Rm(Second reg source operand)
12bits : Constant

 

DT format은 LDR/STR의 형식을 보여주며, Cond는 Condition을, F는 Insturction format을 지정하는 값, Opcode, Rn은 베이스 레지스터, Rd는 목적 레지스터(in LDR) 혹은 변형될 레지스터(in STR)를 의미하고 Offset12는 12-bit의 address offset을 의미한다. 

 

 

(5) Examples

 

구분 MIPS ARM
C code A[300] = h + A[300]; A[300] = h + A[300];
assembly code lw $t0, 1200($t1)
add $t0, $s2, $t0
sw $t0, 1200($t1)
LDR r5, [r3, #1200]
ADD r5, r2, r5
STR r5, [r3, #1200]
machine code 이야.. 길다 ! 너도.. 길다 !

 

MIPS machine code(이야.. 길다 ! 의 표)

 

ARM machine code(너도.. 길다 ! 의 표)

 

(6) Logical Instructions

Lofical Instructions는 한 단어 내의 비트 필드 또는 개별 비트에서도 작동하는 명령어다. [1] MIPS의 경우 항상 0의 값을 갖는 레지스터 $zero와 NOR를 사용하여 Logical NOT을 구현한다. Shift instructions는 sll과 srl을 사용하며 R-type의 rs 필드는 0이다. [2] ARM의 경우, 명령어 MVN을 사용하여 Logical NOT을 구현하며, Dp format의 Rn은 0이다.  Shift operation으로는 MOV, LSL, LSR을 사용하며, Dp format의 Rn은 0이다. 

 

구분 MIPS ARM
C code reg $t0 = reg $t1 & reg $t2;
$t0 = ~($t1 | $zero) = ~($t1 | 0) = ~ $t1;
reg $t2 = reg $s0 << 4 bits
r5 = r1 | 100;
r5 = ~r1;
r6 = r5 >> r3;
assembly code and $t0, $t1, $t2
nor $t0, $t1, $zero
sll $t2, $s0, 4
ORR r5, r1, #100
MVN r5, r1
MOV r6, r5, LSR r3
machine code 이야.. 길다 ! 너도.. 길다 !

 

DP Format의 Operand2 필드에 대해 정확히 알아보자. 아래 그림을 참고하자. 

 

 

(7) Branches, Condition Codes

컴퓨터는 단순 계산기들과 다르게 '판단'이 가능하다. if statement, loops(while, for 등)을 사용하여 수행할 수 있다. [1] Conditional branch는 if statement과 goto를 합친 기능을 수행하며, [2] Uncontional branch는 goto에 해당한다. 

 

MIPS에선 2개의 conditional branch인 beq, bne가 있다. 이들은 I-type이다. 그리고, I-type에서 immediate field에 대해 자세히 알아보자. 거의 모든 조건부 분기가 PC에서 짧은 거리에 있다. immediate는 현재 PC와의 거리를 의미한다. [1] 명령어는 32bits, 4 bytes, 1 word라서 Address는 항상 4의 배수여야만 한다. 또한 distance = immediate x 4이다. [2] Branch는 항상 forward 방향일까? 아니다. immediate는 부호가 있는 +- 215 words라고 보면 된다. 따라서 분기 대상이 그것 이내다. 

-> 84쪽을 이해하거라 ~!

 

beq $r1, $r2, L r1 = r2면 L로 표시된 명령으로 이동하라. 
bne $r1, $r2, L r1 != r2면 L로 표시된 명령으로 이동하라.

 

MIPS의 Unconditional branch, 즉 무조건적으로 branch하는 명령어에는 j가 있다. 이는 J-type으로 op(6bits), low address(26bits)로 존재한다. 'j L'이라 함은 무조건 L로 라벨된 명령어로 이동하라는 의미다. 어,, 근데 address 32bit인데 J-type의 low_address는 6bits 모자라네?? 어떡하지?? [1] 26bits의 오른쪽에 2bits의 00을 붙인다. (Word-alignment) 그러면 4bits가 부족하다. [2] current PC의 최상위 4bits를 사용한다. 

 

 

MIPS에서 +- 215 words 이상 떨어진 곳으로 conditionally branch할 경우, j와 conditional instruction을 섞어 사용하자. 방법은 두 가지다. [1] Original conditional branch 다음에 unconditional jump를 삽입한다. 이럴 경우 타겟은 원래 조건부 브랜치의 타겟으로 설정한다. [2] Conditional branch instruction의 condition을 반대로 한다. 이 경우, 브랜치 타겟은 unconditional jump 다음으로 설정한다. 

 

수정 전 수정 후
beq $s0, $s1, L1    bne $s0, $s1, L2
   j L1
L2:

 

ARM의 경우, 2개의 conditional branch인 BEQ, BNE가 있으며 이들은 CMP 명령어와 같이 사용된다. CMP reg1, reg2 인 경우 reg1에서 reg2를 빼고 그 결과가 0인지 아닌지 등을 바탕으로 condition code flags를 업데이트한다. 브랜치 명령어는 이러한 플래그들을 보고 비교 결과를 알 수 있다. 

-> ARM의 condition code flags는 CPSR(Current Program Status Register)이라고 하며, 크게 4가지 정보를 담고 있다. [1] N은 CPSR[31]이며, 연산 결과가 signed로 해석했을 때에 음수면 1, 양수면 0이다. 연산 결과의 bit 31과 같은 값을 가지는 셈이다. [2] Z는 CPSR[30]이며, 연산 결과가 0(zero)면 1, 0이 아니면 0이다. [3] C는 CPSR[29]며, 덧셈에 의해 carry가 발생 혹은 뺄셈에 의해 borrow가 발생하지 않은 경우에 1, 덧셈에 의해 carry가 발생하기 않은 경우 혹은 뺄셈에 의해 borrow가 발생한 경우에 0이다. [4] V는 CPSR[28]이며, signed overflow가 발생하면 1, 발생하지 않으면 0이다. 

-> Condigion code flags는 ARM의 DP format의 S field로부터 사용 여부를 알 수 있다. S = 0인 경우, 본래의 주어진 data processing을 수행한다. S = 1인 경우 본래의 주어진 것 외에 그 결과에 따라 condition flags를 업데이트한다. condition flags를 업데이트하는 명령어들에는 ADDS, SUBS, MOVS, ANDS, ORRS, MVNS, CMP 등이 있다. 위 명령어들은 모두 S 필드가 1인 셈이다. -> CMP과 SUBS의 차이점은? 

-> 참고로, CMP는 DP format이다. BEQ와 BNE는 Cond(4bits), 101(3bits), L(1bit), Signed_immed_24(24bits)로 구성된다. 또한 L은 항상 0이다. 그리고 PC-relative addressing을 사용하여 아래 공식이 성립한다. 

 

 

CMP reg1, reg2
BEQ L1
reg1 = reg2면 L1으로 이동하라. 
CMP reg1, reg2
BNE L1
reg1 != reg2면 L1으로 이동하라.

 

다양한 브랜치들... 와 이거 언제 다 외우냐 ...

 

ARM에서의 Conditional Execution에 대해 좀 더 알아보자. ARM의 거의 모든 명령어들은 Cond 필드가 존재하며, 그 값에 따라 해당 명령어는 특정 조건에서만 실행된다. 예를 들어 덧셈의 Cond 필드가 0000(EQ)이면, ADDEQ라는 명령어가 되고, Z 플래그가 1인 경우에만 실행되는 것이다. 이는 ARM의 고유 특성으로서, 브랜치를 없앨 수 있다는 장점을 가진다. 

 

구분 MIPS ARM
C code if (i == j) f = g + h;
else f = g – h;
if (i == j) f = g + h;
else f = g – h;
assembly code    bne $s3, $s4, Else
   add $s0, $s1, $s2
   j Exit
Else: sub $s0, $s1, $s2
Exit:
   CMP r3, r4
   BNE Else
   ADD r0, r1, r2
   B Exit
Else: SUB r0, r1, r2
Exit:
assembly code2 X CMP r3, r4
ADDEQ r0, r1, r2
SUBNE r0, r1, r2

 

 

(8) Jump Register

256MB 범위 밖의 address로의 jump가 필요하다. 즉, 현재 PC 값에 상관 없는 32-bit absolute address 지정이 필요하다. [한계] Return address는 어디에서 porcedure를 call 했는지에 따라 달라진다. [한계2] 프로그램 수행 중 PC와 immediate는 변경되지 않는다. 즉, 타겟의 주소는 고정된다. 이를 해결하고자 switch, case 문법을 사용한 jump address table이 고안되었다. 

MIPS는 'jr'을 사용하고, 이는 R-type format이다. (90쪽 이해 잘 해보자) 

 

C 문법 MIPS
switch (k) {
   case 0: ① statements; break;
   case 1: ② statements; break;
   case 2: ③ statements; break;
   case 3: ④ statements; break;
}
sll $t1, $s5, 2                  # $t1 = 4*k
add $t1, $t1, $t4
lw $t0, 0($t1)
jr $t0

 

ARM은 'MOV'를 사용하여 jump register를 구현한다. pc(r15)가 general-purpose register이므로 MOV의 목적지 레지스터로 사용될 수 있다. pc를 사용하면 ARM의 거의 모든 명령어들이 브랜치 효과를 가질 수 있다. 

 

(9) Procedures

Proceduresubroutine, function이라고도 부르며 특정 작업(task)을 수행하기 위한 명령어 그룹이다. 이들은 Main 프로그램과 별도로 작성되며, 한 번 만들어두고 그걸 반복적으로 수행하는 원리다. main에서 명령어들을 중복으로 쓸 필요가 없게 된다. 즉, Memory의 효율적인 사용이 가능하다. 주의점으로, 작업을 마치고 돌아왔을 때에는 '지시된 것 외에는 상태 변화가 없어야' 한다. 아래와 같은 단계로 수행된다. 

 

1. Input arguments, parameter의 설정
-> register (MIPS에서는 $a0 ~ $a3) 또는 stack에 설정한다.
-> Input arjuments가 어디에 있는지는 메인과 함수 모두 알아야 한다. 

2. Program sequence를 procedure로 바꿈
-> 돌아올 주소(return address)를 $ra에 저장한다. 
-> jal(call) 명령어를 사용하자. 

3. Local variables 설정 및 변경될 registers 저장
-> Stack을 사용하여 작업을 수행한다. 

4. Procedure 작업 수행

5. Output arguments 설정
-> register (MIPS에서는 $v0 ~ $v1) 또는 stack에 설정한다.
-> Output arjuments가 어디에 있는지는 메인과 함수 모두 알아야 한다. 

6. 중단되었던 main program 위치로 Program sequence를 변경
-> jal(call) instruction 다음 명령어부터 다시 시작한다. 
-> jr $ra 명령에 의해 수행된다.

 

 MIPS에선 jump-and-link 명령어로 'jal PrAddr'을 사용한다. 이는 J-type으로, 돌아올 return address를 $ra에 저장하면서 프로그램 순서를 procedure로 변경한다. 함수 작업을 마치고 원래 위치로 돌아올 때는 'jr $ra'를 사용한다. 정리하자면 [1] Input argument는 $a0 ~ $a3까지, register 4-7을 사용하고, [2] Output argument는 수행된 작업의 결과를 caller에게 돌려주기 위한 목적으로 $v0 ~ $v1까지, register 2-3을 사용한다. [3] Return address register는 $ra이며, 이는 register 31이다. 'jal' 명령어에 의해 리턴 주소가 $ra에 자동으로 저장되며, 'jr $ra' 명령을 수행하는 순간 함수는 자동 종료된다. 

-> procedure는 특정 위치에서만 call되는 것이 아니다. 즉, 돌아갈 주소가 그때 그때 다르므로 j 대신에 jr을 사용한다. 

ARM에선 Branch-and-Link 명령어로 'BL PrAddr'을 사용한다. 이는 Cond(4bits), 101(3bits), L=1(1bit), Signed_immed_24(24bits)로 구성되며 돌아올 return address를 r14에 저장하면서 프로그램 순서를 procedure로 변경한다. 함수 작업을 마치고 원래 위치로 돌아올 때는 'MOV pc, r14'를 사용한다. 정리하자면 [1] Input argument는 a1 ~ a4까지, register 0-3을 사용하고, [2] Output argument는 수행된 작업의 결과를 caller에게 돌려주기 위한 목적으로 a1 ~ a2까지, register 0-1을 사용한다. [3] Return address register는 lr(r14)이며, 이는 register 14이다. 'BL' 명령어에 의해 리턴 주소가 lr에 자동으로 저장되며, 'MOV pc, lr' 명령을 수행하는 순간 함수는 자동 종료된다. [4] Stack pointer register는 현재 stack이 어디까지 성장해 있는지를 알려주는 register로, sp(r13)이다. 

 

(10) Stack

프로그램의 메모리 영역은 아래 그림처럼 크게 4개 구역으로 나뉜다. [1] Text는 machine instructions가 저장되는 부분이고, [2] Static data는 상수 데이터 또는 정적 변수가 저장되는 부분이다. c언어의 전역 변수 등이 저장된다. [3] Heap는 Linked lists와 같은 동적 데이터(Dynamic data)가 저장되는 부분으로 c언어의 malloc(), calloc(), free() 함수 등을 생각하면 된다. [4] Stack은 Procedure 수행을 위한 data를 저장하는 부분이다. 

 

 

즉, Stack에는 procedure 수행과 관련된 data들이 저장된다. [1] Procedure arguments, 입출력을 비롯한 값들이 저장된다. 물론 $a0~$a3, $v0~$v1 등의 레지스터가 존재하지만, arguments가 많을 경우 stack을 이용하기도 한다. [2] 함수 내에 사용되는 Local variables가 저장된다. [3] Microprocessor register values, 함수 수행 중에 변경되지 않아햐 하는 registers를 불가피하게 변경할 경우에는 Stack에 해당 레지스터의 값을 저장하고(spill), 나중에 리턴 직전에 그 값들을 읽어와 원래의 register에 복구한다. 

Stack에서 data를 저장하는 것을 push라 하고, data를 제거하는 것을 pop이라 한다. Stack은 LIFO다. 

 

 

현재 stack이 어디까지 성장해 있는지를 알려주는 것을 stack pointer라고 한다. stack pointer는 stack의 top location을 가리키며, 이를 저장하기 위한 별도의 레지스터가 존재한다. Stack에 data를 읽고 쓸 용도로서 stack pointer가 존재한다. push할 경우 stack pointer가 감소, pop할 경우 stack pointer가 증가한다. MIPS의 stack pointer는 $sp로, register 29다.  --> 116쪽은 담에 ~

 

C 문법 MIPS
int leaf_example (int g, int h, int i, int j) {
   return ((g + h) – (i + j));
}
leaf_example:
   addi $sp, $sp, -12
   sw $t1, 8($sp)
   sw $t0, 4($sp)
   sw $s0, 0($sp) 
   add $t0, $a0, $a1
   add $t1, $a2, $a3
   sub $s0, $t0, $t1            # (g + h) – (i + j)
   add $v0, $s0, $zero       # return value
   lw $s0, 0($sp)
   lw $t0, 4($sp)
   lw $t1, 8($sp)
   addi $sp, $sp, 12
   jr $ra

 

 

(11) Nesting Procedures 

call 되는 procedure가 다시 새로운 procedure를 call 할 수 있으며, 이러한 것을 nesting이라고 한다. [1]  Leaf procedures는 또 다른 procedure를 call하지 않는 procedure를 일컫는 용어다. 반대로 [2] Nonleaf procedures는 또 다른 procedure를 call하는 procedure로, 또다시 콜 하기 전에 레지스터 상태 보전을 위해 추가적인 주의가 필요하다. 예를 들어, $ra는 또 다른 함수를 호출할 때 값이 변경되므로 사전에 저장할 필요가 있다. argumetn register들도 마찬가지다. 그 외에도 temporary register들의 값을 보존할 필요가 있을 때에는 메모리에 보관한 후, 또 다른 함수를 콜해야 한다. 

 

C 문법 MIPS
int nonleaf (int g) {
   return (square (g + 1) – g);
}
nonleaf:
   addi $sp, $sp, -8
   sw $ra, 4($sp)
   sw $a0, 0($sp)
   addi $a0, $a0, 1        # g + 1
   jal square 
   lw $a0, 0($sp)
   lw $ra, 4($sp)
   addi $sp, $sp, 8
   sub $v0, $v0, $a0 
   jr $ra
square:

 

(12) Procedure Frame and Frame Pointer

특정 Procedure와 관련된 data를 저장하고 있는 segment of stack을 그 procedure의 frame이라고 한다. Frame pointer($fp in MIPS)는 register 30이며, 값이 계속 변하는 stack pointer에 비해 Local variable을 access할 때 편리하다. 

 

 

4. 추가 Instructions

 

130쪽 부터 

 

 

 

 

 

 

 

명령어 포맷(mips, arm 각 2개씩)

논리명령어, if문, 점프문, 플래그, procedure, 스택, 

 

 

 

 

 

 

 

 

 

 

 

1) Design Principle 1 : 

2) Design Principle 2 : Smaller is faster

3) Design Principle 3 : Make the common case fast

4) Design Pringciple 4 : Good design demands good compromises

-> 참고 : 소수 다룰 때 Biased Notation(53쪽)을 참고하자 !!

 

 

 

 

728x90
반응형