Little Endian과 Big Endian

위의 그림은 Big Endian의 메모리 저장 방식이다. Most Significant Byte(최상위 바이트)부터 메모리에 저장을 하여 Least Significant Byte(최하위 바이트)까지 저장하는 방식이다.

위의 그림은 Little Endian의 메모리 저장 방식이다. 메모리에 저장할 때 LSB부터 저장을 하여 MSB까지 저장을 한다. 


이렇게 굳이 2가지로 구분을 해서 저장을 해야 할까? 그냥 Big Endian이든 Little Endian이든 한 가지 방식으로만 통합해서 사용하면 훨씬 편할텐데 왜 이렇게 했을까? 

이유는 Big Endian 방식은 논리적인 것들이나 숫자의 대소 비교를 할 때 Little Endian 방식보다 훨씬 빠르다. 예를 들어서 0x98251501, 0x11251501 있다고 하면, 숫자의 대소 비교는 제일 앞부터 비교를 하는 것이 시간을 단축할 수 있다. 만약 Little Endian 방식으로 사용해서 비교를 한다면 3바이트를 비교한 후, 마지막 바이트까지 검사를 해야 숫자의 대소 비교가 끝날 것이다. 또한 사람이 숫자를 읽고 쓰는 방식과 유사하기 때문에 소프트웨어의 디버깅이 쉽다는 장점이 있다.

하지만 계산에 있어서는 Little Endian 방식이 훨씬 효과적이다. 0x0145와 0xFA99가 있다고 하면 앞에서부터 계산하는 것이 쉽겠는가 뒤에서부터 계산하는 것이 쉽겠는가?

Posted by 知彼知己百戰不殆
,

함수 포인터는 반환형+(*함수이름)+인자로 이루어진다. 함수 이름을 진한색으로 표시한 이유는 단순 함수 이름이 아니라 (*)의 함수 이름이기 때문이다.


printf의 함수 원형(프로토타입) 

int printf (const char*, ...);

↓↓↓↓

타입 추출 (함수 이름만 제거)

int () (const char*, ...);

↓↓↓↓

int (*) (const char*, ...);

symbol table로 나타내면 

 반환형

함수 이름 

 주소

 int (*) (const char*, ...)

printf 

?? 


즉, printf의 함수 타입을 추출해 보면 int (*) (const char*, ...);란 결과를 얻을 수 있다.


자 그럼 내가 만든 함수에서 return 값으로 printf 함수 자체를 반환하면 어떻게 함수 구현을 해야 할까?

일단, 함수의 기본을 보면 예를 들어서 인자는 없고 int형 test함수를 만들고 싶다고 생각했다면 int test(void) { ~~~}를 떠올릴 수 있다. 여기서 반환형은 int, 함수 이름은 test, 인자는 (void) 이다. 

방금 printf 함수의 반환형 int (*) (const char*, ...)라고 하였다. 그렇다면 return printf을 하여서 나오는 반환형은 저 부분이 되어야 하니까 

int (*) (const char*, ...) { ~~ return printf } 가 되게 된다. 여기서 함수 이름을 test로 한다고 하면

int (*test (void)) (const char*, ...) {~~ return printf }

여기서 test(void) 함수 대신 뭐 p를 쓴다던가 단순 변수를 쓰게 되면 그냥 변수가 돼버린다. 주의!!!


이렇게 printf 함수를 반환하는 test함수를 만들었다면, 이걸 main에서 호출해 보자. 방금 만든 test함수의 원형을 살펴보면

맨 처음에 했던 타입 추출하는 방법대로 함수 이름 부분을 (*)로 바꿔주면 된다.

즉, int (*(*)(void)) (const char*, ...) 가 함수 타입 추출이다. 그렇다면 여기에 call이란 함수 포인터 변수를 만들어 준다면?

int (*(*call)(void)) (const char*, ...)

int main()

{

    int (*(*call)(void) (const char*, ...);

    call = test;

}

이렇게 해주면 main에서 내가 만들어준 함수인 test를 호출하고 test함수에서 printf 함수를 리턴하는 것까지 에러, 경고 없이 컴파일이 된다.

'언어 > 큐브인턴(Embedded)' 카테고리의 다른 글

풀업 저항, 풀다운 저항, 플로팅  (0) 2016.08.31
Little Endian, Big Endian  (0) 2016.08.25
리눅스 ASLR 해제  (0) 2016.08.17
C언어 컴파일 과정  (0) 2016.08.16
컴퓨터 구조(CPU, 메모리, 버스) 특강  (0) 2016.08.03
Posted by 知彼知己百戰不殆
,

ㅎㅎ

http://kkamagui.tistory.com/861

https://bpsecblog.wordpress.com/2016/05/16/memory_protect_linux_1/

참고

Posted by 知彼知己百戰不殆
,