공부

20200916 공부

글로벌디노 2020. 9. 16. 21:55

엔디언

함수포인터

switch case

구조체 패딩

 

 

 

 

엔디언 메모리 저장 방법

리틀엔디언   하위->상위

빅엔디언      상위->하위

 

 

함수포인터

함수포인터를 배열에 넣고 사용해보기

#include <stdio.h>

int sum(int a, int b)
{
	return a + b;
}

int sub(int a, int b)
{
	return a - b;
}

int mul(int a, int b)
{
	return a * b;
}

int main()
{
	int (*calcs[3])(int, int);

	calcs[0] = sum;
	calcs[1] = sub;
	calcs[2] = mul;


	int a = calcs[0](10, 20);
	int b = calcs[1](20, 10);
	int c = calcs[2](10, 2);

	return 0;
}

 

 

switch case

 

테스트 케이스 1

// Release 64bit 코드최적화없음

#include <stdio.h>

int main()
{
	int num = 3;
	int sum = 0;

	switch (num)
	{
	case 1:
		sum += 1;
		break;
	case 2:
		sum += 2;
		break;
	case 3:
		sum += 3;
		break;
	case 4:
		sum += 4;
		break;
	case 5:
		sum += 5;
		break;
	}

	return 0;
}
	int num = 3;
00007FF677801004  mov         dword ptr [num],3  
	int sum = 0;
00007FF67780100C  mov         dword ptr [rsp],0  

	switch (num)
00007FF677801013  mov         eax,dword ptr [num]  
00007FF677801017  mov         dword ptr [rsp+4],eax  
00007FF67780101B  cmp         dword ptr [rsp+4],1  
00007FF677801020  je          main+40h (07FF677801040h)  
00007FF677801022  cmp         dword ptr [rsp+4],2  
00007FF677801027  je          main+4Ah (07FF67780104Ah)  
00007FF677801029  cmp         dword ptr [rsp+4],3  
00007FF67780102E  je          main+55h (07FF677801055h)  
00007FF677801030  cmp         dword ptr [rsp+4],4  
00007FF677801035  je          main+60h (07FF677801060h)  
00007FF677801037  cmp         dword ptr [rsp+4],5  
00007FF67780103C  je          main+6Bh (07FF67780106Bh)  
00007FF67780103E  jmp         main+74h (07FF677801074h)  
	{
	case 1:
		sum += 1;
00007FF677801040  mov         eax,dword ptr [rsp]  
00007FF677801043  inc         eax  
00007FF677801045  mov         dword ptr [rsp],eax  
		break;
00007FF677801048  jmp         main+74h (07FF677801074h)

num 값을 1, 2, 3, 4, 5 와 일일이 cmp 비교연산한다

 

 

테스트 케이스 2

// Release 64bit 코드최적화없음
#include <stdio.h>

int main()
{
	int num = 70;
	int sum = 0;

	switch (num)
	{
	case 1:
		sum += 1;
		break;
	case 2:
		sum += 2;
		break;
	case 3:
		sum += 3;
		break;
	case 4:
		sum += 4;
		break;
	case 5:
		sum += 5;
		break;
	case 60:
		sum += 6;
		break;
	case 70:
		sum += 7;
		break;
	case 80:
		sum += 8;
		break;
	case 90:
		sum += 9;
		break;
	case 100:
		sum += 10;
		break;
	}

	return 0;
}
	int num = 70;
00007FF68C4E1004  mov         dword ptr [num],46h  
	int sum = 0;
00007FF68C4E100C  mov         dword ptr [rsp],0  

	switch (num)
00007FF68C4E1013  mov         eax,dword ptr [num]  
00007FF68C4E1017  mov         dword ptr [rsp+4],eax  
00007FF68C4E101B  mov         eax,dword ptr [rsp+4]  
00007FF68C4E101F  dec         eax  
00007FF68C4E1021  mov         dword ptr [rsp+4],eax  
00007FF68C4E1025  cmp         dword ptr [rsp+4],63h  
00007FF68C4E102A  ja          $LN13+9h (07FF68C4E10BBh)  
00007FF68C4E1030  movsxd      rax,dword ptr [rsp+4]  
00007FF68C4E1035  lea         rcx,[__ImageBase (07FF68C4E0000h)]  
00007FF68C4E103C  movzx       eax,byte ptr [rcx+rax+10F0h]  
00007FF68C4E1044  mov         eax,dword ptr [rcx+rax*4+10C4h]  
00007FF68C4E104B  add         rax,rcx  
00007FF68C4E104E  jmp         rax  
	{
	case 1:
		sum += 1;
00007FF68C4E1050  mov         eax,dword ptr [rsp]  
00007FF68C4E1053  inc         eax  
00007FF68C4E1055  mov         dword ptr [rsp],eax  
		break;
00007FF68C4E1058  jmp         $LN13+9h (07FF68C4E10BBh)

메모리확인

주소: rcx + 0x10F0

0x00007FF68C4E10F0  00 01 02 03 04 0a 0a 0a
0x00007FF68C4E10F8  0a 0a 0a 0a 0a 0a 0a 0a
0x00007FF68C4E1100  0a 0a 0a 0a 0a 0a 0a 0a
0x00007FF68C4E1108  0a 0a 0a 0a 0a 0a 0a 0a
0x00007FF68C4E1110  0a 0a 0a 0a 0a 0a 0a 0a
0x00007FF68C4E1118  0a 0a 0a 0a 0a 0a 0a 0a
0x00007FF68C4E1120  0a 0a 0a 0a 0a 0a 0a 0a
0x00007FF68C4E1128  0a 0a 0a 05 0a 0a 0a 0a
0x00007FF68C4E1130  0a 0a 0a 0a 0a 06 0a 0a
0x00007FF68C4E1138  0a 0a 0a 0a 0a 0a 0a 07
0x00007FF68C4E1140  0a 0a 0a 0a 0a 0a 0a 0a
0x00007FF68C4E1148  0a 08 0a 0a 0a 0a 0a 0a
0x00007FF68C4E1150  0a 0a 0a 09 cc cc cc cc

메모리확인

주소: rcx + 0x10C4

0x00007FF68C4E10C4  50 10 00 00 5a 10 00 00
0x00007FF68C4E10CC  65 10 00 00 70 10 00 00
0x00007FF68C4E10D4  7b 10 00 00 86 10 00 00
0x00007FF68C4E10DC  91 10 00 00 9c 10 00 00
0x00007FF68C4E10E4  a7 10 00 00 b2 10 00 00
0x00007FF68C4E10EC  bb 10 00 00 00 01 02 03
0x00007FF68C4E10F4  04 0a 0a 0a 0a 0a 0a 0a

 

case를 더 추가했더니 점프테이블이 생겼다

case 가 최소 1, 최대 100 값이라서 그런지 00 01 02 ... 09 까지 100byte의 메모리를 사용해서 인덱스 값을 저장했다

그리고 해당 인덱스에 해당하는 점프시킬 하위주소를 참조할 수 있다

 

rcx 에는 00007FF68C4E0000 값이 들어있고

case가 1인 경우

rax = 1050

rax + rcx -> 00007FF68C4E1050

00007FF68C4E1050 로 점프

위 주소는 case 1: 에 해당하는 명령어주소이다

 

 

 

구조체 패딩

struct Data
{
	short a;
	char b;
	int c;
	int d;
	double e;
	char f;
};

struct Data2
{
	char a;
	Data dt1;
	char b;
};

sizeof(Data) :    32 바이트

short 2

char 1 + padding 1

int 4

int 4 + padding 4

double 8

char 1 + padding 7

 

sizeof(Data2) :   48 바이트

char 1 + padding 7

Data 32

char 1 + padding 7

 

Data에서 double을 주석처리하고 사이즈를 구해보았다

 

Data

short 2

char 1 + padding 1

int 4

int 4

char 1 + padding 3

=> 16 바이트

 

Data2

char 1 + padding 3

Data 16

char 1 + padding 3

=> 24 바이트

 

Data구조체 변수의 최대사이즈에 맞춰서 Data2의 패딩값이 변경됐다

'공부' 카테고리의 다른 글

20200918 테스트 오답노트  (0) 2020.09.18
20200917 공부  (0) 2020.09.18
Console창 생성 및 출력  (0) 2020.09.15
BMP 파일 이미지 데이터 읽기  (0) 2020.09.13
20200905 공부  (0) 2020.09.05