학습 주제
구조체, 공용체, 포인터, 버퍼 오버플로우
정리한 내용
3.9 Heterogeneous Data Structures(이기종 자료구조)
- C는 서로 다른 유형의 객체를 결합해서 자료형을 만드는 두 가지 방법이 존재.
- ‘struct’ Keyword를 사용해서 선언하는 구조체: 여러 개의 객체를 하나의 단위로 결합
- ‘union’ Keyword를 사용해서 선언하는 공용체: 한 객체를 각각의 다른 자료형으로 참조될 수 있음.
3.9.1 Structures (구조체)
- 서로 다른 자료형을 가진 객체를 그룹화해서 하나의 객체로 묶어주는 자료형을 만든다.
- 구조체의 요소들은 각 이름에 의해 참조된다.
- 구조체의 요소들은 연속적인 메모리 영역에 저장되고 구조체의 포인터가 첫 번째 바이트의 주소라는 점에서 배열과 유사하다.
- 컴파일러는 오프셋을 사용하여 구조체의 구성요소에 대한 참조를 생성한다.
- 위 구조체는 4바이트 짜리 두 개의 int형 타입과, 두 개의 int형 배열 요소, 8바이트 짜리 integer pointer로 구성되어 있다.
- 구조체의 필드에 접근하기 위해 컴파일러는 구조체의 주소에 적절한 오프셋을 추가하는 코드를 생성한다.
어셈블리어(참고)
- Immediate: 상수($기호), Register: 메모리 주소값, Memory: 메모리 영역
movq와 leaq의 차이
- movq와 leaq는 유사한 명령어. 연산식은 동일.
- leaq는 Load Effective Address의 약자 lea에 quad word(8byte)가 붙은 것으로 64비트에서 메모리를 참조하는 operand(피연산자)의 구조를 의미.
- movq는 연산 후 메모리에 접근하여 메모리에 저장된 값을 가져와서 Dest에 저장. 즉 movq는 어셈블리의 ‘대입 연산자’
- leaq는 연산된 ‘주소’값만을 Dest에 저장. 즉 leaq는 주소를 저장하는 연산자
- leaq (%rdx), %rax와 movq %rdx, %rax는 동치이다.
leaq를 사용하는 이유
- 산술 연산에 유연하다.
- 주소 이동에 유리
addq $0x4, %rdx
movq %rdx, %rax
//위와 동치이다. leaq가 더 간단하다.
leaq 4(%rdx), %rax
- 1,2,4,8이 아닌 수로 연산하고 싶을 때 사용
// %rdi : idx
leaq (%rdi, %rdi, 4), %rax // 5*idx
- leaq에 dereference 해야지 movq 이다.
r→j = r→i
- 기계어는 필드 선언 또는 필드의 이름에 대한 어떠한 정보도 포함하지 않고 연속된 메모리 영역에서 offset을 이용한 참조를 통해 접근한다.
3.9.2 Unions (공용체)
- Unions은 하나의 객체가 여러 자료형에 따라 참조될 수 있도록 해서 c언어의 자료형 시스템을 피하기 위한 방법을 제공
- union을 선언하는 문법은 구조체와 동일하지만 의미는 매우 다르다.
- 다른 필드들이 메모리의 다른 블록을 참조하는 것이 아니라 같은 블록을 참조한다. 즉 같은 메모리 영역을 여러 개의 필드가 공유하는 것
- 메모리 절약에 용이하다.
- 공용체 형의 각 필드(멤버)는 동시에 값을 기억할 수 없고 , 전체적으로 한번에 1개의 필드만 값을 기억할 수 있다.
- 데이터 구조에서 서로 다른 두 필드의 사용이 ‘상호배타적(mutually exclusive)’임을 미리 알고 있을 때, 두 개의 필드를 공용체로 선언하면 메모리를 절약할 수 있다. ex) 이진트리
- 공용체는 c타입 시스템에 의해 제공되는 안전성을 우회하기에 버그를 초래 할 수 있다. 즉 불안전하다.
//구조체 선언
struct S3 {
char c;
int i[2];
double v;
};
//공용체 선언
union U3 {
char c;
int i[2];
double v;
};
- 세 개의 필드들은 메모리의 같은 블록을 참조
- 전체 사이즈는 필드의 사이즈의 최댓값이 된다.
3.9.3 Data Alignment(데이터의 정렬 at 구조체)
- 대부분의 컴퓨터 시스템들은 기본 자료형에 대한 사용 가능한 주소를 제한을 둔다. 어떤 객체의 주소는 어떤 값 k값의 배수(2 or 4 or 8 등)가 되도록 한다.
- 이러한 정렬의 제한은 프로세서와 메모리 시스템 간의 인터페이스를 구성하는 하드웨어의 설계를 단순화할 수 있는 장점이 존재한다.
- 따라서 정렬 제한이자 규칙은 모든 K개의 기본 자료형의 주소는 어떤 k값의 배수가 되어야 한다.
- 단일 메모리 연산으로 접근 가능. 메모리 시스템의 효율성 증대
- 정렬의 제한이 없다면 두 번의 메모리 연산을 거쳐야 한다.
- 상단 구조체를 예시로
- 컴파일러가 상단의 9바이트 할당을 사용했다고 가정
- 컴파일러는 c와 j 사이에 3바이트를 추가해서 전체 바이트 수를 12로 만든다.
- 따라서 컴파일러는 구조체 s1의 주소값을 4바이트 단위로 접근할 수 있다.
- 12바이트를 맞추기 위해 여분의 바이트를 붙여주는 것을 ‘패딩(padding)’이라고 한다.
- 다른 예시
'Computer Science > 컴퓨터 구조' 카테고리의 다른 글
[CSAPP] 3.11 Floating-Point Code(부동소수점 코드) (0) | 2023.01.24 |
---|---|
[CSAPP] 3.10 Combining Control and Data in Machine-Level Programs(기계 수준 프로그램에서 제어와 데이터 결합) (0) | 2023.01.24 |
[CSAPP] 3.8 Array allocation and access(배열의 할당과 접근) (0) | 2023.01.23 |
[CSAPP] 3.7 procedures(프로시저) (0) | 2023.01.23 |
[CSAPP] 3.6 Controls(제어문) (0) | 2023.01.22 |