728x90

책/CSAPP 30

CSAPP 3.10.3 - 3.10.5

CSAPP 3.10.3 범위를 벗어난 메모리 참조와 버퍼오버플로우 C에서 배열참조시 범위를 체크하지 않으며, 지역변수들이 스택에 보존용 레지스터들과 리턴주소 같은 상태 정보와 함께 스택에 저장된다. 이러한 조합 때문에 심각한 프로그램 에러가 발생할 수 있는데, 스택에 저장된 상태정보가 범위를 벗어난 배열의 원소에 대한 쓰기 작업에 의해 변경되는 것이다. 그러고 나서 프로그램이 레지스터값을 재 적재하거나 이렇게 변경된 상태정보를 사용해서 ret인스트럭션을 실행할 때, 심각한 결과를 초래한다. 일반적인 상태손실을 버퍼오버플로우라고 알려져있다. 일반적으로 gets나 저장공간을 오버플로우하게 되는 함수를 사용하는 것은 나쁜 프로그래밍 습관으로 평가한다. 자주 사용하는 strcpy,strcat,sprintf 같이..

책/CSAPP 2024.01.26

CSAPP 3.10.2

CSAPP 3.10.2 실제 적용하기 : GDB 디버거 사용하기 GDB를 사용하며, 프로그램의 실행을 정교하게 제어하면서 실행되는 프로그램을 관찰하여 프로그램의 동작을 분석할 수 있다. 일반적인 방법은 브레이크 포인트(BreakPoint)를 프로그램에서 관심이 있는 부분 근처에 설정하는 것이다. 함수의 시작 직후나 프로그램의 특정 주소에 설정할 수 있다. 프로그램 실행중에 브레이크 포인트를 만나게 되면, 프로그램은 실행을 중단하고, 제어를 사용자에게 넘긴다. 브레이크 포인트로부터 레지스터나 메모리 위치의 값을 다양한 형식으로 조사할 수있다.

책/CSAPP 2024.01.26

CSAPP 3.9 - 3.10

CSAPP 3.9 이기종 (Heterogeneous) 자료구조 C는 서로 다른 유형의 객체를 연결해서 자료형을 만드는 두 가지 방법을 제공한다. Struct 키워드를 사용해서 선언하는 구조체는 다수의 객체를 하나의 단위로 연결한다. 키워드 union으로 선언하는 공용체는 하나의 객체를 여러개의 다른 자료형으로 참조 될 수 있도록 한다. 3.9.1 구조체 C struct 선언은 서로 다른 유형의 객체들을 하나의 객체로 묶어주는 자료구조를 생성한다. 하나의 구조체 내의 서로 다른 컴포넌트들은 이름을 이용해서 참조된다. 구조체의 구현은 구조체의 모든 컴포넌트들이 메모리의 연속된 영역에 저장되며, 구조체의 포인터가 첫번째 바이트의 주소라는 점에서 배열과 유사하다. 컴파일러는 각 필드의 바이트 오프셋을 가리키는 ..

책/CSAPP 2024.01.25

CSAPP 3.8

CSAPP 3.8 배열의 할당과 접근 C에서 배열을 스칼라 데이터를 보다 큰 자료형으로 연계 시키는 수단이다. 한가지 특이한 점은 배열 원소들에 대한 포인터를 만들고 이들 포인터간에 연산을 할 수 있다는 점이다. 이것은 기계어에서 주소 계산으로 번역된다. 3.8.1 기본원리 자료형 T와 정수형 상수 N T A[N]; 시작하는 위치를 xA라고 표시했을 때, 이 선언은 두 가지 효과를 갖는다. 이것은 L*N 바이트의 연속적인 공간을 메모리에 할당하며, 여기서 L(바이트의 단위)은 자료형 T의 크기를 나타낸다. 새로운 식별자 A를 통해서 배열이 시작하는 위치의 포인터로 사용한다. 이 포인터의 값은 xA다. 배열의 각 원소는 0에서 N-1 사이의 정수형 인덱스를 사용해서 접근 가능하다. 배열의 원소 i는 xA ..

책/CSAPP 2024.01.23

CSAPP 3.6.5 - 3.7

CSAPP 3.6.5 조건부 분기를 조건 제어로 구현하기 C에서 조건부 수식과 문장을 기계어 코드로 번역하는 가장 일반적인 방법은 조건부 및 무조건 점프를 함께 사용하는 것이다.(일부 조건문은 제어의 이동보다 데이터 이동으로 구현 할 수 있다.) GOTO문을 사용하는 것은 코드를 해독하고 디버깅하기 어렵게 할 수 있기 때문에 일반적으로 나쁜 프로그래밍 스타일이다. 3.6.6 조건부 이동으로 조건부 분기 구현하기 조건부 동작을 구현하는 전형적인 방법은 조건이 만족되면 프로그램의 한 가지 실행경로를 따르고, 아닌 경우에는 다른 경로를 따라가도록 하는 제어의 조건부 전환을 통해 이루어진다. 이 방법은 간단하고 일반적이지만 최신 프로세서들에서는 매우 비효율적일 수 있다. 또 다른 전략은 데이터 조건부 전송을 이..

책/CSAPP 2024.01.22

CSAPP 3.5 - 3.6.4

CSAPP 3.5 산술연산과 논리연산 각 인스트럭션 클래스는 네개의 서로 다른 크기의 데이터 연산을 갖는다. 연산들은 4개의 그룹으로 나누어진다. 유효주소 적재 단항(Unary) 이항(Binary) 쉬프트(Shift) 이항연산은 두개의 오퍼랜드를 가지는 반면, 단항연산은 한개의 오퍼랜드를 갖는다. 3.5.1 유효주소 적재(Load Effective Address) 유효주소 적재 인스트럭션 leaq는 실제로는 movq 인스트럭션의 변형이다. 메모리에서 레지스터로 읽어들이는 인스트럭션의 형태를 갖지만, 메모리를 전혀 참조하지 않는다. 이 인스트럭션의 첫번째 오퍼랜드는 일종의 메모리 참조처럼 보이지만, 가리키는 위치에서 읽기를 수행하는 대신에 유효주소를 목적지에 복사한다. 이 인스트럭션은 나중에 메모리 참조에..

책/CSAPP 2024.01.20

CSAPP 3.4

CSAPP 3.4 3.4 정보 접근하기 x86-64 주처리 장치 CPU는 64비트를 저장할 수 있는 범용 레지스터 16개를 보유한다 레지스터는 정수 데이터와 포인터를 저장하는데 사용한다. 인스트럭션들은 16개의 레지스터 하위 바이트들에 저장된 다양한 크기의 데이터에 대해 연산 할 수 있다. 바이트 수준 연산은 가장 덜 중요한 바이트에 대해 연산, 16비트 연산은 덜 중요한 2바이트, 32비트는 4바이트 , 64비트 연산은 레지스터 전체에 접근한다. 일반적인 프로그램에서 서로 다른 레지스터들은 서로 다른 목적으로 이용한다. 스택 포인터 %rsp는 런타임 스택 끝 부분을 가리키기 위해 사용된다. 일부 인스트럭션들은 특별히 이 레지스터를 읽고 쓴다. 다른 15개의 레지스터는 사용이 저금 더 자유롭다. 3.4...

책/CSAPP 2024.01.20

CSAPP 3.1 - 3.3

CSAPP 어셈블리 코드를 짤때 저급 인스트럭션을 명시해야 하는데, 대개의 경우 고급 언어가 제공하는 높은 수준의 추상화를 사용하는 것이 보다 더 생산적이고 안정적이다. 그렇다면 왜 WHY 기계어를 사용하고 공부할까? 컴파일러를 적절한 커맨드라인 인자와 함께 호출하면 컴파일러는 어셈블리 코드 형태의 파일로 출력을 생성한다. 이 코드를 이해하면 컴파일러의 최적화 성능을 알 수 있고, 코드에 내재된 비효율성을 분석할 수 있다. 프로그램이 얼마나 효율적으로 실행될지 이해하기 위해서 생성된 어셈블리 코드를 컴파일하고 분석해 보곤한다. 더욱이 고급언어에서 제공하는 추상화 계층 때문에 이해 가능한 프로그램의 런타임 동작이 감춰지는 경우도 종종 있다. 또 다른 예로 악성 프로그램이 시스템을 감염 시킬 수 있도록 프로..

책/CSAPP 2024.01.20

CSAPP 1.7 - 1완

CSAPP 1.7 - 1끝 운영체제는 하드웨어를 관리한다. 운영체제는 하드웨어와 소프트웨어 사이 소프트웨어 계층. 응용프로그램이 하드웨어를 제어하려면 언제나 운영체제를 통해서 해야 한다. 운영체제의 2가지 목적 제멋대로 동작하는 응용 프로그램들이 하드웨어를 잘못 사용하는 것을 막기 위해서 응용프로그램들이 단순하고 균일한 매커니즘을 사용하여 복잡하고 매우 다른 저수준 하드웨어 장치를 조작할 수 있게 이러한 두 가지 목적을 추상화를 통해 달성한다. 추상화에 대해서 여러가지 글들을 봤는데, 그것들이 가져야 할 핵심적인 특징을 가지는 모델을 만드는 것, 어떤 복잡한 것들을 단순화 시켜 표현한 것. 이런 설명들이 많았다. 프로세스 프로그램이 최신 시스템에서 실행될 때 운영체제는 시스템에서 이 한 개의 프로그램만 ..

책/CSAPP 2024.01.20

CSAPP 1.1 - 1.6

정보는 비트와 컨텍스트로 이루어진다. 모든 시스템 내부의 정보 - 디스크 파일, 메모리상의 프로그램, 데이터, 네트워크를 통해 전송되는 데이터- 는 비트들로 표시된다. 서로 다른 객체들을 구분하는 방법은 이를 바라보는 컨텍스트에 의해서다. 다른 컨텍스트에서는 동일한 일련의 바이트가 정수, 부동소수, 문자열 또는 기계어 명령을 의미할 수 있다. 프로그램은 다른 프로그램에 의해 다른 형태로 번역된다. GCC 컴파일러 드라이버는 소스파일을 읽어서 실행파일로 번역한다. 번역은 4개의 단계를 거쳐서 실행된다. 이 네 단계를 실행하는 프로그램들(전처리기, 컴파일러 ,어셈블러, 링커)을 합쳐서 컴파일 시스템이라고 한다. 전처리 단계 : 전처리기(cpp)는 본래의 C프로그램을 #문자로 시작하는 디렉티브(directiv..

책/CSAPP 2024.01.20
728x90