0. 사담
스터디 모임을 하고 있는데 문제가 나와서 그냥 풀기엔 내 머리속에서 휘발될거 같아서 좀 끄적여 보려고 한다. 답이랑 풀이과정이 틀릴수 있으니 언제나 반박해 줬으면 좋겠다.
1. 실행 후 eax의 값은?
0x0000000000001131 <main+8>: mov DWORD PTR [rbp-0x10],0x1
0x0000000000001138 <main+15>: mov DWORD PTR [rbp-0xc],0x3
0x000000000000113f <main+22>: mov DWORD PTR [rbp-0x8],0x5
0x0000000000001146 <main+29>: mov edx,DWORD PTR [rbp-0x10]
0x0000000000001149 <main+32>: mov eax,DWORD PTR [rbp-0xc]
0x000000000000114c <main+35>: add edx,eax
0x000000000000114e <main+37>: mov eax,DWORD PTR [rbp-0x8]
0x0000000000001151 <main+40>: add eax,edx
풀이 방법으로 선택한 것은 문제의 어셈블리 코드를 C코드로 변환하는 방법이다.
int a = 1; //[rbp-0x10]
int b = 3; //[rbp-0xc]
int c = 5; //[rbp-0x8]
int result = c + (a + b)
eax가 rpb-0x10과 같이 저장공간을 따로 받지는 않았지만 보기 좋게 result로 표현을 해봤다.
그래서 답은 9
2. 실행 후 DWORD PTR [rbp-0x10] 의 값은?
0x0000000000001131 <main+8>: mov DWORD PTR [rbp-0x10],0x0
0x0000000000001138 <main+15>: mov DWORD PTR [rbp-0xc],0x2
0x000000000000113f <main+22>: mov DWORD PTR [rbp-0x8],0x3
0x0000000000001146 <main+29>: mov eax,DWORD PTR [rbp-0xc]
0x0000000000001149 <main+32>: imul eax,DWORD PTR [rbp-0x8]
0x000000000000114d <main+36>: mov DWORD PTR [rbp-0x4],eax
0x0000000000001150 <main+39>: cmp DWORD PTR [rbp-0x4],0x6
0x0000000000001154 <main+43>: jne 0x115f <main+54>
0x0000000000001156 <main+45>: mov DWORD PTR [rbp-0x10],0xff
0x000000000000115d <main+52>: jmp 0x1166 <main+61>
0x000000000000115f <main+54>: mov DWORD PTR [rbp-0x10],0x0
0x0000000000001166 <main+61>: mov eax,DWORD PTR [rbp-0x4]
0x0000000000001169 <main+64>: and DWORD PTR [rbp-0x10],eax
변환!
int a = 0 // [rbp-0x10]
int b = 2 // [rbp-0xc]
int c = 3 // [rbp-0x8]
int d = b * c // [rbp-0x4]
if(d != 6){
a = 0xff
} else {
a = 0
}
a = d & a
이러면 되지 않을까?
그래서 답은 6
3. 실행 후 DWORD PTR [rbp-0x38]의 값은?
0x0000000000001164 <main+27>: mov DWORD PTR [rbp-0x30],0x1
0x000000000000116b <main+34>: mov DWORD PTR [rbp-0x2c],0x2
0x0000000000001172 <main+41>: mov DWORD PTR [rbp-0x28],0x3
0x0000000000001179 <main+48>: mov DWORD PTR [rbp-0x24],0x4
0x0000000000001180 <main+55>: mov DWORD PTR [rbp-0x20],0x5
0x0000000000001187 <main+62>: mov DWORD PTR [rbp-0x1c],0x6
0x000000000000118e <main+69>: mov DWORD PTR [rbp-0x18],0x7
0x0000000000001195 <main+76>: mov DWORD PTR [rbp-0x14],0x8
0x000000000000119c <main+83>: mov DWORD PTR [rbp-0x10],0x9
0x00000000000011a3 <main+90>: mov DWORD PTR [rbp-0xc],0xa
0x00000000000011aa <main+97>: mov DWORD PTR [rbp-0x38],0x0
0x00000000000011b1 <main+104>: mov DWORD PTR [rbp-0x34],0x0
0x00000000000011b8 <main+111>: jmp 0x11ca <main+129>
0x00000000000011ba <main+113>: mov eax,DWORD PTR [rbp-0x34]
0x00000000000011bd <main+116>: cdqe
0x00000000000011bf <main+118>: mov eax,DWORD PTR [rbp+rax*4-0x30]
0x00000000000011c3 <main+122>: add DWORD PTR [rbp-0x38],eax
0x00000000000011c6 <main+125>: inc DWORD PTR [rbp-0x34]
0x00000000000011ca <main+129>: cmp DWORD PTR [rbp-0x34],0x9
0x00000000000011ce <main+133>: jle 0x11ba <main+113>
변환!
int a[10] = [1,2,3,4,5,6,7,8,9,10]; // [rbp-0x30 ~ rbp-0xc]
int b = 0; // [rbp-0x38]
int c = 0; // [rbp-0x34]
while(c <= 9){
b = b + a[c];
c++;
}
일단 main+118에서 일정한 간격마다 값을 참조하기 떄문에 배열로 표현을 해봤다.
코드 또한 1부터 10까지 더하는 것이니
답은 55
4. 실행 후 rbp-0x10에 해당하는 값은?
0x000000000040110e <+8>: mov DWORD PTR [rbp-0x40],0x1
0x0000000000401115 <+15>: mov DWORD PTR [rbp-0x3c],0x3
0x000000000040111c <+22>: mov DWORD PTR [rbp-0x38],0x7
0x0000000000401123 <+29>: mov DWORD PTR [rbp-0x34],0xd
0x000000000040112a <+36>: mov DWORD PTR [rbp-0x30],0x15
0x0000000000401131 <+43>: mov DWORD PTR [rbp-0x2c],0x1
0x0000000000401138 <+50>: mov DWORD PTR [rbp-0x28],0xd
0x000000000040113f <+57>: mov DWORD PTR [rbp-0x24],0x1b
0x0000000000401146 <+64>: mov DWORD PTR [rbp-0x20],0xd
0x000000000040114d <+71>: mov DWORD PTR [rbp-0x1c],0x1
0x0000000000401154 <+78>: mov DWORD PTR [rbp-0x4],0x1e
0x000000000040115b <+85>: mov DWORD PTR [rbp-0x8],0x0
0x0000000000401162 <+92>: mov DWORD PTR [rbp-0xc],0x0
0x0000000000401169 <+99>: jmp 0x4011a3 <main+157>
0x000000000040116b <+101>: mov eax,DWORD PTR [rbp-0xc]
0x000000000040116e <+104>: cdqe
0x0000000000401170 <+106>: mov eax,DWORD PTR [rbp+rax*4-0x40]
0x0000000000401174 <+110>: cmp DWORD PTR [rbp-0x4],eax
0x0000000000401177 <+113>: jle 0x401185 <main+127>
0x0000000000401179 <+115>: mov eax,DWORD PTR [rbp-0xc]
0x000000000040117c <+118>: cdqe
0x000000000040117e <+120>: mov eax,DWORD PTR [rbp+rax*4-0x40]
0x0000000000401182 <+124>: mov DWORD PTR [rbp-0x4],eax
0x0000000000401185 <+127>: mov eax,DWORD PTR [rbp-0xc]
0x0000000000401188 <+130>: cdqe
0x000000000040118a <+132>: mov eax,DWORD PTR [rbp+rax*4-0x40]
0x000000000040118e <+136>: cmp DWORD PTR [rbp-0x8],eax
0x0000000000401191 <+139>: jge 0x40119f <main+153>
0x0000000000401193 <+141>: mov eax,DWORD PTR [rbp-0xc]
0x0000000000401196 <+144>: cdqe
0x0000000000401198 <+146>: mov eax,DWORD PTR [rbp+rax*4-0x40]
0x000000000040119c <+150>: mov DWORD PTR [rbp-0x8],eax
0x000000000040119f <+153>: add DWORD PTR [rbp-0xc],0x1
0x00000000004011a3 <+157>: cmp DWORD PTR [rbp-0xc],0x9
0x00000000004011a7 <+161>: jle 0x40116b <main+101>
0x00000000004011a9 <+163>: mov edx,DWORD PTR [rbp-0x4]
0x00000000004011ac <+166>: mov eax,DWORD PTR [rbp-0x8]
0x00000000004011af <+169>: add eax,edx
0x00000000004011b1 <+171>: mov DWORD PTR [rbp-0x10],e
변환하기에 앞서 풀이를 했던 흐름을 생각해 보면 반복문 관련된 문제를 앞에서 풀기도 했고 공간만들고 값을 넣는 모습을 보니 역시 반복문이 있겠구나 생각했고 그 반복문 안에 조건문도 두개정도 있다고 파악하고 시작을 했다. (점프 관련 코드가 두개가 있었기 떄문)
처음 조건식은 rbp-0x4가 작을 때 뭔갈 하고 두번쨰 조건식은 rbp-0x8이 클 때 뭔갈 하는거 보니 정렬관련된 건가? 해서 몇바퀴 돌렸더니
rbp-0x4보다 작은 값을 찾으면 rbp-0x4에 저장하고 rbp-0x8보다 큰 값을 찾으면 rbp-0x8에 저장하는 그런 것이였다.
이것의 의미는 가장 큰 값과 가장 작은 값을 찾는다는 것이고.
마지막에 이 두개를 더하니 가장 큰 값과 가장 작은 값을 더한게 답일 것이다.
변환!
int a[10] = {1, 3, 7, 13, 21, 1, 13, 27, 13, 1}; // [rbp-0x40 ~ rbp-0x1c]
int min = 30 // [rbp-0x4]
int max = 3 // [rbpj-0x8]
int i = 0 // [rbp-0xc]
int result // [rbp-0x10]
while(i <= 9){
if (min > a[i]){
min = a[i];
}
if (max < a[i]){
max = a[i];
}
i++;
}
result = min + max;
그래서 답은 28
99. 후기
오랜만에 하는 어셈블리라 나름 재밌었다.