출처 : 디지털 동호회
----------------------------------------------------------------------
ARM7 강좌 [4] : 레지스터
----------------------------------------------------------------------
* ARM7의 레지스터
지난 강좌에서 ARM7에는 31개의 General Purpose 레지스터와 6개의Status
레지스터가 있다고 말씀드렸습니다. 물론 모두 32비트 레지스터 입니다.
그런데 ARM7의 어셈블러에서 사용하는 범용 레지스터 키워드는 r0 에서
r15 까지 16개 밖에는 되지 않습니다. 즉, 다시 말해서 사용자가 한번에
사용할 수 있는 레지스터는 16개 입니다. 그중에 몇개는 프로그램 카운터
(PC) 나 스택 포인터(SP) 등의 용도로 사용됩니다. 나머지 레지스터는
CPU 동작 모드(Exception)과 관련되어 r0-r15로 리맵핑 되어 사용되는데
이는 다시 설명 드리겠습니다.
1. Special Purpose General Register
윗부분에서 잠시 설명드렸지만, 유저가 프로그램 할때 레지스터 지정을
위해 사용할 수 있는 키워드는 r0에서 r15 까지 입니다. 그중에 몇 가지
는 특별한 목적을 위해 사용됩니다.
- Program Counter (r15)
: r15는 다른 CPU에서 PC와 같은 역할을 합니다. 다만 차이가 있다면
r15를 일반 다른 레지스터처럼 오퍼랜드로 사용할 수 있다는 점이고
(다른 CPU도 마찬가지 인가요?) ARM어셈블러에서는 pc라는 키워드와
r15를 동일하게 취급합니다.
- Stack Pointer (r13)
: ARM7에는 Stack을 위한 명령어가 따로 없습니다. 즉, Push 나 Pop등
의 명령어가 제공되지 않습니다. 그러나 sp라는 키워드를 사용하여
r13을 쓸 수 있는데, 묵시적으로 r13을 스택포인터로 사용할 수 있도
록 정해 놓은 듯 합니다. 그러면 왜 하필이면 r0 나 r1 이 아니고
r13을 sp라고 칭하느냐면, 역시 Exception 과 관련된 부분이므로 잠
시 후에(혹은 다음강좌에) 설명하도록 하지요. 그리고, Push 명령이
나 Pop 명령이 없으므로, ARM7에서는 같은 기능을 일반 데이터 전송
명령을 통해 해결 합니다. ARM7의 데이터 전송명령은 Auto Increment
기능이 있어서 하나의 인스트럭션으로 Push나 Pop과 동일한 기능을
수행 할 수 있습니다.
- Link Register (r14)
: r14는 링크 레지스터라고 부릅니다. 이 레지스터는 8086 등 에서는
보지 못했던 기능의 레지스터 입니다. 8086등의 프로세서는 서브루틴
을 호출할 경우 CALL을 사용하면 다음에 수행될 프로그램 카운터를
스택에 넣고, 호출될 번지를 프로그램 카운터에 넣는 동작을 하는데,
ARM7에서는 CALL과 RET와 같은 명령이 없습니다. 대신 Branch with
Link 라는 명령(BL) 이 있는데, 해당 명령을 수행하면, CALL과 비슷
하게 다음에 수행될 pc(r15)값을 스택이 아니라 lr(r14)에 넣고 분기
번지를 pc(r15)에 넣어 분기합니다. 즉, 스택을 사용하지 않는 것이
지요. 복귀할 때는 RET대신 mov pc,lr 이라는 데이터 전송명령으로
복귀합니다.
이런 방식은 나름대로 장단점이 있습니다. 우선 단점을 말하자면, 어
떤 서브루틴이 콜 되었을 때, 서브루틴에서는 복귀번지가 r14에 들어
있는 상태가 됩니다. 문제는 해당 서브루틴에서 다시한번 다른 서브
루틴을 콜 한다면, 원래 r14에 보관되어 있던 복귀 번지값이 덮어씌
워지는 결과가 생깁니다. 이런 경우엔, 수동으로 sp(r13)를 이용하여
스택에 r14 값을 보관해 두어야 합니다. 즉, Call하기 전에 r14를 스
택에 보관해 두고, 리턴해서 복구하는 과정을 거치는 셈이지요.
그러면 구태여 왜 이런 방법을 사용할까요. 이미 눈치채신 분들도 계
시겠지만, 그렇게 Call을 연속적으로 하는 경우가 아닌, 한번만 Call
하는 경우라면, 스택을 사용하지 않고 레지스터를 사용함으로써, 그
속도에서 이익을 얻게 되는 것이죠.
개인적으로는 기능이야 어떻든, Call과 Ret 마저 없어서 코드를 읽기
가 상당이 좋지 않다는 생각입니다. 코드를 보고 어디서 어디까지가
한 프로시져 인지 쉽게 분간이 안갈 경우가 많거든요.
2. ARM7 Status Register
이제 스테이터스 레지스터를 살펴보려고 합니다. ARM7에는 32비트의 스테
이터스 레지스터가 6개가 있습니다. 그러나 6개 모두를 한꺼번에 사용하
지는 못하고, 또 그럴 필요도 없죠. 일단은 하나의 32비트 Status 레지스
터만 생각하면 됩니다.
스테이터스 레지스터는 PSR이라고 부릅니다. 그리고 일반적으로 CPSR이라
고 하여 Current Processor Status Register 로 부릅니다.
PSR은 크게 Flag Bits부분과 Control Bits부분으로 나뉩니다.
- Flag Bits
: 어떤 인스트럭션의 결과 등을 나타내는 부분으로 4 비트가 있습니다.
다른 CPU의 그것과 유사한데, 각각 N, Z, C, V 의 4가지 입니다.
1) Negative/Less Than Flag
: N 으로 표기되는 이 플래그는 연산의 결과가 마이너스인 경우에
세트됩니다.
2) Zero Flag
: Z 으로 표기되는 이 플래그는 연산의 결과가 0이 되었을 경우에
세트됩니다.
3) Carry/Borrow/Extend Flag
: C 로표기되는 이 플래그는 자리올림이나 내림이 발생한 경우,
그리고 Shift 연산 등에서 사용됩니다.
4) Overflow Flag
: V 로 표기되는 이 플래그는 연산의 결과가 오버플로우 되었을
경우 사용됩니다.
이상의 Flag Bit들은 다른 칩의 상태 레지스터와 다르지 않습니다.
따라서 이해를 하는데에도 별 무리가 없으리라 생각되며, 더 자세히
알고 싶으시다면, 각 명령어와 관련된 문서를 참조하시길 바랍니다.
- Control Bits
: 컨트롤 비트들은 인터럽트를 제어하는 비트와 계속해서 언급되기만
하고 실체를 드러내지 않고 있는 Exception 과 관련된 CPU 동작모드
를 설정하거나 확인할 수 있는 기능을 가진 Bit 가 있습니다.
1) IRQ / FIQ Disable Bit
: ARM7의 인터럽트중에서 IRQ와 FIQ 를 금지시킬 수 있는 플래그
입니다. 인터럽트의 종류는 이밖에도 몇가지가 더 있는데, 그중
에서 IRQ, FIQ는 PSR을 통해 금지시키거나 가능하도록 설정할
수 있습니다.
2) Mode Bits
: M0 에서 M4까지의 모드 비트는 CPU의 6개의 동작 상태를 나타냅
니다. 즉, 간단히만 말하자면 ARM7은 6개의 동작 모드를 가지는
데, 이를테면 유저모드와 인터럽트 모드 등 입니다. 역시 자세
한 내용은 다음 강좌를 통해 말씀드리겠습니다.
이제 스테이터스 레지스터를 한번 그려보겠습니다.
------------------------------------------------------------------
| N | Z | C | V | ... | I | F | | M4 | M3 | M2 | M1 | M0 |
------------------------------------------------------------------
Bit 31 30 29 28 7 6 4 3 2 1 0
오늘은 ARM7의 레지스터에 대해 기본적인 내용을 알아보았습니다. 하지만
많은 부분에서 ARM7 의 동작 모드와 관련되는 부분이 나왔지요. 때문에 다
음 시간으로 미룬 부분들이 많군요.
다음 강좌에서는 ARM7 Exception 에 대해서 다루려고 합니다. 오늘은 이만
줄이겠습니다.
----------------------------------------------------------------------
ARM7 강좌 [4] : 레지스터
----------------------------------------------------------------------
* ARM7의 레지스터
지난 강좌에서 ARM7에는 31개의 General Purpose 레지스터와 6개의Status
레지스터가 있다고 말씀드렸습니다. 물론 모두 32비트 레지스터 입니다.
그런데 ARM7의 어셈블러에서 사용하는 범용 레지스터 키워드는 r0 에서
r15 까지 16개 밖에는 되지 않습니다. 즉, 다시 말해서 사용자가 한번에
사용할 수 있는 레지스터는 16개 입니다. 그중에 몇개는 프로그램 카운터
(PC) 나 스택 포인터(SP) 등의 용도로 사용됩니다. 나머지 레지스터는
CPU 동작 모드(Exception)과 관련되어 r0-r15로 리맵핑 되어 사용되는데
이는 다시 설명 드리겠습니다.
1. Special Purpose General Register
윗부분에서 잠시 설명드렸지만, 유저가 프로그램 할때 레지스터 지정을
위해 사용할 수 있는 키워드는 r0에서 r15 까지 입니다. 그중에 몇 가지
는 특별한 목적을 위해 사용됩니다.
- Program Counter (r15)
: r15는 다른 CPU에서 PC와 같은 역할을 합니다. 다만 차이가 있다면
r15를 일반 다른 레지스터처럼 오퍼랜드로 사용할 수 있다는 점이고
(다른 CPU도 마찬가지 인가요?) ARM어셈블러에서는 pc라는 키워드와
r15를 동일하게 취급합니다.
- Stack Pointer (r13)
: ARM7에는 Stack을 위한 명령어가 따로 없습니다. 즉, Push 나 Pop등
의 명령어가 제공되지 않습니다. 그러나 sp라는 키워드를 사용하여
r13을 쓸 수 있는데, 묵시적으로 r13을 스택포인터로 사용할 수 있도
록 정해 놓은 듯 합니다. 그러면 왜 하필이면 r0 나 r1 이 아니고
r13을 sp라고 칭하느냐면, 역시 Exception 과 관련된 부분이므로 잠
시 후에(혹은 다음강좌에) 설명하도록 하지요. 그리고, Push 명령이
나 Pop 명령이 없으므로, ARM7에서는 같은 기능을 일반 데이터 전송
명령을 통해 해결 합니다. ARM7의 데이터 전송명령은 Auto Increment
기능이 있어서 하나의 인스트럭션으로 Push나 Pop과 동일한 기능을
수행 할 수 있습니다.
- Link Register (r14)
: r14는 링크 레지스터라고 부릅니다. 이 레지스터는 8086 등 에서는
보지 못했던 기능의 레지스터 입니다. 8086등의 프로세서는 서브루틴
을 호출할 경우 CALL을 사용하면 다음에 수행될 프로그램 카운터를
스택에 넣고, 호출될 번지를 프로그램 카운터에 넣는 동작을 하는데,
ARM7에서는 CALL과 RET와 같은 명령이 없습니다. 대신 Branch with
Link 라는 명령(BL) 이 있는데, 해당 명령을 수행하면, CALL과 비슷
하게 다음에 수행될 pc(r15)값을 스택이 아니라 lr(r14)에 넣고 분기
번지를 pc(r15)에 넣어 분기합니다. 즉, 스택을 사용하지 않는 것이
지요. 복귀할 때는 RET대신 mov pc,lr 이라는 데이터 전송명령으로
복귀합니다.
이런 방식은 나름대로 장단점이 있습니다. 우선 단점을 말하자면, 어
떤 서브루틴이 콜 되었을 때, 서브루틴에서는 복귀번지가 r14에 들어
있는 상태가 됩니다. 문제는 해당 서브루틴에서 다시한번 다른 서브
루틴을 콜 한다면, 원래 r14에 보관되어 있던 복귀 번지값이 덮어씌
워지는 결과가 생깁니다. 이런 경우엔, 수동으로 sp(r13)를 이용하여
스택에 r14 값을 보관해 두어야 합니다. 즉, Call하기 전에 r14를 스
택에 보관해 두고, 리턴해서 복구하는 과정을 거치는 셈이지요.
그러면 구태여 왜 이런 방법을 사용할까요. 이미 눈치채신 분들도 계
시겠지만, 그렇게 Call을 연속적으로 하는 경우가 아닌, 한번만 Call
하는 경우라면, 스택을 사용하지 않고 레지스터를 사용함으로써, 그
속도에서 이익을 얻게 되는 것이죠.
개인적으로는 기능이야 어떻든, Call과 Ret 마저 없어서 코드를 읽기
가 상당이 좋지 않다는 생각입니다. 코드를 보고 어디서 어디까지가
한 프로시져 인지 쉽게 분간이 안갈 경우가 많거든요.
2. ARM7 Status Register
이제 스테이터스 레지스터를 살펴보려고 합니다. ARM7에는 32비트의 스테
이터스 레지스터가 6개가 있습니다. 그러나 6개 모두를 한꺼번에 사용하
지는 못하고, 또 그럴 필요도 없죠. 일단은 하나의 32비트 Status 레지스
터만 생각하면 됩니다.
스테이터스 레지스터는 PSR이라고 부릅니다. 그리고 일반적으로 CPSR이라
고 하여 Current Processor Status Register 로 부릅니다.
PSR은 크게 Flag Bits부분과 Control Bits부분으로 나뉩니다.
- Flag Bits
: 어떤 인스트럭션의 결과 등을 나타내는 부분으로 4 비트가 있습니다.
다른 CPU의 그것과 유사한데, 각각 N, Z, C, V 의 4가지 입니다.
1) Negative/Less Than Flag
: N 으로 표기되는 이 플래그는 연산의 결과가 마이너스인 경우에
세트됩니다.
2) Zero Flag
: Z 으로 표기되는 이 플래그는 연산의 결과가 0이 되었을 경우에
세트됩니다.
3) Carry/Borrow/Extend Flag
: C 로표기되는 이 플래그는 자리올림이나 내림이 발생한 경우,
그리고 Shift 연산 등에서 사용됩니다.
4) Overflow Flag
: V 로 표기되는 이 플래그는 연산의 결과가 오버플로우 되었을
경우 사용됩니다.
이상의 Flag Bit들은 다른 칩의 상태 레지스터와 다르지 않습니다.
따라서 이해를 하는데에도 별 무리가 없으리라 생각되며, 더 자세히
알고 싶으시다면, 각 명령어와 관련된 문서를 참조하시길 바랍니다.
- Control Bits
: 컨트롤 비트들은 인터럽트를 제어하는 비트와 계속해서 언급되기만
하고 실체를 드러내지 않고 있는 Exception 과 관련된 CPU 동작모드
를 설정하거나 확인할 수 있는 기능을 가진 Bit 가 있습니다.
1) IRQ / FIQ Disable Bit
: ARM7의 인터럽트중에서 IRQ와 FIQ 를 금지시킬 수 있는 플래그
입니다. 인터럽트의 종류는 이밖에도 몇가지가 더 있는데, 그중
에서 IRQ, FIQ는 PSR을 통해 금지시키거나 가능하도록 설정할
수 있습니다.
2) Mode Bits
: M0 에서 M4까지의 모드 비트는 CPU의 6개의 동작 상태를 나타냅
니다. 즉, 간단히만 말하자면 ARM7은 6개의 동작 모드를 가지는
데, 이를테면 유저모드와 인터럽트 모드 등 입니다. 역시 자세
한 내용은 다음 강좌를 통해 말씀드리겠습니다.
이제 스테이터스 레지스터를 한번 그려보겠습니다.
------------------------------------------------------------------
| N | Z | C | V | ... | I | F | | M4 | M3 | M2 | M1 | M0 |
------------------------------------------------------------------
Bit 31 30 29 28 7 6 4 3 2 1 0
오늘은 ARM7의 레지스터에 대해 기본적인 내용을 알아보았습니다. 하지만
많은 부분에서 ARM7 의 동작 모드와 관련되는 부분이 나왔지요. 때문에 다
음 시간으로 미룬 부분들이 많군요.
다음 강좌에서는 ARM7 Exception 에 대해서 다루려고 합니다. 오늘은 이만
줄이겠습니다.