jun-wiki

View My GitHub Profile

Posts (Latest 10 updated) :
Read all
Contents:
  1. csapp 3 : 프로그램의 기계표현
    1. 3.1 역사적 관점
    2. 3.2 프로그램의 인코딩
      1. gcc의 호출 과정
    3. 3.2.1 기계수준 코드
      1. ISA란?
      2. 가상 주소란?

csapp 3 : 프로그램의 기계표현

이번 장에서는 기계어와 이를 사람이 읽을 수 있는 표현 법인 어셈블리 코드를 배운다고 한다



파이썬이나 c같은 고급 언어 대신
왜 그딴 저급 언어를 배우냐?(진짜 모름)



라고 생각하면 큰 오산(경기도 아님)이다

비록 계산 수행 위한 명령들을 하나하나 프로그래머가 지정해야하고

컴파일러가 제공하는 오류 탐지 기능을 비롯한

다른 기계에서의 컴파일 기능 지원까지 포기하며

호환성마저 구린 기계어를 배워야 하는 이유?


그야…


그래야 몸값이 오르니까

어셈블리 코드를 읽고 해석해 최적화 하는 능력등을

기르면 더 고-급 개발자가 되고

당연히 고-급 인력 답게 돈도 고-급으로 받는다

cs gosu가 될거야




3.1 역사적 관점

3장을 다루며 x86-64에 기초를 다루고 있다

그래서 인텔 프로세서의 모델과 머신들의 발전 과정의 역사를 보여준다

이 장에서 하고 싶은 말은

이전 버전과의 하위 호환성 때문에 명령어 집합에 이상한게 있다는 거다

(대충 복잡하고 난해한 기능 같은 건 안다룰거라는 내용)




3.2 프로그램의 인코딩

linux> gcc -Og -o p p1.c p2.c

예시 명령어 하나와 함께 인코딩 과정을 간략히 설명한다

  • p1.cp2.cC 프로그램 파일이다

  • gccC 컴파일러 명칭이다

  • -Og는 기존 구조를 어느 정도 유지하며 기계어 코드로 최적화하는 명령어다

    • -O1, -O2가 더 최적화 좋다고 한다

    • 그치만 이들의 경우 코드를 심하게 변형해 관계를 이해하기 어려워 지금은 -Og를 쓴거다

gcc의 호출 과정

  1. 전처리기 (Preprocessor)
    • #include, #define 등을 처리하여 확장된 소스 코드 생성
  2. 컴파일러 (Compiler)
    • C 코드를 어셈블리 코드(.s) 로 변환
    • p1.s, p2.s로 변환됨
  3. 어셈블러 (Assembler)
    • 어셈블리 코드를 객체 코드(.o) 로 변환 (주소 미완성 상태)
    • p1.o, p2.o로 변환됨
  4. 링커 (Linker)
    • 객체 코드 + 라이브러리 코드를 결합하여 실행 파일 생성
    • 프로세서가 실행하는 최종 형태 코드



7장에서 자세히 다룬다고 한다



3.2.1 기계수준 코드

기계 수준 프로그래밍에선 두가지 중요한 추상화가 존재한다


하나는 기계 수준 프로그램의 형식과 동작은 ISA가 정의 한다는 거고

다른 하나는 사용하는 메모리 주소가 가상 주소라는 거시다

ISA란?

  • 명령어 집합 아키텍쳐
  • 프로세서 상태, 명령어 형식, 미치는 효과 등을 규정한다

가상 주소란?

  • 매우 큰 바이트 배열처럼 보이는 메모리 모델을 제공한다
  • 실제 메모리 시스템은 다르며 이는 9장에도 나와있는 사실이다


컴파일러는 컴파일 과정 중 거의 다 한다.

고급 언어가 제공한 추상적 모델을 단순한 명령들로 바꿔주는 일을 한다

어셈블리 코드는 기계어와 거의 같으며, 차이점은 사람이 읽을 수 있냐 없냐다

어셈블리 코드 이해하고 원래의 C코드 등과 연결 방법을 파악하는게 컴퓨터 이해의 ⌜핵심⌟ 이다


x86-64의 기계어는 C코드와 매우 다르다
프로세서 상태가 드러나니

(아아 두렵다)

  • 예시)
    • 프로그램 카운터
    • 정수 레지스터
    • 조건 코드 레지스터
    • 벡터 레지스터


C언어에서 지원하는 여러 모델들과 다르게

기계어는 메모리를 바이트 배열로만 본다는 내용

기계어 명령은 무척 단순해 여러 기계어 명령을 조합한다는 내용



___