예를 들어 우리가 C언어를 작성하고 있다고 합시다. 이 C언어는 어떤 동작을 통해 컴퓨터에 전달될까요?
C code
f = (g+h) - (i+j)가 있다면,
Compiled ARM code
ADD t0, g, h ; temp t0 = g+h
ADD t1, i, j ; temp t1 = i+j
SUM f, t0 ,t1 ; f = t0-t1 으로 구성됩니다.
ARM는 아래의 그림과 같이 16x32bit의 레지스터로 구성됩니다.
32비트 크기의 플립플롭이 16개 배열되어있는 구조이고, 32bit의 데이터를 우리는 word라 부릅니다.
어떤 연산을 할때, 메모리또는 레지스터로 부터 값을 로드하여 정보를 가져오고 이값을 연산한 후, 레지스터 또는 메모리에 다시 저장합니다. 메모리는 어떻게 구성되어 있을까요?
메모리는 8비트에 하나씩 번지수가 증가하여 구성되지만 실제는 다릅니다. 메모리에 word를 저장해야되는데 이 word의 크기가 32bit이기 때문입니다. 즉, 메모리 한칸에 32bit로 구성해야 합니다. 그래서 4번지를 한꺼번에 사용하여 실제 메모리를 구현합니다. 이를 words가 메모리에 aligned되어 있다라고 말합니다. 그래서 번지수는 무조건 4의 배수이죠.
Memory Operand Example
다음 C code가 있다고 가정합시다.
C code :
g = h + A[8]
g in r1, h in r2 , base address of A in r3, r5 is temporary register
Compiled ARM Code : Index 8 required offset of 32
LDR r5, [r3,#32] ; reg r5 get A[8]
ADD r1, r2, r5 ; g=h + A[8]
STR r5, [r3,#48]
C언어에서 포인터의 개념을 우리는 알고있습니다. 포인터란 말 그대로 어떠한 데이터를 특정한 메모리 번지수에 저장하는 것을 의미했습니다. 지금 하고있는 동작은 이러한 포인터의 개념과 동일합니다.
A 배열이 12번지에 선언되어있다고 가정합시다. 그러면 A[8]는 메모리의 몇번지에 있을까요? 일단 한 word당 4byte를 갖는다는 것을 알고있을떼, A[8]은 A에가 선언된 번지에서 8칸 아래에 있다는 것을 알 수 있습니다. 즉, 8*4인 32번지 떨어진 곳에 위치 한다는 것 입니다.
즉, LDR r5, [r3,#32] 의미는 r3에서 32번지 떨어진 곳에 존재하는 데이터를 로드(load)해서 r5에 집어넣어라. 이러한 뜻입니다. 여기서 r3를 base register라 하고 #32를 offset이라 정의 합니다.
STR r5, [r3,#48]은 무슨 의미 일까요?
STR은 저장하라(store)라는 의미이고 #48은 r3로 부터 48번지 떨어진 곳을 의미할 것입니다.
즉, r3에서 48번지 떨어진 곳에 r5를 저장해라 라는 뜻입니다.
Registers Vs Memmory
레지스트와 메모리는 프로세서가 직접 접근 할 수 있는 데이터를 보유하고 CPU의 처리 속도를 향상시킨다는 공통점이 있습니다. 하지만 레지스터와 메모리는 서로 거의 차이를 고유하지 않습니다. 이 둘의 기본적인 차이점은 레스터가 CPU가 현재 처리하고 있는 데이터를 보유하는 반면, 메모리는 프로그램이 실행에 필요한 프로그램 명령과 데이터를 보유한다는 것 입니다.
즉, 자주쓰는것을 레지스터에 보관하고 자주 쓰지 않는 것들을 위주로 메모리에 저장한다면 효율이 더 좋아 질 것입니다.
레지스터 <--- 컴파일러 ---> 메모리
레지스터와 메모리 간의 동작에서는 컴파일러의 도움을 받습니다. 즉, 컴파일러의 성능과 최적화가 중요한 요인이 될 수있습니다. 예를들어 LDR과 STR이 동작하는 과정이 생각보다 시간을 많이 소요하기 때문입니다. 또한 레스터에 데이터를 어떻게 잘 할당시킬 것인가 등 다양한 문제를 해결하기 위해서는 컴파일러의 성능이 중요합니다.
Immediate Operands
어떤 명령어를 수행하기 위해서 먼저 메모리에서 데이터를 로드해서 가져오고 또 명령을 수행한 드음 스토어 했다. 하지만 이런 명령어를 계속사용하면 효율이 그만큼 떨어질 것이다. 레지스터가 들어오는 것이아니라 밑 수식과 같이 숫자를 바로 써버리면 그 만큼 효율개선이 될 것이다. 이러한 형태를 Immeiate형태라 한다.
Make the common case fast
ADD r3,r3,#4 ; r3 =r3+4 (# : immediate 기호)
Representing Instructions
Arm 명령어는 32비트로 인코드되어있다. 즉, 하나의 명령어가 한줄에 딱 맞게 들어갈 수 있다. 예를들어 add sub 등 계산을 하는 명령어들이 몇개정도 있을까? 사칙연산 등을 포함해도 아주 많지는 않습니다. 만약 내가 써야하는 모든 명령어의 수가 50개라면 이러한 명령어를 위한 몇비트의 공간이 필요할까? 6비트면 충분합니다.
즉, 32비트 한줄안에 이러한 명령어들이 들어가는 칸, 각 레지스터가 들어가는 칸 등 여러가지 항목들이 포함될 것입니다.
위 이미지는 Arm instruction의 format입니다.
cond : 이 부분을 보고 전체 Instruction을 할지 말지 결정한다. (추후 설명)
F : Instruction format을 나타내며, LDR과 STR같은 명령어를 굳이 opcode부분에 저장 하지 않고 따로 분류한다. 즉, instruction이 LDR에 관한것인지, STR에 관한것인지 판단한다.
I : Immediate상태를 표현하며, 1일 경우 immediate, 0일경우 레지스터로 본다.
Opcode : 명려어를 지정하는 칸이며 4bit이므로 16가지 명령어를 쓸 수 있다.
S : set condition code이며 flag와 관련 (추후 설명)
Rn : 저장될 위치의 레지스터
Rd : 소스 레지스터
Operand : Immediate값 12bit로 넉넉하게 포함된다. (4096까지 쓸 수 있다. 즉, 왠만한 수 다 커버)
예제)
ADD r5, r1, r2 ; r5 = r1+r2
14 0 0 4 0 1 5 2 >>> 1110 -- 101(2) 이런식으로 표현된다.
'Computer Architecture > 컴퓨터 구조' 카테고리의 다른 글
[9] CH2 명령어:컴퓨터 언어 < MIPS 버전 2 > (0) | 2022.01.16 |
---|---|
[8] CH2 명령어:컴퓨터 언어 < MIPS 버전 > (0) | 2022.01.16 |
[7] CH1 컴퓨터 추상화 및 관련 기술 < 결론 > (0) | 2022.01.12 |
[6] CH1 컴퓨터 추상화 및 관련 기술 < 오류 및 함정 > (0) | 2022.01.12 |
[5] CH1 컴퓨터 추상화 및 관련 기술 < Intel Core i7 벤치마킹 > (0) | 2022.01.11 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!