엔디언 메모리 저장 방법
리틀엔디언 하위->상위
빅엔디언 상위->하위
함수포인터
함수포인터를 배열에 넣고 사용해보기
#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 |