본문 바로가기

3. Pwnable (포너블)/2) 개념 정리

[2022.04.02] C와 C++을 동시에 배워보자, 달고나 문서 -p.12

<C와 C++을 동시에 배워보자 - 두들낙서의 C/C++>

https://inf.run/eMru

 

[무료] C 와 C++ 을 동시에 배워보자 - 두들낙서의 C/C++ - 인프런 | 강의

C 와 C++ 을 동시에 배울 수 있는 강좌 입니다. 프로그래밍에 대한 입문자나 C ,C++ 을 처음 배우고 싶은 분께 도움이 됩니다., - 강의 소개 | 인프런...

www.inflearn.com

이 강의를

01. Hello, World!부터 05. 자료형 2까지 수강하였습니다.

 

Hello, World!
1. printf를 통하여 Hello, World! 출력하기
 1) #include <stdio.h>: stdio.h라는 파일을 포함한다는 의미가 있다. stdio.h를 통해서 printf가 무엇인지 알 수 있다.
 2) main(): 함수, 명령어 실행 값을 출력한다.
 3) printf: 문자를 출력한다.
 4) ;은 항상 넣어줘야 한다. 마침표와 같은 역할을 한다.

 

Hello, World!가 잘 출력된 것을 확인 가능합니다.

 

2. 과제

 동해물과 백두산이
 마르고
 닳도록

을 ① printf를 한 번 사용해서 출력하기, ② printf를 여러 번 사용해서 출력하기의 두 가지 방법을 이용해서 출력해봅시다.

둘 다 출력이 잘 되는 것을 확인할 수 있습니다.

 

Printf로 다양한 데이터 출력하기

1.  // : 주석, 프로그래머한테만 보여진다.

 

2. %d: 정수를 출력한다. 소수를 넣으면 이상한 값이 나온다.

 1) 정수를 넣는다면?

이렇게 잘 나옵니다.

 2) 소수를 넣는다면?

2.4가 858993459가 되었습니다. (이런...)

 

3. %f: 실수를 출력한다. ② %2f: 소수점 둘째자리까지 출력한다. (반올림한다.)
 1)  %f를 이용하여 출력

3.14인 건 알겠으나, 뒤의 공 네 개가 거슬린다면.

 2) 2%f를 이용하여 출력

깔끔하게 잘 나오는 것을 알 수 있다.

 

4. %g: 실수 출력

5. %c: 문자 출력

 

​6. %s: 문자열 출력 (문자열이란 문자가 열거되어있는 것을 뜻하며, 러시아어, 한자어 등 일부 출력이 되지 않는 언어가 있다. 또한 문자열을 표현하기 위해서 큰 따옴표 “”를 사용한다.)

 

변수란?

1. 변수란?
 1) int a; -> 변수의 자료형 결정. (int는 정수형 변수, a는 변수의 이름으로 설정된다.)
 2) a=3; -> 등호는 a에 3을 대입하겠다라는 것을 의미한다.
 3) 추가로, 변수 이름은 ① 알파벳 대소문자, ②_(언더 바), ③ 숫자(첫번째 글자 제외)를 사용할 수 있다.

 

자료형

1. int 
 ① + : 합, ② - : 차, ③ * : 곱, ④ / : 몫, ⑤ % : 나머지

여기서 / 기호를 이용하면 몫을 나타내는데, 정수끼리의 나눗셈이므로 정수로만 나온다.

 

2. float: 실수를 담는 데 쓰인다. 따라서 %를 사용하면 안 됨. (나머지가 없으니까 오류가 나온다.)

 

3. 자료형 정리

 1) 정수형

 Char(1바이트): 문자를 담는 데 쓰인다.
② Short(2바이트)
③ Long(4바이트)
④ Long long(8바이트)
⑤ Int: 원래 시스템에 의해 결정되는 것이었다. 요즘은 long으로 쓰는 추세. 고로 4바이트이다.

 

 2) 실수형
Float(4바이트)
② Double(8바이트)

 

 3) Unsigned, signed
 Unsigned: 부호 무시

 

 4) Void, bool
 Void: 리턴 값 없는 함수의 자료형
② Bool: 참/거짓 저장하는 자료형(char이랑 유사하다고 볼 수 있다.)

 

 

<달고나 문서 - CPU 레지스터 구조>

레지스터 : CPU 내부에 존재하는 메모리, CPU가 프로세스를 실행하기 전에 필요한 여러 데이터들을 적재시키기 위해 필요한 장소

 

레지스터는 저장 목적에 따라서 범용 레지스터, 세그먼트 레지스터, 플레그 레지스터, 인스트럭션 포인터로 구성된다.

 

범용 레지스터

논리 연산, 수리 연산에 사용되는 피연산자, 주소를 계산하는데 사용되는 피연산자, 그리고 메모리 포인터가 저장되는 레지스터

프로그래머가 임의로 조작할 수 있게 허용되어 있음.

4개의 32bit 변수라고 생각하면 됨.

EAX - 피연산자와 연산 결과의 저장소

EBX - DS segment안의 데이터를 가리키는 포인터

ECX - 문자열 처리나 루프를 위한 카운터

EDX - I/O 포인터

ESI - DS 레지스터가 가리키는 data segment 내의 어느 데이터를 가리키고 있는 포인터. 문자열 처리에서 source를 가리킴.

ED - ES 레지스터가 가리키고 있는 data segment 내의 어느 데이터를 가리키고 있는 포인터. 문자열 처리에서 destination을 가리킴

ESP - SS 레지스터가 가리키는 stack segment의 맨 꼭대기를 가리키는 포인터

EBP - SS 레지스터가 가리키는 스택 상의 한 데이터를 가리키는 포인터

EAX, EBX, ECX, EDX 레지스터들은 프로그래머의 필요에 따라 아무렇게나 사용해도 되지만 나중에 기계어 코드를 읽고 이행하기 편하게 하기 위해 목적대로 사용해주는 것이 좋음.

 

세그먼트 레지스터

code segment, data segment, stack segment를 가리키는 주소가 들어있는 레지스터

CS 레지스터 : code segment 가리킴

DS, ES, FS, GS 레지스터 : data segment 가리킴

SS 레지스터 : stack segment 가리킴

이렇게 세그먼트 레지스터가 가리키는 위치를 바탕으로 우리는 원하는 segment안의 특정 데이터,

명령어들 정확하게 끄집어낼 수 있게 됨.

 

플래그 레지스터

프로그램의 현재 상태나 조건 등을 검사하는데 사용되는 플래그들이 있는 레지스터

컨트롤 플래그 레지스터는 상태 플래그, 컨트롤 플래그, 시스템 플래그의 집합.

- 상태 플래그

CF - carry flag. 연산을 수행하면서 carry 혹은 borrow가 발생하면 1이 된다. Carry borrow는 덧셈 연산시 bit bound 를 넘어가거나 벨셈을 하는데 빌려오는 경우를 말한다.

PF - Parity flag 연산 결과 최하위 바이트의 값이 1이 짝수 일 경우에 1이 된다. 패리티 체크를 하는데 사용된다.

AF - Adjust filag. 연산 컬과 carry borow 3bit 이상 발생할 경우 1이 된다.

ZF - Zero flag 결과가 zero임을 가리킨다. I문 같은 조건문이 만족될 경우 set된다.

SF - Sign fiag 이것은 연산 걸과 최상위 비트의 값과 같다. Signed 변수의 경우 양수이면 0, 음수이면 1이 된다.

OF - Overflow flag. 정수형 결과값이 너무 큰 양수이거나 너무 작은 음수여서 피연산자의 데이터 타입에 모두 들어가지 않을 경우 1이 된다.

DF - Direction ilag. 문자열 처리에 있어서 1일 경우 문자열 처리 instruction이 자동으로 감소(문자열 처리가 high address에 서 ow address로 이루어진다), 0일 경우 자동으로 증가 한다.

 

- 시스템 플래그

IF - Interrupt enable flag. 프로세서에게 mask interupt에 응답할 수 있게 하려면 1을 춘다.

TF - Trap ilag 디버깅을 할 때 single-step을 가능하게 하려면 1을 준다.

IOPL - IO privilege level field. 현재 수행 중인 프로세스 혹은 task의 권한 레벨을 가리킨다. 현재 수행 중인 프로세스의 권한을 가리키는 CPL IO address 영역에 접근하기 위해서는 IO privilege level보다 작거나 같아야 한다.

NT - Nested task 1ag Interrupt chain을 제어한다. 1이 되면 이전 실행 task와 현재 task가 연걸되어 있음을 나타낸다.

RF - Resume fiag Exception debug 하기 위해 프로세서의 응답을 제어한다.

VM - Virtual- -8086 mode 1ag- Virtual- 8086 모드를 사용하려면 1을 준다.

AC - Alignment check fiag 이 비트와 CRO 레지스터의 AM 비트가 set되어 있으면 메모리 레퍼런스의 alignment checking이 가능하다.

VIF - Virtual interrupt flag IF flag의 가상 이미지이다. VIP flag와 결합시켜 사용한다.

VIP - Virtual interupt pending flag 인터럼 트가 pending(경쟁 상태) 되었음을 가리킨다.

ID - Identification flag CPUID instruction 을 지원하는 CPU인지를 나타낸다.

 

인스트럭션 포인터

다음 수행해야 하는 명령이 있는 메모리 상의 주소가 들어가 있는 레지스터

다음 실행할 명령어가 있는 현재 code segment offset 값을 가짐. 이를 통해 하나의 명령어 범위에서 선형 명령 집합의 다음 위치를 가리킬 수 있을 뿐만 아니라 JMP, Jcc, CALL, RET, IRET instruction이 있는 주소값을 가짐

인스트럭션 포인터(EIP)는 소프트웨어에 의해 바로 엑세스 할 수 없고 control-transfer instruction (JMP, Jcc, CALL, RET)이나 interrupt exception에 의해서 제어된다. EIP 레지스터를 읽을 수 있는 방법은 CALL instruction을 수행하고 나서 프로시저 스텍(procedure stack) 으로부터 리턴하는 instruction address 를 읽는 것이다 프로시저 스텍의 return instruction pointer의 값을 수정하고 return instruction(RET, IRET)을 수행함으로 해서 EIP 레지스터의 값을 간접적으로 지정해 줄 수 있다.