임베디드/임베디드 레시피

Context와 AAPCS

twoweeks-within 2024. 12. 3. 20:07

 

Context : 현재 CPU 대한 모든 정보( == Register들의 현재 값들)

 

 

Context

 

 

현재 System이 동작하는데 필요한 모든 정보를 담고 있음.

 

 R0~R12 : CPU의 연습장.

 R13 : Stack Pointer, 현재 CPU가 사용하고 있는 Stack의 주소 중,, 마지막 Push한 Data가 있는 곳의 주소.

 R14 : Linked Register ::어디서 왔는지, 어디로 돌아가야 하는지에 대한것,

 R15 : (PC) : 현재 실행 주소 정보

 CPSR : 현재 CPU의 상태에 대한 주소.

 

 Register 값들만 잘 보존하면 pc를 왔다갔다 가능

  > Function Call

void ContextDaughter();

void ContextMother (void)
{
     나불나불나불~
     ①
     ContextDaughter ();
     궁시렁궁시렁~
}

ContextMother >ContextDaughter 호출

 

①에서의 Register의 모양

 R0~R12 :여러 가지 값

R13 :현재 SP (Stack Pointer) :: 0x1000

R14 : ContextMother가 실행된 후에 돌아가야 할 곳 > 0x2000

R15 (PC) 현재 실행되고 있는  PC값( ①):: 0x1500

 

 ContextDaughter()로  진입

 > R0~R12는 ContextDaughter 마음대로 주물럭 거릴 테고, R13은 역시 철없는 ContextDuaghter가 Data를 Push/ pop한 만큼 증가되거나, 감소될 거구요. R14는 만질 수도 있고, 안만질 수도 있고요. 물론 PC (R15)는 branch를 했으니까 값이 바뀌겠죠.
 >> 레지스터 값들이 마아악 바뀜 

// 안바뀌게 하는게 목적인데

 

void ContextMother (void)
{
    나불나불나불~
    ①
    ContextDaughter ();
    ②
    궁시렁궁시렁~
}

>>

 ① : 어딘가에 저장해 놓았다가, ② 순간에 다시 ①로 복기

 

void ContextMother (void)
{
   나불나불나불~
    /* ContextDaughter() 가 있던 자리 */
    궁시렁궁시렁~
}

 >> 이렇게  ContextDaughter() 는 없는셈취급함으로서

       > 맘 편하게 레지스터 값, 스택변경 걱정없이 함수를 호출 할 수 있음

 

 ContextDaughter() 호출

 > ContextDuaghter()가 연습장으로 쓸 Register들을 Stack에 Push

 

ex) R3, R4, R5 > ContextDaughter()함수의 초입에는 push R3, R4, R5를 해주는 코드 삽입

>  SP (R13) : Stack의 용도에 맞게 사용

 

(Thumb mode )

void ContextMother (void)
{
0x1500 | 나불나불나불~
0x1502 | /* ContextDaughter() 가 있던 자리 */
0x1504 | 궁시렁궁시렁~
}

 

R14 :  0x1504

 

 ContextDaughter()도 다른 함수를 또 부를지 모름

   > R14도 Stack에 같이 Push.

 

CPSR

 > Function Call : ContextDaughter() > CPSR을 Flag field를 제외한 나머지 값들을 수정하는 routine이 있어서는 안됨

> ContextDaughter() 진입, push {R3, R4, R5, R14}.

      > ContextDaughter() 종료   pop{R3, R4, R5, pc}

     :: 이전과 같은 Context 유지

// Push: 스택에 데이터를 넣는 작업

// Pop: 스택에서 데이터를 꺼내는 작업

 

Callee (호출된 함수)에서 Register값을 변경 > Caller함수에서 Register값이 변경 > 문제발생

    :  Callee  > Caller로 복귀 할때

  >  원래대로 복구해야함

 

Scratch Register (R0~R3, R12) : Callee가 마음대로 변경 및 수정, 훼손에 대한 권리를 갖고 있음 

    > " AAPCS " : R0~R3은 Return값과 Callee 함수에 대한 Passing Parameter를 넘겨줄 수 있음

 

Function Call :  

1)

Scratch Register를 훼손하였으나, 다른 함수를 호출하지 않는 경우 ( ==Leaf 함수)

   > Stack에 Backup필요 X,

   > 복귀 : MOV pc, lr

// Linked Register : 복귀할주소

2)

Scratch Register 훼손하였고, 그 함수가 또 다른 함수를 불렀을 경우

  >  lr > stack에 넣어줌

  >  복귀 : stack에 있은 lr을 pop > pc에 넣어줌

 

 >>  Exception 순간, Function Call, Scheduler에 의한 Context Switching 

       > 다 비슷한 의미

 

 

'임베디드 > 임베디드 레시피' 카테고리의 다른 글

struct , packed  (0) 2024.12.05
Pointer  (0) 2024.12.04
Scatter Loading 주의점, heap 및 stack  (2) 2024.12.02
Reset Handler에서 main까지 (Entry Point)  (0) 2024.12.01
Coprocessor Assembly  (0) 2024.11.27