관리 메뉴

History

c 언어 온라인 무료강좌 4-2차시 정리 본문

Tipslab 강좌 복습/김성엽 선생님 c 강의 복습

c 언어 온라인 무료강좌 4-2차시 정리

luckybee 2021. 1. 20. 11:11
728x90
반응형

해당 게시물은 김성엽 선생님의 강의를 바탕으로 만든 게시물입니다.

 

4-1 정리 부분에 이어서 글을 쓰겠다. 까먹은 사람들은 아래 링크를 통해서 다시 4-1 글을 보고 오면 된다!

 

c 언어 온라인 무료강좌 4-1차시 정리 (tistory.com)

 

c 언어 온라인 무료강좌 4-1차시 정리

History c 언어 온라인 무료강좌 4-1차시 정리 본문 Prev 1 2 3 4 5 ··· 7 Next

hard-go-head.tistory.com

 

그럼 저번 글에 이어서 다시 글을 써보자. 만약 아래와 같은 코드가 있다.

int main()
{
   short a;
   short *p;
   p=&a;      //== (short*)a
}

이 코드는 a라는 short 변수와 포인터 변수 p가 선언된 후 p에 a의 주소 값을 대입하는 코드이다. 주석에 쓰여있는 코드는 같은 뜻이라는 것을 알려준다.

 

a의 주소위치, p의 주소위치

위에 보이는 그림은 방금 보여준 코드를 그림으로 그린 것이다. bp는 시작 주소이고 bp-1은 a의 시작주소, bp-5는 포인터 변수 p의 시작 주소이다. 

 

p의 변수형은 short이지만 *(포인터)이므로  주소값을 가지는 4바이트 크기이기 때문에 bp-5가 되는 것이다. 포인터형 변수는 4byte 잊지말자. 

 

그러면 어셈블리 해석으로 넘어가면 &연산자와 = 연산자 2번의 연산을 실행한다. 그럼 아래 그림과 같은 과정을 실행한다.

 

연산과정

먼저 &연산을 하고 = 연산을 실행한다. 그러면 a의 주소 값을 AX레지스터에 대입을 하고 a의 시작 주소는 bp-1이다.

=연산에서는 4byte크기만큼 대입을 p의 시작 주소에 대입을 한다. 그 시작 주소는 ptr [bp-5]이다. 뭐를? a의 시작 주소(AX레지스터에 대입했던 값)를!

 

그러면 아래 그림처럼 도출된다.  

연산 결과

a의 시작 주소가 16진수 63이라고 했을 때 p에는 00000063의 데이터가 들어간다. 

 

 

그럼 a에 직접대입하는 코드 a=0x1234;를 해보자

위의 그림처럼 대입이 실행이 되고 2byte의 크기만큼 a의 시작주 소은 ptr [bp-1] 위치에 0x1234가 입력이 된다. 빨간 박스가 결과라고 할 수 있다. 그다음에는 포인터 연산으로 계산해보자

 

*p=0x3377;이라는 코드가 있다. 이런경우에도 *와 =연산이 2개가 있으므로 나눠서 계산해보자

 

연산 과정

우선 *P의 주소에 가서 저장된 값을 가지고 와야하기 때문에 AX레지스터에 ptr [bp-5]의 값을 대입한다. 그다음은 =연산 과정이다. *p가 가리키는 주소의 대상은 short의 자료형이기 때문에 2byte의 크기로 대입을 한다. 어디다가? ptr [AX]에다가 무엇을? 0X3377 값을. 그러면 결과는

 

파란색 박스안의 숫자로 업뎃

파란 박스 안에 숫자로 바뀐다.

 

그럼 이제 지금까지 했던 내용들을 기반으로 계속 글을 쓰겠다

 

만약 P=P+1이라는 연산을 했다고 가정하면 기계어(어셈블리어)로 어떻게 바뀌는지 살펴보자

 

그러면 덧셈연산과 대입 연산이 있다. 이렇게 2가지 연산이 생기는데 사실 더 세부적으로 구분하면 3가지 연산이 존재한다고 볼 수 있다. 왜냐하면 p의 값을 AX레지스터에 대입하기 위한 대입 연산, p+1에서 덧셈 연산 그리고 p+1의 값을 다시 p에 대입하기 위한 대입 연산 총 2가지의 대입 연산과 1가지의 덧셈 연산이 필요하다.

 

지금부터 세부적으로 구분된 연산을 해보겠다. 

우선 p의 값을 AX 레지스터에 대입하는 대입연산이 첫 번째로 실행되고, p+1의 연산과정에서 AX 레지스터에다가 1을 더한다. 이 공식은 AX=AX+1과 같다 왜냐하면 AX값에 1을 더한 값을 다시 AX에 대입하는 상황이기 때문이다. 그러나 여기에서는 1이 더해지는 것이 아니라 2가 더해진다.

 

왜?

 

이 연산은 산술연산이 아니라 주소 연산이기 때문이다. 주소 연산을 할 때는 p가 가리키는 대상의 크기만큼 더해진다. 현재는 short형이라서 2byte가 더해지지만 int형 이면 4byte가 더해질 것이다.

 

만약 현재상황에서 1을 더해서 진짜 1을 더하는 것이 주소 연산이 실행되면 p+1은 p의 위치랑 겹쳐진다. 그래서 정상적이지 않은 코드가 생길 수 도 있다. 

 

그리고 마지막으로 p= 즉 대입 연산을 실행하면 *p의 크기는 4byte니까 4 크기만큼 p의 시작 주소인 ptr [bp-5]로 가서 AX의 값을 대입.

 

그러면 현재 데이터를 기준으로 p=p+1의 코드로 정말 1칸(1byte)만큼 움직이게 하려면 어떻게 해야할까?

 

현재 p는 short자료형이기 때문에 2byte다. 1byte만큼 옮기려면 형 변환 캐스팅을 해줘야 한다. 지금부터 해보자. 

 

먼저 답은 p=(short*)((char*)&p+1) 이거다.

 

하나하나 뜯어보면 ((char*)&p+1) 이 코드는 char형으로 p를 형 변환을 시켰고 +1을 실행했다. 그러면 p는 1byte이고 +1을 하면 1byte씩 늘어나게 된다. 그럼 (short*) 이 코드는 왜 적었을까?

 

왜냐하면 현재 p는 short형이기 때문에 char형과 자료형이 같지 않다. 그래서 char형을 다시 short형으로 형 변환을 시켜줘야하기 때문에 (short*)라는 코드로 형변환을 시켜준 것이다.

 

 

 

포인터에 대해서 대충 암기만 하고 넘어갔었는데 이렇게 원리를 하나하나 파보고 그림판으로 그림 그리면서 블로그를 쓰니까 뭔가 좀 깨닫는 것 같다.

 

 

같이 보면 좋은 선생님의 자료 링크를 같이 올릴게용

 

주소 연산에 대하여 : 네이버 블로그 (naver.com)

 

주소 연산에 대하여

: C 언어 관련 전체 목차 - http://blog.naver.com/tipsware/221010831969 이 글은 제 책(Do it! C언어 ...

blog.naver.com

연산과 자료형에 대한 이야기 : 네이버 블로그 (naver.com)

 

연산과 자료형에 대한 이야기

: C 언어 관련 전체 목차 http://blog.naver.com/tipsware/221010831969 1. 연산에 참여하는 피연산자의 ...

blog.naver.com

[실습] int 정숫값을 바이트 단위로 출력하기 : 네이버 블로그 (naver.com)

 

[실습] int 정숫값을 바이트 단위로 출력하기

: C 언어 관련 전체 목차 https://blog.naver.com/tipsware/221010831969 1. 실습 내용 아래와 같이 int ...

blog.naver.com

 

728x90
반응형
Comments