오류 : 강력한 명령어를 사용하면 성능이 좋아진다. x86명령어가 강력한 이유 중 하나는 명령어 실행 방식을 변경하는 접두사를 가지고 있기 때문입니다. 접두사를 쓰지 않고 표준 명령어만 사용해서 데이터를 레지스터에 적재했다가 다시 메모리에 저장하는 방식을 사용할 수도 있습니다. 공평한 비교를 위해 순환문 오버헤드가 없도록 순환문으로 만들지 말고 명령어를 반복적으로 늘어놓는 방법을 쓰면 접두사를 쓴 것보다 더 빠릅니다. 오류 : 최고 성능을 얻기 위해 어셈블리 언어로 프로그램 작성하기 컴파일러의 눈부신 발전으로 어셈블리 프로그래머가 기계에 밀린다. 함정 : 바이트 주소를 사용하는 컴퓨터에서 인접 워드 간 주소 차이가 1이 아니라는 사실을 잊는것. 많은 어셈블리 프로그래머들이 주소를 하나 증가시키면 다음 워..
MIPS와 가장 비슷한 명령어 집합인 RISC-V도 대학에서 개발되었습니다. MIPS를 아는 사람은 RISC-V도 쉽게 배울 수 있습니다. 그러나 RISC-V는 기구에서 관리하는 개방형 구조로서, 특정 회사의 소유물이 아닙니다. RISC-V와 MIPS의 공통적 특징은 다음과 같습니다. - 두 구조의 명령어 길이는 모두 32비트 - 두 고조 모두 32개의 범용 레지스터를 갖고 있으며, 그중 하나는 항상 0으로 고정되어 있다. - 메모리 접근은 적재와 저장 명령어를 통해서만 가능하다. - 다른 구조들과 달리 다중 레지스터에 적재하거나 저장하는 명령어가 없다. - 두 구조 모두 레지스터가 0이면 분기하라는 명령어와 레지스터가 0이 아니면 분기하라는 명령어를 갖고 있다. - 주소지정 방식이 모든 데이터 크기에 ..
명령어집합의 여러 잠재적 문제점들 중에서 거의 극복하기 불가능한 문제 중 하나는 메모리 주소가 너무 작은 것입니다. x86은 16비트에서 32비트로, 나중에는 64비트까지 성공적으로 주소를 확장하였지만, 대부분의 다른 프로세서들은 이를 따라하지 못했습니다. ARM설계자들은 자신들의 32비트 주소 컴퓨터에 대한 비판을 인지하고 2007년에 설계를 시작해 2013년에 64비트 주소버전을 내놓았습니다. MIPS를 이해하고 있다면 64비트 버전인 ARMv8은 매우 쉽게 이해할 수 있습니다. 첫째로, MIPS에 없는 ARMv7의 이상한 특징들을 사실상 거의 다 없애 버렸습니다. - v7에서 거의 모든 명령어에 있던 조건부 실행 필드가 없어졌다. - v7에서 복잡한 과정을 거쳐 계산해야 했던 수치 필드를 단순한 1..
ARM은 임베디드용으로는 가장 인기 있는 명령어 집합 구조입니다. ARM은 원래 Acorn RISC Machine의 약자였는데 후에 Advanced RISC Machine으로 바뀌었습니다. ARM은 MIPS와 같은 해에 나왔으며 같은 설계 철학을 따르고 있습니다. 다음 그림은 두 프로게서 사이의 유사성에 대해 보여주고 있습니다. 가장 큰 차이는 MIPS는 레지스터가 더 많고 ARM은 주소지정 방식이 더 많다는 점입니다. 주소지정 방식 MIPS와 달리 ARM에는 상수 0을 갖고 있는 레지스터가 없습니다. MIPS는 겨우 3개의 단순한 데이터 주소지정 방식을 갖고 있는 반면 ARM은 9개의 주소지정 방식을 갖고 있으며 이 중에는 상당히 복잡한 계산을 하는 방식도 포함되어 있습니다. 예를들면 레지스터를 원하는..
프로그램 번역과 실행 이번 장에서는 비휘발성 저장장치 파일에 저장되어 있는 C프로그램을 컴퓨터가 실행할 수 있는 프로그램으로 변환하기 위한 4단계를 설명한다. 밑의 그림은 이러한 번역 단계를 계층적으로 보여줍니다. 어떤 시스템은 번역 시간을 줄이기 위해 이 중 몇단계를 하나로 합치기도 하지만, 논리적으로는 이 4단계를 거쳐야 합니다. 이 장에서는 번역 계층 에 따라 설명을 진행합니다. 컴파일러 컴파일러는 C프로그램을 엄셈블리 언어 프로그램으로 바꿉니다. 어셈블리 언어 프로그램은 컴퓨터가 이해할 수 있는 명령의 기호 형태입니다. 상위 수준 언어 프로그램은 어셈블리 언어보다 문장 수가 훨씬 적으므로 프로그래머의 생산성이 높아집니다. 1975년 당시에는 메모리가 부족하고 컴파일러가 비효율적이였기 때문에 운영체..
32비트 수치와 주소를 위한 MIPS의 주소 지정 방식 MIPS명령어의 길이를 32비트로 고정한 덕에 하드웨어가 간단해지기는 했지만, 명령어 내에 32비트 상수나 32비트 주소를 표시할 수 없어 불편한 점도 있다. 이 절에서는 32비트 상수 처리를 위한 일반적 해법을 제시하고, 이어서 32비트 명령어 주소를 분기나 점프 명령어 내에 표시하기 위한 최적화 방안을 보입니다. 32비트 수치 피연산자 대부분 16비트 필드면 충분하지만 대에 따라서는 더 큰 상수가 필요합니다. 이럴 때를 위해 MIPS는 레지스터의 상위 16비트에 상수를 넣은 lui(load upper immediate)명령어를 제공합니다. 하위 16비트는 그 다음에 나오는 다른 명령으로 채울 수 있습니다. 32비트 상수의 로딩 예 레지스터 $s0..
조건부 명령 if / else와 같은 Arm 명령어이다. CMP reg1, reg2 ; r1, r2를 비교해라 . 여기서 비교란 뺄셈을 하라는 의미이다. 만약 두 값이 같으면 두 값을 뺀값은 0이 될것이다. > zero flag BEQ L1 ; 이전 계산이 0이면 L1으로 분기하라 BNE L1 ; 이전 계산이 0이 아니면 L1으로 분기하라 B exit ; 무조건 분기 하라 C code if (i == j) f = g+h; else f = g-h Compiled ARM code CMP r3, r4 BNE Else ; go to Else if i != j ADD r0, r1, r2 = f = g+h(skipped if i != j) B Exit Else ; SUB r0, r1, r2 ; f = g + h (..
하드웨어 프로시저 지원 프로시저(procedure)나 함수는 이해하기 쉽고 재사용이 가능하도록 프로그램을 구조화하는 방법 중 하나입니다. 프로시저는 프로그래머가 한 번에 한 부분씩 집중해서 처리할 수 있게 해줍니다. 인수(parameter)는 프로시저에 값을 보내고 결과를 받아 오는 일을 하므로, 프로그램의 다른 부분 및 데이터와 프로시저 사이의 인터페이스 역할을 합니다. 프로시저는 소프트웨어에서 추상화를 구현하는 방법중 하나입니다. 프로그램이 프로시저를 실행할 때도 다음과 같이 여섯단계를 거칩니다. 1. 프로시저가 접근할 수 있는 곳에 인수를 넣는다. 2. 프로시저로 제어를 넘긴다. 3. 프로시저가 필요로 하는 메모리 자원을 획득한다. 4. 필요한 작업을 수행한다. 5. 호출한 프로그램이 접근할 수 있..
논리 연산 명령어 초기의 컴퓨터는 워드 전체에 대한 처리에만 관심을 가졌으나, 워드 내 일부 비트들에 대한 연산, 각각의 비트에 대한 연산도 필요하다는 것이 명백해졌습니다. 비트들을 워드로 묶는 패키징 작업과 워드를 비트 단위로 나누는 언패키징 작업을 간단하게 하는 명령어들이 프로그래밍 언어와 명령어집합에 추가되었습니다. 이러한 논리 연산 명령어라 지칭합니다. 이번시간에는 MIPS의 논리 연산을 보여줍니다. 1. shift 연산 워드 내의 모든 비트를 왼쪽 또는 오른쪽으로 이동시키고, 이동 후 빈 자리는 0으로 채웁니다. MIPS 자리이동 명령어의 실제 이름은 s11(shift left logical)과 sr1(shift right logical)입니다. 다음은 위의 연산을 수행하는 MIPS명령어이고 단..
명령어의 컴퓨터 내부 표현 거의 모든 명령어가 레지스터를 사용하기 때문에 레지스터 이름을 숫자로 매핑하는 규칙이 있어야 합니다. MIPS에서는 레지스터 $0에서 $7까지는 레지스터번호 16~23번까지로, $t0에서 $t7까지는 번호 8에서 15번까지 매핑합니다. MIPS 어셈블리 언어를 기계어로 변환 예) add $t0, $s1, $s2 다음 어셈블리 명령어의 실제 MIPS언어 버전을 십진수와 이진수 형태로 표현하라. 십진수 표현은 다음과 같습니다. 명령어의 각 부분을 필드(field)라 부릅니다. 처음과 마지막 필드는 더셈에 사용할 첫 번째 레지스터 번호, 세 번째 필드는 두 번째 피연산자 레지스터 번호를 나타냅니다. 네 번째 필드는 계산 결과가 들어갈 레지스터의 번호입니다. 이 명령어에서 다섯 번째 ..