티스토리 뷰

4.1 The Y86-64 Instruction Set Architecutre

 

4.1.1 Programmer-Visible State

Y86-64의 각 명령어들은 프로세서 상태의 어떤 부분을 읽고 수정할 수 있다.

프로그래머에게 보여지는 상태(programmer-visible state)라고 하며, 프로그래머는 어셈블리 코드로 프로그램을 작성할 수 있고 기계 수준의 코드를 생성하는 컴파일러를 작성할 수 있다.

 

15개의 프로그램 레지스터가 있다. (%rax, %rax, %rcx, %rdx, %rbx, %rsp, %rbp, %rsi, %rdi, and %r8 through %r14)

각 레지스터들은 64비트 word를 저장한다.

레지스터 %rsp는 push, pop, call, return 명령어를 이용하여 스택 포인터처럼 사용한다.

레지스터는 고정된 값이 없으며 세 가지의 단일 비트 조건 코드, ZF, SF, OF을 사용하여 가장 최근의 산술 또는 논리 명령어의 효과에 대한 정보를 저장한다.

PC는 가장 최근에 실행된 명령어의 주소를 가지고 있다.

메모리는 개념적으로 큰 바이트 배열로 프로그램과 데이터를 가지고 있다.

Y86-64 프로그램은 가상 주소(virtual address)을 사용하여 메모리 위치를 참조한다.

프로그램 상태의 마지막 부분은 상태 코드 Stat이며, 프로그램 실행의 전체적인 상태를 가리킨다.

 

4.1.2 Y86-64 Instructions

명령어 집합을 프로세서 구현의 목적처럼 사용한다.

Y86-64 명령어 집합은 x86-64 명령어 집합의 부분집합이다.

이는 적은 addressing mode를 가진 8바이트 정수 연산과 더 작은 연산 집합을 포함한다.

8바이트 데이터만을 사용하기 때문에, 어떠한 모호성 없이 "words"로 참조할 수 있다.

 

Y86-64 명령어의 세부 사항:

- x86-64 movq 명령어는 네 가지 명령어로 나눌 수 있다: irmovq, rrmovq, mrmovq, rmmovq

- 네 가지 정수 연산 명령어가 있다: addq, subq, andq, xorq, 레지스터 데이터에만 연산이 가능하며 세가지 조건 코드(ZF, SF, OF)를 설정한다.

- 7개의 jump 명령어가 있다: jmp, jle,j jl, je, jne, jge, jg, 브랜치들은 브랜치의 타입과 조건 코드의 설정에 따라 발생한다.

- 6개의 조건 move 명령어가 있다: cmovle, cmovl, cmove, cmovne, cmovge, cmovg

- call 명령어는 반환 주소를 스택에 push하고 push하고 목적지 주소로 jump한며 ret 명령어는 이러한 호출로부터 반환한다.

- pushq와 popq 명령어는 push와 pop을 구현한다.

- halt 명령어는 명령어 실행을 중지한다. x86-64에는 hlt라는 명령어가 있으며 x86-64 애플리케이션 프로그램은 이 명령어를 사용하지 못한다. Y86-64는 halt 명령어를 사용하여 프로세서를 중지한다. (HLT)

 

4.1.3 Instruction Encoding

명령어의 바이트 수준 인코딩은 1부터 10바이트 사이를 필요로 한다.

모든 명령어는 명령어 타입을 확인하는 초기 바이트를 가지고 있다.

이 바이트는 2가지의 4비트 부분으로 나눌 수 있다: high-order, code와 low-order, function

코드 값은 0부터 0xB의 범위를 가지며 함수 값은 연관된 명령어의 그룹이 코드를 공유하는 경우에만 중요하다.

 

15개의 프로그램 레지스터는 연관된 레지스터 ID가 있다. (0 ~ 0xE)

프로그램 레지스터는 레지스터 파일에 CPU에 저장된다.

0xF ID 값은 명령어 인코딩에 사용된다.

 

어떤 명령어는 1바이트의 길이지만 더 긴 인코딩을 가진 피연산자를 요구할 수 있다.

추가적인 레지스터 구별 바이트가 있을 수 있다. 레지스터 필드는 rA와 rB로 불린다.

명령어의 어셈블리 코드 버전가 보여주듯이, 데이터 소스와 목적지를 사용한 레지스터와 주소 계산에 사용되는 base 레지스터를 구별한다.

하나의 레지스터 피연산자가 있는 명령어(irmovq, pushq, popq)는 0xF 값을 설정하는 다른 레지스터 구별자를 가지고 있다.

 

어떤 명령어는 추가적인 8바이트 상수 word를 필요로 한다.

이 word는 iromvq에 대한 immediate 데이터로써 제공하고, rmmovq와 mrmovq 주소 구별자와 브랜치와 호출에 대한 목적지의 변위(displacement)이다.

브랜치와 호출 목적지가 절대 주소로 제공된다. X86-64에서는 PC-relative 주소를 제공한다.

프로세서는 PC-relative addressing을 사용하여 더 압축적인 인코딩을 주고 코드가 메모리의 한 부분에서 다른 곳으로 이동하게끔 해준다.

 

명령어 집합의 중요한 특성 중 하나는 바이트 인코딩은 유일한 해석(interpretation)을 가져야만 한다.

바이트의 임의적인 시퀀스는 유일한 명령어 시퀀스로 인코딩하거나 올바른 바이트 시퀀스가 아니다.

이 특성은 프로세서가 코드에 대해 어떠한 애매모호성 없이 오브젝트 코드 프로그램을 실행할 수 있게 해준다.

코드 시퀀스의 시작 부분을 모른다면, 시퀀스를 각각의 명령어로 나누는 것을 미리 결정할 수 없다.

 

4.1.4 Y86-64 Exceptions

Y86-64 programmer-visible state는 실행 중인 프로그램의 전체적인 상태를 표현하는 상태 코드 Stat을 포함한다.

Code값 1, AOK는 프로그램이 실행 중인 것

Code값 2, HLT는 프로세서가 halt 명령어를 실행했다는 것

Code값 3, ADR은 프로세서가 유효하지 않은 메모리 주소를 작성하거나 이로 부터 읽을 수 있다는 것

Code값 4, INS는 유효하지 않은 명령어를 상대했을 때

 

더 완벽한 설계에서, 프로세서는 예외처리 핸들러(exception handler)를 부른다.

 

4.2 Logic Design and the Hardware Control Language HCL

하드웨어 설계에서, 전자 회로는 비트에 대한 함수를 계산하고 각기 다른 메모리에 비트를 저장하는 데 사용된다.

대부분의 현재 회로 기술은 신호 와이어의 높거나 낮은 전압에 따른 값을 표현한다.

논리 값 1은 높은 전압이고 반면에 0은 낮은 전압이다.

세 가지 주된 요소들은 디지털 시스템을 구현하는데 필요로 한다: 조합 논리는 비트 함수 계산, 메모리 요소는 비트 저장, 클럭 시그널은 메모리 요소의 갱신을 규제합니다.

 

HCL(Hardware Control Language)는 프로세서 설계의 제어 논리를 묘사하는 데 사용하는 언어이다.

 

4.2.1 Logic Gate

논리 게이트 타입

논리 게이트는 디지털 회로의 기본적인 컴퓨팅 요소이다. 논리게이트는 input의 비트 값의 부울 함수에 대한 output을 생성한다.

HCL 표현식은 C에서 연산자로 표현할 수 있다: && - AND, || - OR, ! - NOT

 

이러한 연산자를 사용하여 HCL를 작성하여, a, b, c에 대한 AND 연산자를 하면 a && b && c가 된다.

논리 게이트는 항상 활성화(active)되어 있다. 어떤 input이 게이트를 바꾸게 하면, output도 그에 따라 바뀐다.

 

4.2.2 Combinational Circuits and HCL Boolean Expressions

많은 논리 게이트를 네트워크로 조립함으로써, 우리는 조합 회로로 알려져 있는 블록을 만들 수 있다.

어떻게 네트워크를 만들 지에 대해 많은 제한 사항이 있다:

- 모든 논리 게이트 input은 다음 중 하나와 정확히 연결되어야 한다: 시스템 input 중 하나, 메모리 요소의 output 연결, 어떤 논리 게이트의 output

- 두 개 이상의 논리 게이트의 output은 서로 연결될 수 없다.

- 네트워크는 비순환이어야 한다. 네트워크 내에서 루프를 형성한 게이트를 통과한 경로가 없어야 한다.

 

멀티플렉서(multiplexor)는 제어 input 신호의 값에 따라 다른 데이터 신호의 집합에서 값을 선택한다.

단일 비트 멀티플렉서에서, 두 데이터 신호는 input 비트 a와 b이고 제어 신호는 input 비트 s이다.

Ouput은 s가 1일 때 a이고, s가 0일 때는 b이다.

 

HCL 표현식은 조합 논리 회로와 C에서 논리 표현식 사이의 병행성을 입증하며 둘 다 부울 연산을 사용하여 함수를 계산한다.

 

4.2.3 Word-Level Combinational Circuits and HCL Integer Expressions

논리 게이트의 더 큰 네트워크로 조립하면서, 더 복잡한 함수를 계산하는 조합 회로를 만들 수 있다.

데이터 words를 연산하는 회로를 설계한다. 이들은 정수나 다른 제어 패턴을 표현하는 비트 수준 패턴의 그룹이다.

 

word 수준 계산을 수행하는 조합 회로는 output word의 각각의 비트를 계산하는 논리 게이트를 사용하여 만들어진다.

HCL에서 word-level 신호를 int로 선언한다. HCL은 words에 대한 동일성 비교를 할 수 있게 해줘서 회로의 함수가 word 수준으로 표현될 수 있다.

 

word-level 멀티플렉서는 control input 비트 s에 의존하는 두 개의 input A와 B중 하나와 같은 64비트 word Out를 생성한다.

회로는 64개의 부분 회로를 가지고 있으며, 각각은 비트 수준의 멀티플렉서와 유사한 구조를 가지고 있다.

비트 수준의 멀티플렉서를 64번 복사하는 것보다 word 수준 버전이 !s를 한번 생성하고 각 비트 위치에 재사용하여 인버터를 감소시킨다.

case expression

프로세서 설계에서 많은 형태의 멀티플렉서를 사용할 것이다. HCL에서 멀티플렉서 함수는 case expression을 사용하여 설명된다.

논리적으로 selection expression은 시퀀스에서 평가되고 1의 결과를 낳는 첫 번째 케이스가 선택된다.

 

selection expression은 임의의 부울 표현식이 될 수 있고 임의적인 숫자가 될 수 있다.

이는 input 시널에 많은 선택이 있는 블록들을 표현할 수 있게 해준다.

 

가끔식 selection expression은 단순화 될 수 있는 데, 첫 번째 매칭 경우가 선택될 때가 이유가 된다.

 

ALU(Arithmetic/Logic Unit)

조합 논리 회로는 word 수준의 데이터에 다양하고 많은 타입의 연산을 수행할 수 있도록 설계된다.

ALU로 알려져 있는 중요한 조합 회로는 추상화 수준으로 다이어그램으로 표현할 수 있다.

 

4.2.4 Set Membership

 

4.2.5 Memory and Clocking

조합 회로는 어떠한 정보를 저장하지 않는다. 대신에 input에 신호에 단순하게 반응하고 output을 생성한다.

순차 회로를 만들려면 비트로 표현되는 정보를 저장하는 장치를 소개해야 한다.

 

우리의 저장 장치는 새로운 값이 언제 장치로 로드되는 지를 결정하는 주기적인 신호를 결정하는 단일 클럭(clock)에 의해 컨트롤된다.

메모리 장치의 두 가지 클래스를 고려한다:

- Clocked Register는 개별적인 word나 비트를 저장한다. 클럭 신호는 레지스터의 로딩을 제어한다.

- Random Access Memories는 다수의 words를 저장하며 어떤 word가 읽어지고 쓰여지는 것을 선택하려고 주소를 사용한다.

 

"레지스터"는 하드웨어로 말할 때와 기계 언어 프로그래밍으로 말할 때랑 살짝 다르다.

하드웨어에서, 레지스터는 input과 output 와이어에 의해 직접적으로 회로의 나머지 부분과 연결된다.

기계 수준 프로그래밍에서, 레지스터는 레지스터 ID로 구성되어 있는 주소들인 CPU에서 addressable words의 작은 컬렉션을 표현한다.

 

하드웨어 레지스터는 고정된 상태로 있으며, 현재 상태와 같은 output를 생성한다.

신호는 조합 회로를 거쳐 레지스터로 전파되지만, 레지스터 output은 클럭이 낮아야 유지된다.

클럭이 발생하면, input 신호은 다음 상태로써의 레지스터로 로드되고 다음 클럭이 발생할 때까지 새로운 레지스터 output이 된다.

중요한 점은 레지스터가 회로의 다른 부분에 있는 조합 회로 사이의 경계로서 제공된다는 것이다.

Y86-64 레지스터는 PC, condition code(CC), 프로그램 상태(Stat)을 가지고 있는 clocked register를 사용할 것이다.

 

전형적인 레지스터 파일 다이어그램

레지스터 파일에는 두 개의 읽기 포트(A, B)가 있고 하나의 쓰기 포트(W)가 있다.

멀티포트가 있는 random access memory는 multiple 읽기와 쓰기 연산을 동시에 할 수 있게 해준다.

 

레지스터 파일은 내부 저장소가 있기 때문에 조합 회로가 아니다. 그러나 우리의 구현체에서는 데이터가 마치 주소 input과 데이터 output을 가지는 조합 논리의 블록이라서 데이터가 레지스터 파일로 부터 읽을 수 있다.

 

레지스터 파일에 words을 작성하는 것은 clocked register에 값을 로드하는 것과 비슷한 방법의 클럭 신호에 의해 컨트롤된다.

우리의 프로세서가 프로그램 데이터를 저장하기 위해 random access memory를 가지고 있다.

이 메모리는 단일 address input이고, 쓰기를 위한 data input 그리고 읽기를 위한 data output을 가지고 있다.

레지스터 파일과 같이, 메모리로부터 읽는 것은 조합 논리와 비슷한 방법으로 연산한다:

address input에 주소를 제공하고 write control signal을 0으로 설정하면, 주소에 저장되어 있는 값은 data out을 보여줄 것이다.

주소가 범위 밖에 있으면 error 신호는 1로 설정될 것이고 반대면은 0이다.

 

메모리에 쓰기 연산을 하는 것은 클럭에 의해 컨트롤된다:

address에 원하는 주소로 설정하고 data에는 원하는 값, 그리고 write는 1로 설정한다.

클럭을 연산할 때, 주소가 유효하면 메모리의 특정 위치가 업데이트 된다.

읽기 연산을 할 때, 주소가 유효하지 않으면 error 신호는 1이 된다.

 

우리의 프로세서는 명령어를 읽기 위한 추가적인 읽기 전용 메모리를 포함한다.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함