사용 보드 정보

Vendor: Nuvoton

Device: M2351KIAAE

 

사용 툴: uVision Keil

 

Stack pointer도 일단은 register이기 때문에 직접 조작하려면 assembly가 필요하다. 따라서 __asm__ __volatile__ 키워드를 통해 arm inline assembly를 사용한다.

 

1. Inline assembly의 literal string에 직접 써서 옮기기

예를 들어 0x20만큼 옮긴다고 하면,

 

__asm__ __volatile__("SUB sp, sp, #0x20");

// ... main firmware routine

__asm__ __volatile__("ADD sp, sp, #0x20");

 

2. Input operand를 사용하여 임의의 offset만큼 옮기기

예를 들어 STACK_OFFSET_MEM에 임의의 offset을 저장했다고 하면,

SUB sp, sp, Rm의 형태는 사용할 수 없으므로 연산 가능한 레지스터에 값을 옮기고 연산하여 다시 stack pointer에 집어넣는 방식을 취한다. Lo register (r0 ~ r7)은 실행 과정에서 자주 사용되므로 잘 안쓰는 레지스터에 값을 백업해두고 복원하였다.

 

__asm__ __volatile__(" \
MOV r11, r3; \
MOV r10, r4; \
MOV r4, sp; \
ADDS r3, r4, %0; \
MOV sp, r3; \
MOV r3, r11; \
MOV r4, r10 \
" \
: \
: "r"(STACK_OFFSET_MEM) \
);

// ... main firmware routine

// (SUBS STACK_OFFSET_MEM)

 

여기서 임의의 값은 M2351KIAAE보드의 TRNG 함수를 사용해서 가져왔다.

thumb모드의 제약과 input operand 문법이 생소해서 고생했다..

 

Inline assembly 참고 링크

https://developer.arm.com/documentation/dui0489/i/arm-and-thumb-instructions/sub

 

http://www.ethernut.de/en/documents/arm-inline-asm.html

 

http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html

 

https://developer.arm.com/documentation/100748/0617/Using-Assembly-and-Intrinsics-in-C-or-C---Code/Writing-inline-assembly-code?lang=en

 

Arm embedded program flow 참고 링크

http://www.vlsiip.com/c/embedded_c/ec_0002.html

 

http://recipes.egloos.com/5044366

 

https://openmicrolab.com/arm-cortex-m0-%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98/

 

__scatterload의 역할 참고 링크

https://community.arm.com/support-forums/f/compilers-and-libraries-forum/7240/__scatterload-function-in-arm-c-library/22072

 

 

'프로그래밍 기타' 카테고리의 다른 글

자료형에서의 overflow와 underflow에 대하여  (0) 2021.03.05

+ Recent posts