사용 보드 정보
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
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의 역할 참고 링크
'프로그래밍 기타' 카테고리의 다른 글
자료형에서의 overflow와 underflow에 대하여 (0) | 2021.03.05 |
---|