Fallacy: More powerful instructions mean higher performance. Fewer instructions required But complex instructions are hard to implement May slow down all instructions, including simple ones Compilers are good at making fast code from simple instructions Fallacy: Write in assembly language to obtain the highest performance. But modern compilers are better at dealing with modern processors More li..
ARM이나 MIPS, RISC-V보다 강력한 연산을 제공하는 Instruction set도 있다. 프로그램이 실행하는 명령어의 개수를 줄이는 것에 목표를 두지만, 간결성을 희생한 대가로 얻어지는 것이다. 명령어의 개수를 줄였지만, 명령어 처리 시간이 길어져서 프로그램 실행에 걸리는 시간은 늘어날 위험이 있다. 이렇게 느려지는 이유는 Clock Cycle Time이 길어지거나 필요한 Clock Cycle Count가 더 많아지기 때문이다. The Intel x86 ISA ARM과 MIPS는 1985년에 작은 연구팀이 만든 것이다. 이 프로세서의 각 부분은 조화를 잘 이루고 있으며 구조도 아주 간결하다. 그러나, x86은 여러 독립적인 그룹이 40년 이상 꾸준히 발전 시킨 것이다. Intel은 마치 짐가방에..
ARM은 임베디드용으로는 가장 인기 있는 Instruction set architecture로 MIPS와 같은 해에 나왔으며 같은 설계 철학을 따르고 있다. 두 프로세서는 아래 표와 같이 매우 유사하다. 가장 큰 차이는 MIPS는 레지스터가 더 많고 ARM은 Addressing mode가 많다는 점이다. Addressing Mode 위 표는 ARM이 지원하는 데이터 Addressing mode를 보여 주고 있다. MIPS와 달리 ARM에는 상수 0을 갖고 있는 레지스터가 있다. MIPS는 3개의 단순한 데이터 addressing mode를 갖고 있는 데 반해 ARM은 9개를 갖고 있다. Compare and Conditional Branch Conditional Branch 여부를 판단하기 위해 MIPS..
Comparison of Array vs. Pointer 배열을 사용하면 새 인덱스 값을 계산해야 하므로 곱셈과 덧셈을 해야 한다. 포인터를 사용하면 p를 직접 증가시킨다. 배열의 마지막 주소 계산을 반복문 바깥으로 빼냄으로써 명령어를 줄였다. 곱셈 대신 자리이동과 배열 주소 계산을 반복문에서 제거함으로써 최적화를 했다. C에서 포인터를 이용하면 배열을 이용하는 것보다 더 효율적이니 포인터를 이용하라고 가르치는 경우가 많다. 그러나 요즘 최적화 컴파일러는 배열을 사용한 코드에 대해서도 똑같이 좋은 코드를 생성할 수 있다.
C swap function void swap(int v[], int k) { int temp; temp = v[k]; v[k] = v[k+1]; v[k+1] = temp; } v in $a0, k in $a1, temp in $t0 MIPS는 Byte address를 사용하므로 각 워드는 실제로 4바이트씩 떨어져 있다. 그러므로 인덱스 k를 주소에 더하기 전에 4를 곱해야 한다. 순차적인 워드 주소가 1이 아니고 4씩 차이가 나는 것을 반드시 기억해야 한다. 따라서 v[k]의 주소를 구하기 위해서 처음 해야 할 일은 k에 4를 곱하는 것이다. sll$t1, $a1, 2# reg $t1 = k * 4 add$t1, $a0, $t1# reg $t1 = v + k * 4 # reg $t1 has the ad..
Compiler Compiler 컴파일러는 C 프로그램을 어셈블리 언어 프로그램으로 바꾼다. 어셈블리 언어 프로그램은 컴퓨터가 이해할 수 있는 명령의 기호 형태이다. 상위 수준 언어 프로그램은 어셈블리 언어보다 문장 수가 훨씬 적으므로 프로그래머의 생산성이 높아진다. 1975년 당시에는 메모리가 부족하고 컴파일러가 비효율적이었기 때문에 운영체제와 어셈블러는 어셈블리 언어(assembly language)로 작성하였다. 그러나 오늘날에는 DRAM 칩의 용량이 수백만 배나 커져서 프로그램 크기 문제도 완화되었다. Assembler Assembler Pseudoinstruction Assembly Language 어셈블리 언어는 상위 수준 소프트웨어와의 인터페이스이므로 원래는 없는 명령어를 어셈블러가 독자적으..
32-Bit Immediate Operands 프로그램에서 사용하는 상수는 대체로 크기가 작다. -> 대부분 16비트 필드면 충분하지만 때에 따라서는 더 큰 상수가 필요한 경우도 있다. MIPS는 레지스터의 상위 16비트에 상수를 넣는 lui(load upper immediate) 명령어를 제공한다. -> Copies 16-bit constant to left 16 bits of rt -> Clears right 16 bits of rt to 0 lui를 이용해서 상위 16비트를 채운다. ori를 이용해서 하위 16비트를 채운다. Addressing in Branches and Jumps Jump Addressing jump 명령어는 가장 간단한 주소 지정 방식 6비트의 op 코드와 26비트의 주소 필드..
대부분의 컴퓨터는 8비트 바이트로 문자를 표현하며, 거의 모든 컴퓨터가 ASCII를 사용한다. 명령어 몇 개를 사용하면 워드 내의 특정 바이트를 추출할 수 있다. 그러므로 lw와 sw은 워드뿐 아니라 바이트 전송에도 충분히 사용할 수 있다. 하지만 텍스트 데이터를 다루는 프로그램이 많기 때문에 효율성을 위해서 MIPS에는 바이트 전송 명령어가 따로 있다. lb(load byte) 메모리에서 한 바이트를 읽어서 레지스터의 오른쪽 8비트에 채우는 명령 sb(sotre byte) 레지스터의 오른쪽 8비트를 메모리로 보내는 명령 lb rt, offset(rs) lh rt, offset(rs) Sign extend to 32 bits in rt lbu rt, offset(rs) lhu rt, offset(rs) ..
Supproting Procedures in Computer Hardware 프로시저(Procedure)나 함수는 이해하기 쉽고 재사용이 가능하도록 프로그램을 구조화하는 방법 중의 하나이다. 프로시저는 프로그래머가 한 번에 한 부분씩 집중해서 처리할 수 있게 해 준다. 인수(Parameter)는 프로시저에 값을 보내고 결과를 받아 오는 일을 하므로, 프로그램의 다른 부분 및 데이터와 프로시저 사이의 인터페이스 역할을 한다. 프로시저는 소프트웨어에서 추상화를 구현하는 방법 중의 하나이다. Procedure Calling 프로그램이 프로시저를 실행할 때 다음과 같은 여섯 단계를 거친다. 프로시저가 접근할 수 있는 곳에 인수를 넣는다. 프로시저로 제어를 넘긴다. 프로시저가 필요로 하는 메모리 자원을 획득한다...
Conditional Operations 프로그래밍 언어에서는 보통 if문장으로 판단 기능을 표현한다. beq reg1, reg2, L1 reg1과 reg2의 값이 같으면 L1에 해당하는 statement로 가라는 뜻이다. beq는 branch if equal을 의미한다. bne reg1, reg2, L1 reg1과 reg2의 값이 같지 않으면 L1으로 가라는 뜻이다. bne는 branch if not equal을 의미한다. beq와 bne 두 명령어를 조건부 분기(conditional branch)라 부른다. Compiling if Statements 다음 코드에서 f, g, h, i, j는 변수이고, 각각은 레지스터 $s0부터 $s4까지에 해당한다. if (i==j) f = g+h; else f = ..
비트들을 워드로 묶는(packing) 작업과 워드를 비트 단위로 나누는 (unpacking) 작업을 간단하게 하는 명령어들이 프로그래밍 언어와 명령어 집합에 추가되었다. 이러한 명령어들을 논리 연산 명령어라 부른다. Shift Operation Shift 연산 워드 내의 모든 비트를 왼쪽 또는 오른쪽으로 이동시키고, 이동 후 빈자리는 0으로 채운다. sll (shift left logical) 비트들을 왼쪽으로 이동시키고 원래 있던 자리는 0으로 채운다. 2를 곱한 것과 같은 결과다. srl (shift right logical) 비트들을 오른쪽으로 이동시키고 원래 있던 자리는 0으로 채운다. 2를 나눈 것과 같은 결과다. AND Operation AND 연산은 bit : bit 연산자로서 두 비트 값이..
거의 모든 명령어가 레지스터를 사용하기 때문에 레지스터 이름을 숫자로 매핑하는 규칙이 있어야 하는데 MIPS에서는 레지스터 $s0에서 $s7까지는 레지스터 번호 16~23번, $t0에서 $t7까지는 8~15번으로 매핑한다. 예제: MIPS 어셈블리 언어를 기계어로 변환 다음 어셈블리 명령어의 실제 MIPS 언어 버전을 십진수와 이진수 형태로 표현하라. add $t0, $s1, $s2 십진수 표현은 다음과 같다. 명령어의 각 부분을 필드(field)라 부른다. 처음과 마지막 필드(0과 32)가 컴퓨터에게 덧셈을 하라고 지시하는 부분이다. 두 번째 필드는 덧셈에 사용할 첫 번째 피연산자 레지스터의 번호(17 = $s1), 세 번째 필드는 두 번째 피연산자 레지스터 번호(18 = $s2), 네 번째 필드는 계..