ARM7 강좌 [8] : Instruction Set (2)
이번 강좌에서는 데이터 프로세싱 명령에 대해 다루려 합니다. 해당 명령은 ARM7의 50%정도에 해당하는 명령입니다. 실제 개수는 16개이고, 연산명령과 비교명령, 비트 연산명령, 데이터 전송 명령 등이 포함됩니다.
● Data Processing Instruction
데이터 전송명령의 형식은 다음과 같습니다.
+--------------------------------------------------------------------+
| Cond | 00 | I | OpCode | S | Rn | Rd | Operland 2 |
+--------------------------------------------------------------------+
4 2 1 4 1 4 4 12
전에 언급했듯이 모든 인스트럭션의 크기는 32 Bit 입니다. 위의 그림에서 숫자는 해당 필드의 비트 수를 의미합니다.
1) <Cond> [31:28] 4 Bit
해당 명령의 조건 실행 플래그입니다. 지난 강좌에서 언급했었던 부분인데, 모든 명령어에 포함되므로 데이터 프로세싱 명령에도 포함됩니다.
혹시나 해서 다시 말씀드리는데, 해당 플래그를 통해 명령을 현재 플래그 레지스터(CPSR)의 상태에 따라 실행 여부를 결정하는데 사용되는 플래그입니다.
2) <I> [25] 1 Bit
Operland 2로 지정되어 있는 부분이 Immediate Operand 인지 아닌지 여부를 나타내는 비트입니다. Immediate Operand라 함은, 예를 들어 8086에서 MOV AX,01234h 라고 했을 경우, 1234h를 가리키는 말입니다. 자세한 내용은 Operland2를 설명하면서 자세히 다루겠습니다.
3) <OpCode> [24:21] 4 Bit
데이터 프로세싱 명령 중 어떤 명령인지를 나타내는 필드입니다. 해당 필드와 명령어는 다음과 같습니다.
<OpCode> Instruction Description
-----------------------------------------------------
0000 AND Rd:=Op1 AND Op2
0001 EOR Rd:=Op1 XOR Op2
0010 SUB Rd:=Op1 - Op2
0011 RSB Rd:=Op2 - Op1
0100 ADD Rd:=Op1 + Op2
0101 ADC Rd:=Op1 + Op2 + C
0110 SBC Rd:=Op1 - Op2 + C - 1
0111 RSC Rd:=Op2 - Op1 + C - 1
1000 TST Op1 AND Op2 -> CPSR
1001 TEQ Op1 XOR Op2 -> CPSR
1010 CMP Op1 - Op2 -> CPSR
1011 CMN Op1 + Op2 -> CPSR
1100 ORR Rd:=Op1 OR Op2
1101 MOV Rd:=Op2
1110 BIC Rd:=Op1 AND (NOT Op2)
1111 MVN Rd:=NOT Op2
명령어들의 간단한 설명만으로도 어느 정도는 이해할 수 있으리라 생각합니다. 각각의 명령에 대해서는 자세히 다루지 않도록 하겠습니다. 나중에 예제를 보시고 이해할 정도라면 족하다고 생각합니다.
4) <S> [20] 1 Bit
S 비트가 1인 경우는 데이터 프로세싱 명령의 결과가 CPSR(플래그레지스터)에 영향을 미칩니다. 즉, 0인 경우에는 CPSR은 변하지 않습니다.
5) <Rn> [19:16] 4 Bit
ARM 데이터 프로세싱 명령은 그 결과와 첫 번째 오퍼랜드는 항상 레지스터로 지정해야 합니다. Rn은 첫 번째 오퍼랜드를 가리키는 것으로 위에서 Op1으로 표기한 것에 해당합니다. ARM에서 한번에 볼 수 있는 범용 레지스터는 sp, lr, pc 등을 포함해서 r0에서 r15까지라고 말씀 드렸습니다. 즉, 4Bit를 통해 레지스터를 나타내게 됩니다. 해당 필드는 명령에 따라 사용되지 않기도 합니다. MOV나 MVN등이 이에 해당합니다.
6) <Rd> [15:12] 4 Bit
오퍼레이션의 결과가 저장될 레지스터를 의미합니다. 역시 레지스터를 가리키므로 4비트를 사용하고 모든 명령에서 디폴트로 사용되는 필드입니다. 말씀드렸듯이 ARM의 데이터 프로세싱 명령의 결과는 항상 레지스터로 들어갑니다.
7) Operand 2 [11:0] 12 Bit
드디어 오늘의 가장 험난한 산인 Operand 2 필드까지 왔군요. 설명 드려야 할 부분이 좀 많거든요. 어떻게 설명을 드려야 할지, 막막하긴 하지만, 용기를 가지고 차근차근 설명해 보도록 하겠습니다.
● 데이터 프로세싱 명령의 Operand 2 필드
오퍼랜드 2의 의미 자체는 별게 아닙니다. 아마도 다들 아시겠지만, ALU에 연산명령을 내릴 경우 한 쪽 입력은 오퍼랜드 1, 다른 쪽은 오퍼랜드 2 그리고, 결과가 나오고... 앞서 설명한 내용에 의거하면 다음과 같이 표현 할 수 있겠죠?
Op1(Rn) Operand 2
-------------- ---------
| | / /
| | / /
| | / /
| /
| ALU /
| /
| /
----------------
Rd
예를 들어 AND r1,r2,r3라는 명령에서 Rd = r1 이고 Rn=r2 입니다. 그리고 r3가 Operand2에 해당하는 부분이 되겠죠. 의미는 r1=r2 & r3 라는 의미입니다.
여기서 설명하고자 하는 ARM7의 데이터 프로세싱 명령의 Operand2의 타입은 두 가지 종류가 있습니다. <I> 필드의 내용에 따라 구분이 되는데, Immediate Operand 혹은 레지스터 Operand입니다.
1) Register Operand
<I> 필드가 0일 경우엔 Op2가 레지스터임을 의미합니다. 레지스터를 나타내기 위해서는 아시다시피 4비트만 있으면 되죠? 그런데 Op2를 위한 비트 수는 총 12 비트입니다. 남는군요.
구체적으로 레지스터 오퍼랜드2의 형식을 보여드리겠습니다.
+----------------------------------------------+
| Shift [11:4] | Rm [3:0] |
+----------------------------------------------+
위의 그림을 보시면 Rm이라고 레지스터를 지정하는 4비트가 포함되어 있습니다. 그러면 Shift 부분은 뭘까요?
강좌의 앞부분에서 언급했나요? 무슨 Shift가 ALU의 한쪽에 달려 있다고. 결론적으로는 레지스터를 ALU로 그냥 집어넣는 것이 아니라 Shifter를 통해서 넣어주도록 되어 있습니다. 따라서, Shift라는 필드는 (8비트죠?) 그런 역할을 해주는 것이겠군요. 그럼 왜 8비트일까요? 여기서 다시 한번 Shift를 구체적으로 살펴보겠습니다.
우선 그전에 Shift 필드에는 Shift 회수를 지정하는 방법이 두 가지가 있는데, 첫 째는 Shift 필드 안에 그 회수를 포함시키는 방법이고, 두 번 째는 Shift 회수가 들어있는 레지스터를 Shift 필드 안에서 지정하는 방법입니다. 경우의 수가 자꾸 늘어가는군요. 해당 타입 두 가지는 Shift 필드의 최하위 비트인 4번 비트에 따라 결정됩니다. 다시 그림을 그려보겠습니다.
+-------------------+ +-------------------+
| count |type | 0 | | Rs | 0 |type | 1 |
+-------------------+ +-------------------+
5 2 1 4 1 2 1
최하위 비트의 값이 0이냐 1이냐에 따라 두 가지로 구분이 되었습니다. 왼쪽의 경우가 직접 Shift 회수를 지정하는 방법으로, count 부분이 총 5 비트로서 그 값을 의미합니다. ARM7의 레지스터는 32비트이므로 5비트는 있어야 Shift 회수를 표현할 수 있겠지요.
그러면 Type은 뭘까요? 2비트인 Type의 의미는 다음과 같습니다.
00 : logical left (LSL)
01 : logical right (LSR)
10 : arithmetic right (ASR)
11 : rotate right (ROR)
그렇군요. 단순히 Shift라고 말씀드렸지만 실제로는 좌, 우, 부호의 여부와 Rotate까지 형식을 지정할 수가 있습니다. (무지 복잡해지는 듯한 느낌입니다.^^)
오른쪽에 레지스터를 지정하는 방식은, 1비트가 남아서 0으로 처리한 것만 제외하고는 별 문제가 없겠죠?
원래는 여기서 쉬프트 방식 4가지에 대한 설명이 뒤를 이어야 하겠지만. 이러다 보면 한도 끝도 없을 것 같네요.
2) Immediate Operand
강좌를 정리하려다 생각하니 Immediate Operand를 설명 안했군요. 여기까지는 해야할 것 같아서.
레지스터 오퍼랜드의 경우 총 12 비트 중에서 4비트는 레지스터를 지정하고, 나머지 8비트는 해당 레지스터 값을 Shift하는 방법을 지정하도록 되어 있었습니다.
Immediate 오퍼랜드는 몇 가지 문제가 있습니다. 32비트 레지스터에 값을 써넣고 싶은데 공간은 12비트 밖에는 없다는 것이지요. 8086등에서는 그냥 여러 바이트로 명령을 처리했었으니 그런 문제가 없었지만, ARM에서는 이것 때문에 모든 명령이 32비트라는 규칙을 깰 수는 없었겠지요. 다음은 구체적인 형태입니다.
+----------------------------------------------------------------+
| Rotate [11:8] | Imm [7:0] |
+----------------------------------------------------------------+
이전과 비슷한 모양이군요. 이번엔 Rotate 필드(4비트)가 있고, 또 8비트의 Imm필드가 있습니다. Imm은 말 그대로 Immediate Value를 넣는 공간입니다. 이 공간이 8비트라서, 결국 ARM7에서 어떤 상수 값을 레지스터로 전송하거나 할 경우 8비트까지는 아무런 문제가 없이 넣을 수 있습니다. 그러면 Rotate 필드의 하는 역할은 무엇일까요?
좀 복잡한데요... ARM7문서에는 다음과 같이 써 있습니다.
“Immediate Operand rotate 필드는 부호 없는 4비트 정수로서 8비트 Immediate 값에 Shift 오퍼레이션을 할 수 있도록 사용되는 값이다. rotate필드 *2 값만큼 8Bit Immediate Value 값을 Right Rotate 시킨다. 결국 8비트 값을 32비트로 확장시키는 역할을 하며 이를 통해 자주 사용되는 많은 상수들을 사용 가능하도록 한다."
8비트의 값이 ALU로 들어가기 전에 Shifter로 들어가면, 이미 32비트로 확장이 됩니다. 이후 그 값을 그냥 쓰면 8비트 영역만 표현할 수 있지만 Rotate필드 값을 * 2 한만큼 Rotate Right 시킨다 그랬으니, 어떤 변화가 생기겠죠?
오늘 분량이 좀 많았네요... 차근차근... 담에 또 말씀드리죠.. 뭐. 몇 가지 예를 들어 보이면서. 오늘 강좌를 정리할까 합니다.
ADDEQ r2,r4,r5 : 제로 플래그가 설정되어 있다면 r2=r4+r5
SUBS r4,r5,r7,LSR r2 : r4=r5-(r7>>r2) & effect CPSR