가장 많이 본 글

2014년 10월 21일 화요일

C main design

일반적으로 bootup code는 startup.S로 작성한다.
startup.S에는 다음 내용이 들어간다.
- vector table
- stack pointer 초기화
- 전역변수 초기화
- 기타 이미지 로딩
- pc를 main으로 이동, 꼭 main이 아니어도 되며, startup.S에서 branch 해주기만 하면 된다. 이 때 부터 C 코드를 사용 가능함.
- C code를 사용하려면 기본적으로 변수 초기화, sp 초기화 등을 해야 한다. 하지 않으면 당연히 data abort!

변수의 class
- register variable
- 예약어는 register이며, 쓴다고 항상 적용되지 않고, 성능에 영향을 준다고 판단하면 그냥 stack에 저장한다.
- 단, register를 사용하면, 주소값을 읽을 수 없다. 원래 register에 저장하라고 하는 것이니깐.
- local variable
- auto 예약어인데 일반적으로 생략된다.
- static variable
- global variable

memory layout
- 아래서부터,
- TEXT(program code)
- RODATA(constant)
- DATA(initialized data)
- BSS(uninitialized data)
- HEAP(BSS 이후로 커감)
- STACK(메모리 끝에서 부터 내려옴)
- 원하는 section에 넣으려면, linker를 이용한다.
- t32에서 section 확인하려면, sYmbol.List.SECtion

Inline assembly
- C보다 빠른 처리를 위함이고, __volatile__ 예약어를 사용해야 컴파일러가 맘대로 최적화 하지 않는다
- 일반적인 형태:
- __asm__ __volatile__("" : "" : "" : "")
- clobber는 개발자가 직접 register를 제어한다면 설정, compiler는 사용 못하도록 하며, 생략 가능하다.
- ex.
__asm__ __volatile__("add %0, %1, %2" : "=r" (result) : "r" (kind), "r" (embedded) : "r0", "r1")
r0, r1은 안쓴다는 의미임

Colling Convention
- ARM사에서 제시한 표준: PCS(procedure call standard), APCS(ARM procedure call standard), TPCS(Thumb ~), AAPCS(ARM Arch ~)
- r0, r1은 argument / result
- r2, r3는 argument / scratch register 등등..
- r13: stack pointer
- r14: link register

Call Assembly - C와 Assembly 상호 호출 방법
- Assembly에서 global keyword를 사용하여 선언하고 c에서 사용
- C symbol은 Assembly에서 .extern keyword 사용하여 호출
예시
startup.S
.extern main
BL main
.global MMU_DisableiCache
MMU_DisableiCache :
mrc p15,0,r0,c1,c0,0
bic r0, r0,#R1_I
mcr p15,0,r0,c1,c0,0
mov pc,lr

main.c
int main() {
MMU_DisableiCache();
return 0;
}

Call C++
- C와 Assembly처럼 심볼을 그대로 가져다 쓸 수 없음.
- compiler가 함수명을 가공하기 때문임.
- c++에서는 extern "C" { }를 이용해서 C의 symbol을 가져옴.

댓글 없음: