독하게 되새기는 C 프로그래밍

minseok·2023년 8월 18일
0

https://www.inflearn.com/course/독하게-되새기는-c프로그래밍/dashboard

강의에서 알려주는 것

1. 컴퓨터 이론 재정리 (컴퓨터는 어떻게 더하는 가?)
2. 컴퓨터 구조와 컴파일러의 이해
3. stack frame 구조와 원리
4. 변수와 상수에 대한 고급 이론과 컴파일러 최적화
5. 멀티 스레드 (생성 및 동기화)
6. 가상 메모리와 IPC
7. 동기 비동기, 파일 입력 출력
8. 정적/동적 라이브러리 개발
9. 보안 시큐어 코딩

컴퓨터 언어 서적, 강의에서 알려주는 보편적인 문법위주의 강의가 전혀 아니며 C를 도구로 사용해서 컴퓨터에 대하여 알려주는 강의

오히려 내용 자체는 면접용 CS 강의 포지션이며 IDE, 메모리 뷰어, 어셈블리어를 사용해 강의를 진행하고 동시에 직접 실습하니 시간은 더 걸리지만 무작정 외우는 것 보다는 좋은 것 같고 재미있음






섹션 1

Byte Order

1.'0x12345678'인 4byte의 데이터가 존재한다.
2. 1Byte씩 분리한다.(1바이트가 메모리에 접근하는 최소 단위이며 16진수로 표기하여 16진수 2개가 1바이트를 표현, 256개)
3. "12", "34", "56", "78"가 나옴

  • Big Endian : 12 34 56 78
  • Little Endian : 78 56 34 12

Mac환경 Visual Studio Code의 메모리 뷰어도 기본적으로 Litten Endian이 적용

다른 Byte Order를 사용하는 호스트끼리는 통신이 안된다고 합니다.


문자 배열

  1. "문자열"은 사실상 "문자 배열"으로 표현하는 것이 정확함
  2. "문자 배열"은 상수가 아니다.
  3. 상수인 문자들의 배열에 R--권한만 설정해 상수처럼 다루는 것

data의 영역

  • Heap : malloc같은 것으로 할당 [할당 시점 : Run]
  • Stack : 자동변수, 함수가 종료되면 자동으로 할당 해제 [할당 시점 : Run]
  • Static : R--(문자배열 포함), RW- [할당 시점 : Compile, 관련된 값은 Executable File에 저장된다.]

16진수 편집기를 사용해서 Executable File의 상수를 수정하고 실행시키면 코드를 작성했던 값이 아니라 위변조된 값이 적용된다.






섹션 2

컴파일러 구성요소

Front-end :

  • Lexical analyzer(어휘 분석기) : 문장을 토큰의 집합으로 변환
  • Syntax analyzer(구문 분석기) : 출력한 토큰으로 구문트리를 생성, 토큰 간의 관계가 올바르게 생성되었는지 검사
  • Semantic analyzer(의미 분석기) : 정수를 0으로 나누기, 정수와 문자 배열의 덧셈같은 의미적인 부분을 검사

Back-end :

  • Code generator(코드 생성기) :
  • Assembler(어셈블러) :






섹션 3

호출관계와 void

Caller : 호출자
Callee : 피호출자
void : 성공, 실패같은 부분을 고려하지 않는다.

매개변수 전달 기법

전달 방식

  • Call by value : 스택에 값 복사
  • Call by address : 복사하는 값이 메모리의 주소
  • Call by reference : C언어는 참조형이 없으며 포인터로 구현
    (reference, address 모두 고급 언어의 개념, 두 방식 모두 기계어에서 보면 같은 동작을 한다.)

매개변수 저장공간 Register?, Stack?

  • 요즘 컴파일러들은 모두 매개변수를 Stack을 사용하지 않고 Register공간을 사용 (main memory에 접근하지 않고 processor에 접근)

Stack

공간크기 : 512KB ~ 1MB 언저리, 1개 호출에서 Stack의 공간이 넘어가면 StackOverFlow가 일어난다.

  • 스택에 데이터는 '메모리 주소 0번지'방향으로 쌓는다. (배열의 요소는 반대로 오름차순으로 쌓는다. [x86, x64에 따라 다를 수 있음])

함수

inline : callee의 내용을 caller에 넣는다. 함수 호출에 의한 오버헤드가 줄어듦

함수 포인터

  • 함수의 이름은 그자체가 주소
  • 콜백 함수와 동일한 개념
int add(int a, int b) {
    int result = a + b;
    return result;
}

int main(void) {
    int result = 0;
    // 일반적인 호출
    result = add(3, 4);
    printf("Result: %d \n", result);
    
    // 함수 포인터 사용
    int (*pfAdd)(int, int) = add;
    result = pfAdd(3, 4);
    printf("Result: %d \n", result);
    
    return 0;
}






섹션 4

Buffered/Non-buffered I/O, Flush

  • File Interface(Kernel과 User영역을 연결)에는 Buffer가 존재
  • File 입출력에 Buffered, Non Buffered를 정해야 한다.(작업의 성격에 따라 다르다.)
  • Input Buffer와 Out Buffer가 따로 존재한다.

동기/비동기 File 입/출력

  • I/O 요청 : 현재 동작중인 운영체제(software)에게 I/O 요청을 전달하는 것

동기 방식

  • 운영체제(process)와 내가 추가로 실행시킨 A 프로그램(process)이 있으며 A 프로그램이 운영체제에게 I/O요청 처리를 전달,
    이 후 A 프로그램은 wait상태로 들어가서 아무것도 안하고 기다린다.

비동기 방식

  • 운영체제에(process)게 요청을 전달하고 기다리지 않고 A 프로그램은 다른 일을 한다.

동기/비동기?

  • 요청자 관점에서만 존재하는 개념이다.

thread 동기화
임계구간 코드가 여러 스레드(multi thread)에서 동시에 실행되는 것을 막는 것

동기화 객체를 이용해 구현

  • Critical Section (User Mode, 비용이 저렴)
  • Mutex (Kernel Object, 비용이 비쌈)
  • Semaphore (Kernel Object, 비용이 비쌈)

임계 구역

  • 고급 언어 식 1개는 어셈블리어로 라인 2개 이상, 고급 언어 식 1개는 원자성을 가지지 못함
  • 스레드 동기화를 하고싶다면 언어차원에서 지원하는 동기화 방식(C : CRITICAL_SECTION Keyword)을 찾아보기
  • 잘 구현된 외부 서비스를 이용하기(Redis, aws sqs)
profile
즐겁게 개발하기

0개의 댓글