C언어 코드들을 샘플로 들어가면서 ARM이 왜 효율적인 아키텍쳐라고 불리는지 조금씩 알아봅시다.

--------------------------------------------
함수 호출
--------------------------------------------
펜티엄 계열에서는 함수 호출과 리턴에 각각 CALL, RET라는 명령어를 사용합니다.
hello();
// CALL _HELLO
void hello() { return; }
// RET
그런데 ARM에서는 함수 호출은 BL(CALL과 역할이 비슷)을 사용하고, 리턴은 MOV명령을 사용합니다.
함수 호출시 실행주소가 LR레지스터에 들어가므로
리턴할때 LR레지스터에 있는 주소를 PC(프로그램카운터)로 되돌리는 것만으로도
RET와 같은 효과가 나기 때문입니다.
(이 방식은 호출이 빈번한 함수의 경우, 스택에 매번 리턴 어드레스를 저장하지 않는다는 점에서 상대적인 장점을 가집니다)
당연한 이야기지만 이런 이유로 ARM에는 RET명령어가 없습니다.
hello();
// CALL _HELLO
void hello() { return; }
// MOV PC, LR
--------------------------------------------
파라메터 세팅
--------------------------------------------
펜티엄에서는 함수에 파라메터를 전달할때 모두 스택에 넣어야 합니다.
예를 들어, 4개의 파라메터를 가지는 함수의 경우 기본적으로 9개의
어셈블리 명령어가 필요합니다.
hello(10,20,30,40)
// MOV AX, 40
// PUSH AX
// MOV AX, 30
// PUSH AX
// MOV AX, 20
// PUSH AX
// MOV AX, 10
// PUSH AX
// CALL _HELLO
반대로 ARM같은 경우에는 4개의 파라메터까지는 그냥 레지스터에 넣고
함수 호출이 가능합니다. 기본적으로 5개의 어셈블리 명령어로 함수 호출이
가능합니다.
hello(10,20,30,40)
// MOV R1, 10
// MOV R2, 20
// MOV R3, 30
// MOV R4, 40
// CALL _HELLO
참고로, 펜티엄상의 PUSH, POP은 파이프라인의 효율적인 스퍼스칼라을 동작을 방해합니다. (*1)
같은 동작을 함에 있어
펜티엄의 경우 최소 10클럭이 필요하지만,
ARM에서는 이론상 최소 3클럭(MOV4개 1클럭, CALL 2클럭)만으로 함수 호출이 가능합니다.
C/C++ 계열의 언어에서 함수 호출이 엄청나게 빈번한데,
ARM이 펜티엄 계열보다 클럭이 낮아도 꽤 괜찮은 성능을 내는 이유중의 하나입니다.
(*1) PUSH, POP은 RISC계열의 CPU들에서는 악(惡)으로 간주되어서
명시적인 SP레지스터와 PUSH, POP 명령어가 없습니다.
수퍼스칼라가 몇개건 PUSH, POP을 사용하는 동안에는 하나의 명령어만이 실행가능합니다.
참고로, 대개의 RISC계열예서는 범용 레지스터중 하나를 SP로 사용하며
그 SP조차조 ADD 또는 SUB 명령으로 PUSH, POP 효과를 냅니다.