<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>kj0on</title>
    <link>https://kj0on.tistory.com/</link>
    <description>It's just the beginning</description>
    <language>ko</language>
    <pubDate>Mon, 6 Apr 2026 07:54:58 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>kj0on</managingEditor>
    <item>
      <title>[Programmers] PCCE 기출문제 (16 문제)</title>
      <link>https://kj0on.tistory.com/53</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;programmers-logo-dark.png&quot; data-origin-width=&quot;683&quot; data-origin-height=&quot;161&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/A8mgw/btsPDGrxCkI/vmBwIvnWEIkHrkaCssqjwk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/A8mgw/btsPDGrxCkI/vmBwIvnWEIkHrkaCssqjwk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/A8mgw/btsPDGrxCkI/vmBwIvnWEIkHrkaCssqjwk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FA8mgw%2FbtsPDGrxCkI%2FvmBwIvnWEIkHrkaCssqjwk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;683&quot; height=&quot;161&quot; data-filename=&quot;programmers-logo-dark.png&quot; data-origin-width=&quot;683&quot; data-origin-height=&quot;161&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;1. [PCCE 기출문제] 1번 / 문자 출력&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/340207&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/340207&lt;/a&gt;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;1-1. 문제 설명&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;주어진 코드는 변수에 데이터를 저장하고 출력하는 코드입니다. 아래와 같이 출력되도록 빈칸을 채워 코드를 완성해 주세요.&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;1-2. 출력 예시&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;3&lt;br /&gt;2&lt;br /&gt;1&lt;br /&gt;Let's go!&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;1-3. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754027136149&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;message = &quot;Let's go!&quot;

print(&quot;3\n2\n1&quot;)
print(message)&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;2. [PCCE&amp;nbsp;기출문제]&amp;nbsp;2번&amp;nbsp;/&amp;nbsp;각도&amp;nbsp;합치기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/340206&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/340206&lt;/a&gt;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;2-1. 문제 설명&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;일반적으로 두 선분이 이루는 각도는 한 바퀴를 360도로 하여 표현합니다. 따라서 각도에 360의 배수를 더하거나 빼더라도 같은 각을 의미합니다. 예를 들면, 30도와 390도는 같은 각도입니다. &lt;br /&gt;&lt;br /&gt;주어진 코드는 각도를 나타내는 두 정수 angle1과 angle2가 주어질 때, 이 두 각의 합을 0도 이상 360도 미만으로 출력하는 코드입니다. 코드가 올바르게 작동하도록 한 줄을 수정해 주세요.&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;2-2. 제한사항&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;0 &amp;le; angle1 &amp;le; 5000 &lt;br /&gt;0 &amp;le; angle2 &amp;le; 5000&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2-3. 입출력 예&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입력 #1&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;280&lt;br /&gt;485&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력 #1&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;45&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;angle1과&amp;nbsp;angle2의&amp;nbsp;합은&amp;nbsp;765도이고,&amp;nbsp;765를&amp;nbsp;720을&amp;nbsp;빼면&amp;nbsp;45도이므로&amp;nbsp;45를&amp;nbsp;출력합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;2-4. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754027324006&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;angle1 = int(input())
angle2 = int(input())

sum_angle = (angle1 + angle2) % 360
print(sum_angle)&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;3. [PCCE&amp;nbsp;기출문제]&amp;nbsp;3번&amp;nbsp;/&amp;nbsp;수&amp;nbsp;나누기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/340205&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/340205&lt;/a&gt;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;3-1. 문제 설명&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;2자리 이상의 정수 number가 주어집니다. 주어진 코드는 이 수를 2자리씩 자른 뒤, 자른 수를 모두 더해서 그 합을 출력하는 코드입니다. 코드가 올바르게 작동하도록 한 줄을 수정해 주세요.&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;3-2. 제한사항&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;10 &amp;le; number &amp;le; 2,000,000,000 &lt;br /&gt;number의 자릿수는 2의 배수입니다.&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;3-3. 입출력 예&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입력 #1&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;4859&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력 #1&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;107&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입출력&amp;nbsp;예&amp;nbsp;#1 &lt;br /&gt;입력된 수를 2자리씩 나눠 합치면 다음과 같습니다. &lt;br /&gt;48&amp;nbsp;+&amp;nbsp;59&amp;nbsp;=&amp;nbsp;107&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입력 #2&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;29&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력 #2&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;29&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입출력 예 #2&lt;br /&gt;입력된&amp;nbsp;수를&amp;nbsp;2자리씩&amp;nbsp;나눠&amp;nbsp;합치면&amp;nbsp;다음과&amp;nbsp;같습니다. &lt;br /&gt;29&amp;nbsp;&amp;nbsp;=&amp;nbsp;29&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;3-4. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754027524163&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;number = int(input())

answer = 0

for i in range(len(str(number)) // 2):
    answer += number % 100
    number //= 100

print(answer)&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;4. [PCCE&amp;nbsp;기출문제]&amp;nbsp;4번&amp;nbsp;/&amp;nbsp;병과분류&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/340204&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/340204&lt;/a&gt;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;4-1. 문제 설명&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;퓨쳐종합병원에서는 접수한 환자가 진료받을 병과에 따라 자동으로 환자 코드를 부여해 주는 프로그램이 있습니다. 환자 코드의 마지막 네 글자를 보면 환자가 어디 병과에서 진료를 받아야 할지 알 수 있습니다. 예를 들어 환자의 코드가 &quot;_eye&quot;로 끝난다면 안과를, &quot;head&quot;로 끝난다면 신경외과 진료를 보게 됩니다. 환자 코드의 마지막 글자에 따른 병과 분류 기준은 다음과 같습니다.&lt;br /&gt;&lt;br /&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;마지막 글자&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;병과&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&quot;_eye&quot;&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&quot;Ophthalmologyc&quot;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&quot;head&quot;&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&quot;Neurosurgery&quot;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&quot;infl&quot;&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&quot;Orthopedics&quot;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&quot;skin&quot;&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&quot;Dermatology&quot;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
환자의 코드를 나타내는 문자열 code를 입력받아 위 표에 맞는 병과를 출력하도록 빈칸을 채워 코드를 완성해 주세요. 위 표의 단어로 끝나지 않는다면 &quot;direct recommendation&quot;를 출력합니다.&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;4-2. 제한사항&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;4 &amp;le; code의 길이 &amp;le; 20 &lt;br /&gt;code는 영어 소문자와 숫자, 언더바(&quot;_&quot;)로 이루어져 있습니다.&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;4-3. 입출력 예&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입력 #1&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;dry_eye&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력 #1&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;Ophthalmologyc&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입출력 예 #1&lt;br /&gt;code가&amp;nbsp;&quot;_eye&quot;로&amp;nbsp;끝나기&amp;nbsp;때문에&amp;nbsp;&quot;Ophthalmologyc&quot;를&amp;nbsp;출력합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입력 #2&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;pat23_08_20_head&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력 #2&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;Neurosurgery&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입출력 예 #2&lt;br /&gt;code가&amp;nbsp;&quot;head&quot;로&amp;nbsp;끝나기&amp;nbsp;때문에&amp;nbsp;&quot;Neurosurgery&quot;를&amp;nbsp;출력합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;4-4. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754027887361&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;code = input()
last_four_words = code[-4:]

if last_four_words == &quot;_eye&quot;:
    print(&quot;Ophthalmologyc&quot;)
elif last_four_words == &quot;head&quot;:
    print(&quot;Neurosurgery&quot;)
elif last_four_words == &quot;infl&quot;:
    print(&quot;Orthopedics&quot;)
elif last_four_words == &quot;skin&quot;:
    print(&quot;Dermatology&quot;)
else:
    print(&quot;direct recommendation&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;5. [PCCE&amp;nbsp;기출문제]&amp;nbsp;5번&amp;nbsp;/&amp;nbsp;심폐소생술&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/340203&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/340203&lt;/a&gt;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;5-1. 문제 설명&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;심폐소생술은 다음과 같은 순서를 통해 실시합니다. &lt;br /&gt;&lt;br /&gt;1. 심정지 및 무호흡 확인 [check] &lt;br /&gt;2. 도움 및 119 신고 요청 [call] &lt;br /&gt;3. 가슴압박 30회 시행 [pressure] &lt;br /&gt;4. 인공호흡 2회 시행 [respiration] &lt;br /&gt;5. 가슴압박, 인공호흡 반복 [repeat] &lt;br /&gt;&lt;br /&gt;주어진 solution 함수는 심폐소생술을 하는 방법의 순서가 담긴 문자열들이 무작위 순서로 담긴 리스트 cpr이 주어질 때 각각의 방법이 몇 번째 단계인지 순서대로 담아 return하는 함수입니다. solution 함수가 올바르게 작동하도록 빈칸을 채워 solution 함수를 완성해 주세요.&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;5-2. 제한사항&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;cpr은 다음 문자열들이 한 번씩 포함되어 있습니다. &lt;br /&gt;&quot;check&quot;, &quot;call&quot;, &quot;pressure&quot;, &quot;respiration&quot;, &quot;repeat&quot;&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;5-3. 입출력 예&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;cpr&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;result&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;[&quot;call&quot;,&amp;nbsp;&quot;respiration&quot;,&amp;nbsp;&quot;repeat&quot;,&amp;nbsp;&quot;check&quot;,&amp;nbsp;&quot;pressure&quot;]&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;[2,&amp;nbsp;4,&amp;nbsp;5,&amp;nbsp;1,&amp;nbsp;3]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;[&quot;respiration&quot;,&amp;nbsp;&quot;repeat&quot;,&amp;nbsp;&quot;check&quot;,&amp;nbsp;&quot;pressure&quot;,&amp;nbsp;&quot;call&quot;]&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;[4,&amp;nbsp;5,&amp;nbsp;1,&amp;nbsp;3,&amp;nbsp;2]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;br /&gt;입출력 예 #1 &lt;br /&gt;&quot;call&quot;, &quot;respiration&quot;, &quot;repeat&quot;, &quot;check&quot;, &quot;pressure&quot;은 각각 2, 4, 5, 1, 3 번째 순서이므로 [2, 4, 5, 1, 3]을 리턴합니다. &lt;br /&gt;&lt;br /&gt;입출력 예 #2 &lt;br /&gt;&quot;respiration&quot;, &quot;repeat&quot;, &quot;check&quot;, &quot;pressure&quot;, &quot;call&quot;은 각각 4, 5, 1, 3, 2 번째 순서이므로 [4, 5, 1, 3, 2]를 리턴합니다.&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5-4. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754028133758&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(cpr):
    answer = []
    basic_order = [&quot;check&quot;, &quot;call&quot;, &quot;pressure&quot;, &quot;respiration&quot;, &quot;repeat&quot;]
    for action in cpr:
        for i in range(len(basic_order)):
            if action == basic_order[i]:
                answer.append(i + 1)
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;6. [PCCE&amp;nbsp;기출문제]&amp;nbsp;6번&amp;nbsp;/&amp;nbsp;물&amp;nbsp;부족&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/340202&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/340202&lt;/a&gt;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;6-1. 문제 설명&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;ㅇㅇ시에서는 저수지가 하나 있는데, 도시 내에서 사용하는 모든 물은 이 저수지에 저장된 물을 끌어와 사용합니다. 이상 기후로 인해 극심한 가뭄이 예고된 상황에서, 지난 달의 물 사용량과 이번달부터 일정 기간 동안의 월별 물 사용량의 변화를 예측한 값을 이용해 몇 달 뒤 물이 부족해지는지 예측하려고 합니다.&lt;br /&gt;&lt;br /&gt;이번달부터의 월별 물 사용량 변화를 예측한 값은 다음과 같이 리스트에 담겨 주어집니다.&lt;br /&gt;&lt;br /&gt;[10, -10, 10, -10, 10, -10, 10, -10, 10, -10]&lt;br /&gt;리스트의 각 원소는 해당 월의 물 사용량이 전 달에 비해 몇 % 만큼 증가 또는 감소하는지를 나타냅니다.&lt;br /&gt;예를 들어, 이번달의 물 사용량 (리스트의 첫 번째 원소)은 지난 달 보다 10% 증가한 값이며, 다음 달(리스트의 두 번째 원소)의 물 사용량은 이번달 사용량에서 10%만큼 감소한 값입니다.&lt;br /&gt;&lt;br /&gt;자세한 값은 입출력 예시를 참고해 주세요.&lt;br /&gt;현재 저수지에 저장된 물의 양을 나타내는 정수 storage와 지난 달 물 사용량을 나타내는 정수 usage, 월별 물 사용량이 전 달 대비 어떻게 변하는지 저장된 정수 리스트 change가 주어질 때 몇 달 뒤 물이 부족해지는지 return 하도록 solution 함수를 작성하려 합니다. 코드가 올바르게 작동하도록 한 줄을 수정해 solution 함수를 완성해 주세요. 가뭄이 끝날때 까지 저수지의 물이 남아 있다면 -1을 return합니다.&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;6-2. 제한사항&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;1,000 &amp;le; storage &amp;le; 1,000,000 &lt;br /&gt;500 &amp;le; usage &amp;le; 30,000 &lt;br /&gt;1 &amp;le; change의 길이 &amp;le; 30 &lt;br /&gt;-99 &amp;le; change[i] &amp;le; 500 &lt;br /&gt;change[i] 가 양수일 경우 물 사용량은 전 달 보다 change[i]% 만큼 증가합니다. &lt;br /&gt;change[i] 가 음수일 경우 물 사용량은 전 달 보다 change[i]% 만큼 감소합니다. &lt;br /&gt;change[i] 가 0일 경우 물 사용량은 전 달과 동일합니다. &lt;br /&gt;매달 물 사용량은 소수점 이하를 버린 정수로 계산합니다.&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;6-3. 입출력 예&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot;&gt;storage&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot;&gt;usage&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot;&gt;change&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot;&gt;result&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot;&gt;5141&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot;&gt;500&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot;&gt;[10, -10, 10, -10, 10, -10, 10, -10, 10, -10]&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot;&gt;-1&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot;&gt;1000&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot;&gt;2000&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot;&gt;[-10, 25, -33]&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot;&gt;1&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;br /&gt;입출력 예 #1&lt;br /&gt;매월 물 사용량은 다음과 같습니다.&lt;br /&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 5%;&quot;&gt;n개월&amp;nbsp;뒤&lt;/td&gt;
&lt;td style=&quot;width: 5%;&quot;&gt;0&amp;nbsp;(이번&amp;nbsp;달)&lt;/td&gt;
&lt;td style=&quot;width: 10%;&quot;&gt;1&amp;nbsp;(다음&amp;nbsp;달)&lt;/td&gt;
&lt;td style=&quot;width: 10%;&quot;&gt;2&lt;/td&gt;
&lt;td style=&quot;width: 10%;&quot;&gt;3&lt;/td&gt;
&lt;td style=&quot;width: 10%;&quot;&gt;4&lt;/td&gt;
&lt;td style=&quot;width: 10%;&quot;&gt;5&lt;/td&gt;
&lt;td style=&quot;width: 10%;&quot;&gt;6&lt;/td&gt;
&lt;td style=&quot;width: 10%;&quot;&gt;7&lt;/td&gt;
&lt;td style=&quot;width: 10%;&quot;&gt;8&lt;/td&gt;
&lt;td style=&quot;width: 10%;&quot;&gt;9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 5%;&quot;&gt;월&amp;nbsp;별&amp;nbsp;물&amp;nbsp;사용량&lt;/td&gt;
&lt;td style=&quot;width: 5%;&quot;&gt;550&lt;/td&gt;
&lt;td style=&quot;width: 10%;&quot;&gt;495&lt;/td&gt;
&lt;td style=&quot;width: 10%;&quot;&gt;544&lt;/td&gt;
&lt;td style=&quot;width: 10%;&quot;&gt;490&lt;/td&gt;
&lt;td style=&quot;width: 10%;&quot;&gt;539&lt;/td&gt;
&lt;td style=&quot;width: 10%;&quot;&gt;485&lt;/td&gt;
&lt;td style=&quot;width: 10%;&quot;&gt;533&lt;/td&gt;
&lt;td style=&quot;width: 10%;&quot;&gt;479&lt;/td&gt;
&lt;td style=&quot;width: 10%;&quot;&gt;526&lt;/td&gt;
&lt;td style=&quot;width: 10%;&quot;&gt;474&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 5%;&quot;&gt;총&amp;nbsp;물&amp;nbsp;사용량&lt;/td&gt;
&lt;td style=&quot;width: 5%;&quot;&gt;550&lt;/td&gt;
&lt;td style=&quot;width: 10%;&quot;&gt;1045&lt;/td&gt;
&lt;td style=&quot;width: 10%;&quot;&gt;1589&lt;/td&gt;
&lt;td style=&quot;width: 10%;&quot;&gt;2079&lt;/td&gt;
&lt;td style=&quot;width: 10%;&quot;&gt;2618&lt;/td&gt;
&lt;td style=&quot;width: 10%;&quot;&gt;3103&lt;/td&gt;
&lt;td style=&quot;width: 10%;&quot;&gt;3636&lt;/td&gt;
&lt;td style=&quot;width: 10%;&quot;&gt;4115&lt;/td&gt;
&lt;td style=&quot;width: 10%;&quot;&gt;4641&lt;/td&gt;
&lt;td style=&quot;width: 10%;&quot;&gt;5115&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
예를 들어, 지난 달 물 사용량 usage = 500이므로, 이번달 물 사용량은 10% 증가한 550입니다. 다음 달 물 사용량은 이번달 사용량 550에서 10% 감소한 495 이며, 나머지 달도 동일하게 계산합니다. 9달 뒤까지 계산한 물 사용량은 총 5115 이며, 현재 저수지에 저장된 물의 양은 storage = 5141입니다. 따라서 물이 부족해지지 않으므로 -1을 return합니다.&lt;br /&gt;&lt;br /&gt;입출력 예 #2 &lt;br /&gt;총 사용가능한 물의 양이 1000인데 2000 * 0.9 = 1800이 필요하므로 이번 달부터 물이 부족합니다. 따라서 0을 return합니다.&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6-4. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754028635489&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(storage, usage, change):
    total_usage = 0
    for i in range(len(change)):
        usage += usage * change[i]/100
        total_usage += usage
        if total_usage &amp;gt; storage:
            return i
    
    return -1&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;7. [PCCE&amp;nbsp;기출문제]&amp;nbsp;7번&amp;nbsp;/&amp;nbsp;버스&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/340201&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/340201&lt;/a&gt;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;7-1. 문제 설명&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;영진이는 약속장소에 가기 위해 버스를 타려고 합니다. 버스에는 좌석이 총 seat개만큼 있습니다. 영진이는 버스 좌석에 앉아서 갈 수 있을지 궁금해합니다. 기점에서 출발한 버스가 영진이가 기다리는 정거장에 도착하기 전에 방문하는 각 정거장에서 승/하차한 승객 정보가 주어질 때, 영진이가 버스에 탄 순간 빈 좌석은 몇 개인지 구해주세요. 영진이가 기다리는 정거장에서는 영진이가 제일 먼저 버스에 탑승하며, 이전 정거장에서 버스에 탑승한 승객들은 남는 좌석이 있다면 항상 앉는다고 가정합니다. 또, 기점에서 출발하는 버스에는 승객이 0명 타고 있습니다.&lt;br /&gt;&lt;br /&gt;예를 들어 다음은 좌석이 5개인 버스에 각 정거장에서 승/하차한 승객 정보를 나타냅니다. 영진이는 4번 정거장에서 기다리고 있으며, &quot;On&quot;은 승차한 승객, &quot;Off&quot;는 하차한 승객을 의미합니다.&lt;br /&gt;&lt;br /&gt;- 1번 정거장 : [&quot;On&quot;, &quot;On&quot;, &quot;On&quot;] (3명 승차, 0명 하차) &lt;br /&gt;- 2번 정거장 : [&quot;Off&quot;, &quot;On&quot;, &quot;-&quot;] (1명 승차, 1명 하차) &lt;br /&gt;- 3번 정거장 : [&quot;Off&quot;, &quot;-&quot;, &quot;-&quot;] (0명 승차, 1명 하차)&lt;br /&gt;&lt;br /&gt;위와 같은 경우, 1번 정거장에서 3명이 승차하고, 2번 정거장에서 1명 승차 1명 하차, 3번 정거장에서 1명이 하차했으므로 4번 정거장에 도착한 버스에는 2명이 타고 있습니다. 4번 정거장에서는 영진이가 가장 먼저 탑승하므로, 남아있는 좌석 수는 3개입니다.&lt;br /&gt;&lt;br /&gt;주어진 solution함수는 버스의 좌석 개수 seat, 기점에서 출발한 버스가 순서대로 방문한 정거장에서 승객이 승/하차한 정보를 담은 2차원 문자열 리스트 passengers가 주어질 때, 버스에 남아있는 좌석의 개수를 return 하는 함수입니다. solution 함수가 올바르게 작동하도록 빈칸을 채워 solution함수를 완성해 주세요.&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;7-2. 제한사항&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;1 &amp;le; seat &amp;le; 30&lt;br /&gt;1 &amp;le;&amp;nbsp;passengers의 길이 &amp;le; 10&lt;br /&gt;1 &amp;le; passengers[i]의 길이 &amp;le; 20&lt;br /&gt;passengers[0]은 1번 정거장,&amp;nbsp;&lt;br /&gt;passengers[1]은 2번 정거장, &amp;hellip;&amp;nbsp;&lt;br /&gt;passengers[i]는 i + 1번 정거장의 정보입니다.&lt;br /&gt;passengers의 길이가 n이라면, 영진이는 n + 1번 정거장에서 기다리고 있습니다.&lt;br /&gt;passengers[i]의 길이는 모두 동일합니다.&lt;br /&gt;passengers[i]의 원소는 &quot;On&quot;, &quot;Off&quot; 또는 &quot;-&quot;입니다.&lt;br /&gt;&quot;-&quot;는 배열의 가로(열) 길이를 맞추기 위한 요소로, 아무런 의미도 없습니다.&lt;br /&gt;&quot;-&quot;가 &quot;On&quot;, &quot;Off&quot; 사이에 있는 경우는 없습니다.&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;7-3. 입출력 예&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 235px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 26px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 26px;&quot;&gt;seat&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 26px;&quot;&gt;passengers&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 26px;&quot;&gt;result&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 52px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 52px;&quot;&gt;5&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 52px;&quot;&gt;[[&quot;On&quot;,&amp;nbsp;&quot;On&quot;,&amp;nbsp;&quot;On&quot;],&amp;nbsp;[&quot;Off&quot;,&amp;nbsp;&quot;On&quot;,&amp;nbsp;&quot;-&quot;],&amp;nbsp;[&quot;Off&quot;,&amp;nbsp;&quot;-&quot;,&amp;nbsp;&quot;-&quot;]]&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 52px;&quot;&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 157px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 157px;&quot;&gt;10&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 157px;&quot;&gt;[[&quot;On&quot;,&amp;nbsp;&quot;On&quot;,&amp;nbsp;&quot;On&quot;,&amp;nbsp;&quot;On&quot;,&amp;nbsp;&quot;On&quot;,&amp;nbsp;&quot;On&quot;,&amp;nbsp;&quot;On&quot;,&amp;nbsp;&quot;On&quot;,&amp;nbsp;&quot;-&quot;,&amp;nbsp;&quot;-&quot;],&amp;nbsp;[&quot;On&quot;,&amp;nbsp;&quot;On&quot;,&amp;nbsp;&quot;Off&quot;,&amp;nbsp;&quot;Off&quot;,&amp;nbsp;&quot;Off&quot;,&amp;nbsp;&quot;On&quot;,&amp;nbsp;&quot;On&quot;,&amp;nbsp;&quot;-&quot;,&amp;nbsp;&quot;-&quot;,&amp;nbsp;&quot;-&quot;],&amp;nbsp;[&quot;On&quot;,&amp;nbsp;&quot;On&quot;,&amp;nbsp;&quot;On&quot;,&amp;nbsp;&quot;Off&quot;,&amp;nbsp;&quot;On&quot;,&amp;nbsp;&quot;On&quot;,&amp;nbsp;&quot;On&quot;,&amp;nbsp;&quot;Off&quot;,&amp;nbsp;&quot;Off&quot;,&amp;nbsp;&quot;Off&quot;],&amp;nbsp;[&quot;On&quot;,&amp;nbsp;&quot;On&quot;,&amp;nbsp;&quot;Off&quot;,&amp;nbsp;&quot;-&quot;,&amp;nbsp;&quot;-&quot;,&amp;nbsp;&quot;-&quot;,&amp;nbsp;&quot;-&quot;,&amp;nbsp;&quot;-&quot;,&amp;nbsp;&quot;-&quot;,&amp;nbsp;&quot;-&quot;]]&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 157px;&quot;&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
입출력 예 #1 &lt;br /&gt;지문과 동일합니다 &lt;br /&gt;&lt;br /&gt;입출력 예 #2 &lt;br /&gt;아래와 같이 승객이 타고 내렸고 마지막으로 12명이 버스에 타고 있으므로 남은 좌석은 0개입니다.&lt;br /&gt;- 1번 정거장 : [&quot;On&quot;, &quot;On&quot;, &quot;On&quot;, &quot;On&quot;, &quot;On&quot;, &quot;On&quot;, &quot;On&quot;, &quot;On&quot;, &quot;-&quot;, &quot;-&quot;] (8명 승차, 0명 하차) &lt;br /&gt;- 2번 정거장 : [&quot;On&quot;, &quot;On&quot;, &quot;Off&quot;, &quot;Off&quot;, &quot;Off&quot;, &quot;On&quot;, &quot;On&quot;, &quot;-&quot;, &quot;-&quot;, &quot;-&quot;] (4명 승차, 3명 하차) &lt;br /&gt;- 3번 정거장 : [&quot;On&quot;, &quot;On&quot;, &quot;On&quot;, &quot;Off&quot;, &quot;On&quot;, &quot;On&quot;, &quot;On&quot;, &quot;Off&quot;, &quot;Off&quot;, &quot;Off&quot;] (6명 승차, 4명 하차) &lt;br /&gt;- 4번 정거장 : [&quot;On&quot;, &quot;On&quot;, &quot;Off&quot;, &quot;-&quot;, &quot;-&quot;, &quot;-&quot;, &quot;-&quot;, &quot;-&quot;, &quot;-&quot;, &quot;-&quot;] (2명 승차, 1명 하차)&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;7-4. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754028927869&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def func1(num):
    if 0 &amp;gt; num:
        return 0
    else:
        return num

def func2(num):
    if num &amp;gt; 0:
        return 0
    else:
        return num

def func3(station):
    num = 0
    for people in station:
        if people == &quot;Off&quot;:
            num += 1
    return num

def func4(station):
    num = 0
    for people in station:
        if people == &quot;On&quot;:
            num += 1
    return num


def solution(seat, passengers):
    num_passenger = 0
    for station in passengers:
        num_passenger += func4(station)

        num_passenger -= func3(station)

    answer = func1(seat - num_passenger)

    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;8. [PCCE&amp;nbsp;기출문제]&amp;nbsp;8번&amp;nbsp;/&amp;nbsp;닉네임&amp;nbsp;규칙&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/340200&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/340200&lt;/a&gt;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;8-1. 문제 설명&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;온라인 서비스를 이용하기 위해서 닉네임이 필요합니다. 이때 닉네임이 될 수 있는 조건은 다음과 같습니다. &lt;br /&gt;&lt;br /&gt;닉네임의 길이가 4자 이상 8자 이하여야합니다. &lt;br /&gt;닉네임에는 소문자 l과w, 대문자 O와 W를 사용할 수 없습니다. &lt;br /&gt;이외의 영어 대소문자와 숫자는 모두 사용이 가능합니다. &lt;br /&gt;&lt;br /&gt;주어진 solution 함수는 사용할 수 없는 닉네임 nickname을 받아 사용할 수 있는 닉네임으로 바꿔주는 함수입니다. 이때 닉네임을 변경하는 규칙은 다음과 같으며 첫 번째 규칙부터 순서대로 적용합니다. &lt;br /&gt;1. 소문자 l을 대문자 I로 변경합니다. &lt;br /&gt;2. 소문자 w를 두 개의 소문자 v, 즉 vv로 변경합니다. &lt;br /&gt;3. 대문자 W를 두 개의 대문자 V, 즉 VV로 변경합니다. &lt;br /&gt;4. 대문자 O를 숫자 0으로 변경합니다. &lt;br /&gt;5. 수정된 닉네임의 길이가 4 미만일 경우 뒤에 소문자 o를 길이가 4가 될때까지 이어붙입니다. &lt;br /&gt;6. 수정된 닉네임의 길이가 8보다 클 경우 8번째 문자까지만 사용합니다. &lt;br /&gt;&lt;br /&gt;주어진 solution 함수에는 위의 규칙 중 올바르게 적용되지 않는 것이 있습니다. solution 함수가 올바르게 작동하도록 한 줄을 수정해주세요.&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;8-2. 제한사항&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;1 &amp;le; nickname의 길이 &amp;le; 10 &lt;br /&gt;nickname은 영어 대소문자와 숫자로만 이루어져있습니다.&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;8-3. 입출력 예&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;nickname&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;result&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&quot;WORLDworld&quot;&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&quot;VV0RLDvv&quot;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&quot;&quot;GO&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&quot;G0oo&quot;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
입출력 예 #1 &lt;br /&gt;닉네임 &quot;WORLDworld&quot;는 1, 2, 3, 4, 6 단계를 거쳐 &quot;VV0RLDvv&quot;가 됩니다.&lt;br /&gt;&quot;WORLDworld&quot; -&amp;gt; &quot;WORLDworId&quot; -&amp;gt; &quot;WORLDvvorId&quot; -&amp;gt; &quot;VVORLDvvorId&quot; -&amp;gt; &quot;VV0RLDvvorId&quot; -&amp;gt; &quot;VV0RLDvv&quot;&lt;br /&gt;&lt;br /&gt;입출력 예 #2 &lt;br /&gt;닉네임 &quot;GO&quot;는 4, 5 단계를 거쳐 &quot;G0oo&quot;가 됩니다.&lt;br /&gt;&quot;GO&quot; -&amp;gt; &quot;G0&quot; -&amp;gt; &quot;G0oo&quot;&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;8-4. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754029188656&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(nickname):
    answer = &quot;&quot;
    for letter in nickname:
        if letter == &quot;l&quot;:
            answer += &quot;I&quot;
        elif letter == &quot;w&quot;:
            answer += &quot;vv&quot;
        elif letter == &quot;W&quot;:
            answer += &quot;VV&quot;
        elif letter == &quot;O&quot;:
            answer += &quot;0&quot;
        else:
            answer += letter
    if len(answer) &amp;lt; 3:
        answer += &quot;o&quot; * (4 - len(answer))
    if len(answer) &amp;gt; 8:
        answer = answer[:8]
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;9. [PCCE&amp;nbsp;기출문제]&amp;nbsp;1번&amp;nbsp;/&amp;nbsp;출력&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/250133&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/250133&lt;/a&gt;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;9-1. 문제 설명&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;주어진 초기 코드는 변수에 데이터를 저장하고 출력하는 코드입니다. 아래와 같이 출력되도록 빈칸을 채워 코드를 완성해 주세요.&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;9-2. 출력 예시&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;Spring is beginning &lt;br /&gt;13 &lt;br /&gt;310&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;9-3. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754029854634&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;string_msg = &quot;Spring is beginning&quot;
int_val = 3
string_val = &quot;3&quot;

print(string_msg)
print(int_val + 10)
print(string_val + &quot;10&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;10. [PCCE&amp;nbsp;기출문제]&amp;nbsp;2번&amp;nbsp;/&amp;nbsp;피타고라스의&amp;nbsp;정리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;10-1. 문제 설명&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;aa.jpg&quot; data-origin-width=&quot;161&quot; data-origin-height=&quot;169&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cl6DDM/btsPEC9Ts27/K0avBfsgIYZILmDAS7H160/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cl6DDM/btsPEC9Ts27/K0avBfsgIYZILmDAS7H160/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cl6DDM/btsPEC9Ts27/K0avBfsgIYZILmDAS7H160/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcl6DDM%2FbtsPEC9Ts27%2FK0avBfsgIYZILmDAS7H160%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;161&quot; height=&quot;169&quot; data-filename=&quot;aa.jpg&quot; data-origin-width=&quot;161&quot; data-origin-height=&quot;169&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;직각삼각형이 주어졌을 때 빗변의 제곱은 다른 두 변을 각각 제곱한 것의 합과 같습니다.&lt;br /&gt;직각삼각형의 한 변의 길이를 나타내는 정수 a와 빗변의 길이를 나타내는 정수 c가 주어질 때, 다른 한 변의 길이의 제곱, b_square 을 출력하도록 한 줄을 수정해 코드를 완성해 주세요.&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;10-2. 제한사항&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;1 &amp;le; a &amp;lt; c &amp;le; 100&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;10-3. 입출력 예&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입력 #1&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;3&lt;br /&gt;5&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력 #1&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;16&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입출력 예 #1&lt;br /&gt;a2&amp;nbsp;=&amp;nbsp;9,&amp;nbsp;c2&amp;nbsp;=&amp;nbsp;25&amp;nbsp;이므로&amp;nbsp;16을&amp;nbsp;출력합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입력 #2&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;9&lt;br /&gt;10&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력 #2&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;19&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입출력&amp;nbsp;예&amp;nbsp;#2 &lt;br /&gt;a2 = 81, c2 = 100 이므로 19를 출력합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;10-4. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754030049412&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;a = int(input())
c = int(input())

b_square = c ** 2 - a ** 2
print(b_square)&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;11. [PCCE&amp;nbsp;기출문제]&amp;nbsp;3번&amp;nbsp;/&amp;nbsp;나이&amp;nbsp;계산&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/250131&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/250131&lt;/a&gt;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;11-1. 문제 설명&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;나이를 세는 방법은 여러 가지가 있습니다. 그중 한국식 나이는 태어난 순간 1살이 되며 해가 바뀔 때마다 1살씩 더 먹게 됩니다. 연 나이는 태어난 순간 0살이며 해가 바뀔 때마다 1살씩 더 먹게 됩니다. 각각 나이의 계산법은 다음과 같습니다. &lt;br /&gt;&lt;br /&gt;한국식 나이 : 현재 연도 - 출생 연도 + 1 &lt;br /&gt;연 나이 : 현재 연도 - 출생 연도 &lt;br /&gt;&lt;br /&gt;출생 연도를 나타내는 정수 year와 구하려는 나이의 종류를 나타내는 문자열 age_type이 주어질 때 2030년에 몇 살인지 출력하도록 빈칸을 채워 코드를 완성해 주세요. age_type이 &quot;Korea&quot;라면 한국식 나이를, &quot;Year&quot;라면 연 나이를 출력합니다.&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;11-2. 제한사항&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;1950 &amp;le; year &amp;le; 2030age_type은 &quot;Korea&quot; 또는 &quot;Year&quot;만 주어집니다.&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;11-3. 입출력 예&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입력 #1&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;2000&lt;br /&gt;Korea&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력 #1&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;31&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입출력 예 #1&lt;br /&gt;2030년에&amp;nbsp;2000년생의&amp;nbsp;한국식&amp;nbsp;나이는&amp;nbsp;2030&amp;nbsp;-&amp;nbsp;2000&amp;nbsp;+&amp;nbsp;1&amp;nbsp;=&amp;nbsp;31살입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입력 #2&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;1999&lt;br /&gt;Year&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력 #2&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;31&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입출력 예 #2&lt;br /&gt;2030년에&amp;nbsp;1999년생의&amp;nbsp;연&amp;nbsp;나이는&amp;nbsp;2030&amp;nbsp;-&amp;nbsp;1999&amp;nbsp;=&amp;nbsp;31살입니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;11-4. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754030231371&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;year = int(input())
age_type = input()

if age_type == &quot;Korea&quot;:
    answer = 2030 - year + 1
elif age_type == &quot;Year&quot;:
    answer = 2030 - year
    
print(answer)&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;12. [PCCE&amp;nbsp;기출문제]&amp;nbsp;4번&amp;nbsp;/&amp;nbsp;저축&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/250130&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/250130&lt;/a&gt;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;12-1. 문제 설명&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;진우는 돈을 모으기 위해 저축을 하려고 합니다. 목표로 하는 금액은 100만 원이며, 첫 달에 일정 금액을 넣은 뒤 70만 원까지는 매월 조금씩 저축하다가 70만 원 이후부터는 월 저축량을 늘려 빠르게 목표 금액을 달성하고자 합니다. &lt;br /&gt;&lt;br /&gt;첫 달에 저축하는 금액을 나타내는 정수 start, 두 번째 달 부터 70만 원 이상 모일 때까지 매월 저축하는 금액을 나타내는 정수 before, 100만 원 이상 모일 때 까지 매월 저축하는 금액을 나타내는 정수 after가 주어질 때, 100만 원 이상을 모을 때까지 걸리는 개월 수를 출력하도록 빈칸을 채워 코드를 완성해 주세요.&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;12-2. 제한사항&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;0 &amp;le; start &amp;le; 991 &amp;le; before &amp;le; after &amp;le; 25&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;12-3. 입출력 예&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입력 #1&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;28&lt;br /&gt;6&lt;br /&gt;8&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력 #1&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;12&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입출력 예 #1&lt;br /&gt;매월&amp;nbsp;저축된&amp;nbsp;금액은&amp;nbsp;아래&amp;nbsp;표와&amp;nbsp;같습니다.&amp;nbsp;따라서&amp;nbsp;12를&amp;nbsp;출력합니다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 34px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 8.33335%; height: 17px;&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;width: 8.33335%; height: 17px;&quot;&gt;2&lt;/td&gt;
&lt;td style=&quot;width: 8.33335%; height: 17px;&quot;&gt;3&lt;/td&gt;
&lt;td style=&quot;width: 8.33335%; height: 17px;&quot;&gt;4&lt;/td&gt;
&lt;td style=&quot;width: 8.33335%; height: 17px;&quot;&gt;5&lt;/td&gt;
&lt;td style=&quot;width: 8.33335%; height: 17px;&quot;&gt;6&lt;/td&gt;
&lt;td style=&quot;width: 8.33335%; height: 17px;&quot;&gt;7&lt;/td&gt;
&lt;td style=&quot;width: 8.33335%; height: 17px;&quot;&gt;8&lt;/td&gt;
&lt;td style=&quot;width: 8.33335%; height: 17px;&quot;&gt;9&lt;/td&gt;
&lt;td style=&quot;width: 8.33335%; height: 17px;&quot;&gt;10&lt;/td&gt;
&lt;td style=&quot;width: 8.33335%; height: 17px;&quot;&gt;11&lt;/td&gt;
&lt;td style=&quot;width: 8.33335%; height: 17px;&quot;&gt;12&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 8.33335%; height: 17px;&quot;&gt;28&lt;/td&gt;
&lt;td style=&quot;width: 8.33335%; height: 17px;&quot;&gt;34&lt;/td&gt;
&lt;td style=&quot;width: 8.33335%; height: 17px;&quot;&gt;40&lt;/td&gt;
&lt;td style=&quot;width: 8.33335%; height: 17px;&quot;&gt;46&lt;/td&gt;
&lt;td style=&quot;width: 8.33335%; height: 17px;&quot;&gt;52&lt;/td&gt;
&lt;td style=&quot;width: 8.33335%; height: 17px;&quot;&gt;58&lt;/td&gt;
&lt;td style=&quot;width: 8.33335%; height: 17px;&quot;&gt;64&lt;/td&gt;
&lt;td style=&quot;width: 8.33335%; height: 17px;&quot;&gt;70&lt;/td&gt;
&lt;td style=&quot;width: 8.33335%; height: 17px;&quot;&gt;78&lt;/td&gt;
&lt;td style=&quot;width: 8.33335%; height: 17px;&quot;&gt;86&lt;/td&gt;
&lt;td style=&quot;width: 8.33335%; height: 17px;&quot;&gt;94&lt;/td&gt;
&lt;td style=&quot;width: 8.33335%; height: 17px;&quot;&gt;102&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입력 #2&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;75&lt;br /&gt;8&lt;br /&gt;25&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력 #2&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;2&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입출력 예 #2&lt;br /&gt;첫&amp;nbsp;달&amp;nbsp;저축된&amp;nbsp;금액이&amp;nbsp;70이&amp;nbsp;넘으므로&amp;nbsp;두&amp;nbsp;번째&amp;nbsp;달부터&amp;nbsp;바로&amp;nbsp;after=&amp;nbsp;25&amp;nbsp;만큼&amp;nbsp;저축합니다.&amp;nbsp;따라서&amp;nbsp;2를&amp;nbsp;출력합니다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;75&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;100&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;12-4. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754030485050&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;start = int(input())
before = int(input())
after = int(input())

money = start
month = 1
while money &amp;lt; 70:
    money += before
    month += 1
while money&amp;lt; 100:
    money += after
    month += 1
print(month)&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;13. [PCCE&amp;nbsp;기출문제]&amp;nbsp;5번&amp;nbsp;/&amp;nbsp;산책&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/250129&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/250129&lt;/a&gt;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;13-1. 문제 설명&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;여름이는 강아지를 산책시키려고 합니다. 여름이는 2차원 좌표평면에서 동/서/남/북 방향으로 1m 단위로 이동하면서 강아지를 산책시킵니다. 산책루트가 담긴 문자열 route가 주어질 때, 도착점의 위치를 return하도록 빈칸을 채워 solution함수를 완성해 주세요. &lt;br /&gt;&lt;br /&gt;route는 &quot;N&quot;, &quot;S&quot;, &quot;E&quot;, &quot;W&quot;로 이루어져 있습니다. &lt;br /&gt;&quot;N&quot;은 북쪽으로 1만큼 움직입니다. &lt;br /&gt;&quot;S&quot;는 남쪽으로 1만큼 움직입니다. &lt;br /&gt;북쪽으로 -1만큼 움직인 것과 같습니다. &lt;br /&gt;&quot;E&quot;는 동쪽으로 1만큼 움직입니다. &lt;br /&gt;&quot;W&quot;는 서쪽으로 1만큼 움직입니다. &lt;br /&gt;동쪽으로 -1만큼 움직인 것과 같습니다. &lt;br /&gt;&lt;br /&gt;출발점으로부터 [동쪽으로 떨어진 거리, 북쪽으로 떨어진 거리]형태로 강아지의 최종 위치를 구해서 return해야 합니다. &lt;br /&gt;출발점을 기준으로 서쪽, 남쪽에 있는 경우는 동쪽, 북쪽으로 음수만큼 떨어진 것으로 표현합니다. &lt;br /&gt;출발점으로부터 동쪽으로 2, 북쪽으로 3만큼 떨어졌다면 [2, 3]을 return 합니다. &lt;br /&gt;출발점으로부터 서쪽으로 1, 남쪽으로 4만큼 떨어졌다면 [-1, -4]를 return 합니다.&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;13-2. 제한사항&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;1 &amp;le; route의 길이 &amp;le; 20&lt;br /&gt;route는 &quot;N&quot;, &quot;S&quot;, &quot;E&quot;, &quot;W&quot;로만 이루어져 있습니다.&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;13-3. 입출력 예&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;route&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;result&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&quot;NSSNEWWN&quot;&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;[-1,&amp;nbsp;1]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&quot;EESEEWNWSNWWNS&quot;&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;[0,&amp;nbsp;0]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
입출력 예 #1 &lt;br /&gt;&quot;NSSNEWWN&quot; 순서대로 움직이면 서쪽으로 1, 북쪽으로 1만큼 떨어진 곳에 도착하게 되므로 [-1, 1]을 return합니다.&lt;br /&gt;&lt;br /&gt;입출력 예 #2 &lt;br /&gt;&quot;EESEEWNWSNWWNS&quot; 순서대로 움직이면 출발지와 같은 곳으로 돌아오므로 [0, 0]을 return합니다.&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;13-4. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754030686791&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(route):
    east = 0
    north = 0
    for i in route:
        if i == &quot;N&quot;:
            north += 1
        elif i == &quot;S&quot; :
            north -= 1
        elif i == &quot;E&quot; :
            east += 1
        elif i == &quot;W&quot;:
            east -= 1
        return [east, north]&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;14. [PCCE&amp;nbsp;기출문제]&amp;nbsp;6번&amp;nbsp;/&amp;nbsp;가채점&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/250128&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/250128&lt;/a&gt;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;14-1. 문제 설명&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;A반 학생들은 시험이 끝난 뒤 성적이 나오기 전 자기 시험지를 가채점해 보았습니다. 이후에 선생님이 실제 성적을 불러 줄 때 가채점한 점수와 실제 성적이 다른 학생들이 있어 선생님께 문의를 하려고 합니다. &lt;br /&gt;&lt;br /&gt;성적을 문의하려는 학생들의 번호가 담긴 정수 리스트 numbers와 가채점한 점수가 성적을 문의하려는 학생 순서대로 담긴 정수 리스트 our_score, 실제 성적이 번호 순서대로 담긴 정수 리스트 score_list가 주어집니다. 주어진 solution 함수는 가채점한 점수가 실제 성적과 동일하다면 &quot;Same&quot;을, 다르다면 &quot;Different&quot;를 순서대로 리스트에 담아 return하는 함수입니다. solution 함수가 올바르게 작동하도록 한 줄을 수정해 주세요.&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;14-2. 제한사항&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;1 &amp;le; numbers의 길이 = our_score의 길이 &amp;le; 10 &lt;br /&gt;1 &amp;le; numbers의 원소 &amp;le; 31 &lt;br /&gt;0 &amp;le; our_score의 원소 &amp;le; 100 &lt;br /&gt;our_score[i]는 numbers[i]번 학생이 가채점한 점수입니다. &lt;br /&gt;numbers는 중복된 원소를 가지지 않습니다. &lt;br /&gt;&lt;br /&gt;2 &amp;le; score_list의 길이 &amp;le; 31 &lt;br /&gt;0 &amp;le; score_list의 원소 &amp;le; 100 &lt;br /&gt;score_list에는 실제 성적이 [1번 학생 성적, 2번 학생 성적, 3번 학생 성적 &amp;hellip;] 순서로 들어있습니다.&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;14-3. 입출력 예&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;numbers&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;our_score&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;score_list&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;result&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;[1]&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;[100]&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;[100,&amp;nbsp;80,&amp;nbsp;90,&amp;nbsp;84,&amp;nbsp;20]&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;[&quot;Same&quot;]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;[3, 4]&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;[85, 93]&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;[85,&amp;nbsp;92,&amp;nbsp;38,&amp;nbsp;93,&amp;nbsp;48,&amp;nbsp;85,&amp;nbsp;92,&amp;nbsp;56]&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;[&quot;Different&quot;,&amp;nbsp;&quot;Same&quot;]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
입출력 예 #1 &lt;br /&gt;1번 학생이 가채점한 성적은 100점으로 실제 성적과 같기 때문에 &quot;Same&quot;을 담아 return합니다. &lt;br /&gt;&lt;br /&gt;입출력 예 #2 &lt;br /&gt;3번 학생이 가채점한 성적은 85점으로 실제 성적 38점과 다르기 때문에 &quot;Different&quot;를, 4번 학생이 채점한 성적은 93점으로 실제 성적과 같기 때문에 &quot;Same&quot;을 담아 return합니다.&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;14-4. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754030897977&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(numbers, our_score, score_list):
    answer = []
    for i in range(len(numbers)):
        if our_score[i] == score_list[numbers[i] - 1]:
            answer.append(&quot;Same&quot;)
        else:
            answer.append(&quot;Different&quot;)
    
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;15. [PCCE&amp;nbsp;기출문제]&amp;nbsp;7번&amp;nbsp;/&amp;nbsp;가습기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/250127&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/250127&lt;/a&gt;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;15-1. 문제 설명&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;상우가 사용하는 가습기에는 &quot;auto&quot;, &quot;target&quot;, &quot;minimum&quot;의 세 가지 모드가 있습니다. 가습기의 가습량은 0~5단계로 구분되며 각 모드 별 동작 방식은 다음과 같습니다. &lt;br /&gt;&lt;br /&gt;&quot;auto&quot; 모드 &lt;br /&gt;습도가 0 이상 10 미만인 경우 : 5단계 &lt;br /&gt;습도가 10 이상 20 미만인 경우 : 4단계 &lt;br /&gt;습도가 20 이상 30 미만인 경우 : 3단계 &lt;br /&gt;습도가 30 이상 40 미만인 경우 : 2단계 &lt;br /&gt;습도가 40 이상 50 미만인 경우 : 1단계 &lt;br /&gt;습도가 50 이상인 경우 : 0단계 &lt;br /&gt;&lt;br /&gt;&quot;target&quot; 모드 &lt;br /&gt;습도가 설정값 미만일 경우 : 3단계 &lt;br /&gt;습도가 설정값 이상일 경우 : 1단계&lt;br /&gt;&lt;br /&gt;&quot;minimum&quot;모드 &lt;br /&gt;습도가 설정값 미만일 경우 : 1단계 &lt;br /&gt;습도가 설정값 이상일 경우 : 0단계 &lt;br /&gt;&lt;br /&gt;상우가 설정한 가습기의 모드를 나타낸 문자열 mode_type, 현재 공기 중 습도를 나타낸 정수 humidity, 설정값을 나타낸 정수 val_set이 주어질 때 현재 가습기가 몇 단계로 작동 중인지 return하도록 빈칸을 채워 solution 함수를 완성해 주세요.&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;15-2. 제한사항&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;mode_type은 &quot;auto&quot;, &quot;target&quot;, &quot;minimum&quot; 세 가지 중 하나의 값을 갖습니다.&lt;br /&gt;0 &amp;le; humidity, val_set &amp;le; 100&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;15-3. 입출력 예&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;mode_type&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;hymidity&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;val_set&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;result&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&quot;auto&quot;&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;23&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;45&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&quot;target&quot;&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;41&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;40&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&quot;minimum&quot;&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;10&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;34&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
입출력 예 #1 &lt;br /&gt;&quot;auto&quot;모드이므로 습도에 따라 가습량이 조절됩니다. 현재 습도가 20 이상 30 미만이므로 3을 return합니다. &lt;br /&gt;&lt;br /&gt;입출력 예 #2 &lt;br /&gt;&quot;target&quot;모드이고, 설정값보다 습도가 높으므로 1을 return합니다. &lt;br /&gt;&lt;br /&gt;입출력 예 #3 &lt;br /&gt;&quot;minimum&quot;모드이고, 설정값보다 습도가 낮으므로 1을 return합니다.&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;15-4. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754031177816&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def func1(humidity, val_set):
    if humidity &amp;lt; val_set:
        return 3
    return 1

def func2(humidity):
    if humidity &amp;gt;= 50:
        return 0
    elif humidity &amp;gt;= 40:
        return 1
    elif humidity &amp;gt;= 30:
        return 2
    elif humidity &amp;gt;= 20:
        return 3
    elif humidity &amp;gt;= 10:
        return 4
    elif 0 &amp;lt;= humidity &amp;lt; 10:
    	return 5

def func3(humidity, val_set):
    if humidity &amp;lt; val_set:
        return 1
    return 0

def solution(mode_type, humidity, val_set):
    answer = 0
    if mode_type == &quot;auto&quot;:
        answer = func2(humidity)
    elif mode_type == &quot;target&quot;:
        answer = func1(humidity, val_set)
    elif mode_type == &quot;minimum&quot;:
        answer = func3(humidity, val_set)
	return answer&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;16. [PCCE&amp;nbsp;기출문제]&amp;nbsp;8번&amp;nbsp;/&amp;nbsp;창고&amp;nbsp;정리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;16-1. 문제 설명&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;bb.jpg&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;245&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2d6TU/btsPEtkUoMO/0W5Rb23TN55g2Y8xQDgWk1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2d6TU/btsPEtkUoMO/0W5Rb23TN55g2Y8xQDgWk1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2d6TU/btsPEtkUoMO/0W5Rb23TN55g2Y8xQDgWk1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2d6TU%2FbtsPEtkUoMO%2F0W5Rb23TN55g2Y8xQDgWk1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;245&quot; data-filename=&quot;bb.jpg&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;245&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;선빈이는 게임을 즐기던 중 가지고 있는 물건이 너무 많아 창고 정리를 하기로 했습니다. 선빈이가 보유한 게임 속 창고는 여러 칸으로 나누어져 있고 각 칸에는 물건들이 담겨있습니다. 창고를 정리할 방법을 고민하던 선빈이는 같은 물건이 여러 칸에 나누어 들어있는 것을 발견하고 우선 같은 물건끼리 최대한 겹쳐쌓는 방식으로 창고를 정리하기로 했습니다. 선빈이의 창고에 들어있는 물건의 이름과 개수는 리스트 형태로 주어지며, 한 칸에 겹쳐질 수 있는 물건의 개수에는 제한이 없다고 가정합니다. &lt;br /&gt;&lt;br /&gt;예를 들어 창고의 각 칸에 담겨있는 물건의 이름이storage = [&quot;pencil&quot;, &quot;pencil&quot;, &quot;pencil&quot;, &quot;book&quot;], 각 물건의 개수가 num = [2, 4, 3, 1]이라면 연필과 책을 한 칸에 각각 겹쳐 쌓아 간단하게 clean_storage = [&quot;pencil&quot;, &quot;book&quot;], clean_num = [9, 1]로 만들 수 있습니다.&lt;br /&gt;&lt;br /&gt;주어진 solution 함수는 정리되기 전 창고의 물건 이름이 담긴 문자열 리스트 storage와 각 물건의 개수가 담긴 정수 리스트 num이 주어질 때, 정리된 창고에서 개수가 가장 많은 물건의 이름을 return 하는 함수입니다. solution 함수가 올바르게 작동하도록 한 줄을 수정해 주세요.&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;16-2. 제한사항&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;1 &amp;le; storage의 길이 = num의 길이 &amp;le; 30&lt;br /&gt;storage[i]는 영어 대소문자로 이루어져 있습니다.&lt;br /&gt;물건은 대소문자를 구분합니다. 즉, &quot;Book&quot;과 &quot;book&quot;은 서로 다른 물건입니다.&lt;br /&gt;1 &amp;le; storage[i]의 길이 &amp;le; 30&lt;br /&gt;1 &amp;le; num[i] &amp;le; 20&lt;br /&gt;num[i]에는 storage[i]에 해당하는 물건의 개수가 담겨있습니다.&lt;br /&gt;가장 개수가 많은 물건이 두 가지 이상인 경우는 없습니다.&lt;br /&gt;한 칸에는 한 종류의 물건만 들어갈 수 있습니다.&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;16-3. 입출력 예&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;storage&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;num&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;result&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;[&quot;pencil&quot;,&amp;nbsp;&quot;pencil&quot;,&amp;nbsp;&quot;pencil&quot;,&amp;nbsp;&quot;book&quot;] [2,&amp;nbsp;4,&amp;nbsp;3,&amp;nbsp;1]&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;[2, 4, 3, 1]&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;&quot;pencil&quot;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;[&quot;doll&quot;,&amp;nbsp;&quot;doll&quot;,&amp;nbsp;&quot;doll&quot;,&amp;nbsp;&quot;doll&quot;] [1,&amp;nbsp;1,&amp;nbsp;1,&amp;nbsp;1]&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;[1, 1, 1, 1]&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;&quot;doll&quot;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;[&quot;apple&quot;,&amp;nbsp;&quot;steel&quot;,&amp;nbsp;&quot;leaf&quot;,&amp;nbsp;&quot;apple&quot;,&amp;nbsp;&quot;leaf&quot;]&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;[5,&amp;nbsp;3,&amp;nbsp;5,&amp;nbsp;3,&amp;nbsp;7]&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;&quot;leaf&quot;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;[&quot;mirror&quot;,&amp;nbsp;&quot;net&quot;,&amp;nbsp;&quot;mirror&quot;,&amp;nbsp;&quot;net&quot;,&amp;nbsp;&quot;bottle&quot;]&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;[4,&amp;nbsp;1,&amp;nbsp;4,&amp;nbsp;1,&amp;nbsp;5]&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;&quot;mirror&quot;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
입출력 예 #1 &lt;br /&gt;본문에 설명된 대로 창고를 정리하면 clean_storage = [&quot;pencil&quot;, &quot;book&quot;], clean_num = [9, 1]이 됩니다. 따라서 가장 개수가 많은 물건인 &quot;pencil&quot;을 return합니다. &lt;br /&gt;&lt;br /&gt;입출력 예 #2 &lt;br /&gt;창고를 정리하면 clean_storage = [&quot;doll&quot;], clean_num = [4]가 됩니다. 따라서 가장 개수가 많은 물건인 &quot;doll&quot;을 return합니다.&lt;br /&gt;&lt;br /&gt;입출력 예 #3 &lt;br /&gt;창고를 정리하면 clean_storage = [&quot;apple&quot;, &quot;steel&quot;, &quot;leaf&quot;], clean_num = [8, 3, 12]가 됩니다. 따라서 가장 개수가 많은 물건인 &quot;leaf&quot;를 return합니다.&lt;br /&gt;&lt;br /&gt;입출력 예 #4 &lt;br /&gt;창고를 정리하면 clean_storage = [&quot;mirror&quot;, &quot;net&quot;, &quot;bottle&quot;], clean_num = [8, 2, 5]가 됩니다. 따라서 가장 개수가 많은 물건인 &quot;mirror&quot;를 return합니다.&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000;&quot; data-ke-size=&quot;size23&quot;&gt;16-4. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754031425263&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(storage, num):
    clean_storage = []
    clean_num = []
    for i in range(len(storage)):
        if storage[i] in clean_storage:
            pos = clean_storage.index(storage[i])
            clean_num[pos] += num[i]
        else:
            clean_storage.append(storage[i])
            clean_num.append(num[i])
            
    # 아래 코드에는 틀린 부분이 없습니다.
            
    max_num = max(clean_num)
    answer = clean_storage[clean_num.index(max_num)]
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Python/Coding Test</category>
      <category>PCCE 기출문제</category>
      <category>Programmers</category>
      <category>Python</category>
      <category>파이썬</category>
      <category>프로그래머스</category>
      <author>kj0on</author>
      <guid isPermaLink="true">https://kj0on.tistory.com/53</guid>
      <comments>https://kj0on.tistory.com/53#entry53comment</comments>
      <pubDate>Fri, 1 Aug 2025 15:20:06 +0900</pubDate>
    </item>
    <item>
      <title>[C/Python] x32 함수 호출 규약 성능 비교 (stdcall, cdecl, fastcall, vectorcall)</title>
      <link>https://kj0on.tistory.com/52</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;0. x32 함수 호출 규약 (32bit Calling Convention)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;32비트 함수 호출 규약의 자세한 내용은 &lt;a href=&quot;https://kj0on.tistory.com/42&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://kj0on.tistory.com/42&lt;/a&gt; 참고&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. Common Calling Convention (__stdcall, __cdecl, __fastcall, __vectorcall) 성능&lt;/h2&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 108px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 23.6047%; height: 22px; text-align: justify;&quot;&gt;항목&lt;/td&gt;
&lt;td style=&quot;width: 76.3953%; height: 22px; text-align: justify;&quot;&gt;의미&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 35px;&quot;&gt;
&lt;td style=&quot;width: 23.6047%; height: 35px; text-align: justify;&quot;&gt;테스트 함수&lt;/td&gt;
&lt;td style=&quot;width: 76.3953%; height: 35px; text-align: justify;&quot;&gt;int(int a, int b, int c, int b) &amp;rarr; a + b + c + d&lt;br /&gt;float(float a, float b, float c, float d) &amp;rarr; a + b + c + d&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 23.6047%; height: 17px; text-align: justify;&quot;&gt;ITERATIONS&lt;/td&gt;
&lt;td style=&quot;width: 76.3953%; height: 17px; text-align: justify;&quot;&gt;한 번의 샘플에서 각각의 테스트 함수를 몇 회 호출할지에 대한 값이다. 값이 클수록 측정 정밀도는 올라가지만 전체 실행 시간이 길어진다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 23.6047%; height: 17px; text-align: justify;&quot;&gt;SAMPLES&lt;/td&gt;
&lt;td style=&quot;width: 76.3953%; height: 17px; text-align: justify;&quot;&gt;독립적인 측정 값이다. 매 샘플마다 타이머를 초기화한 뒤 ITERATIONS 만큼 함수 호출을 반복해 소요 시간을 기록한다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 23.6047%; height: 17px; text-align: justify;&quot;&gt;우선순위 고정&lt;/td&gt;
&lt;td style=&quot;width: 76.3953%; height: 17px; text-align: justify;&quot;&gt;CPU&amp;nbsp;코어,&amp;nbsp;프로세스/스레드&amp;nbsp;우선순위를&amp;nbsp;고정해&amp;nbsp;잡음(스케줄링,&amp;nbsp;코어&amp;nbsp;마이그레이션)을&amp;nbsp;최소화한다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트는 노트북에서 실행했기 때문에 전력 관리로 인한 주파수 변동, 백그라운드 서비스 및 인터럽트에 의한 스케줄링 잡음, 공유 캐시 등 다양한 환경 요인에 노출된다. 동일 코어에 과부하가 반복되면 클록이 순간적으로 하락 할 수 있고, 이는 샘플 간 변동성을 키운다. 또한 고정된 단일 코어라도 OS 커널 스레드가 주기적으로 선점하면 지연이 누적된다. 이런 제약으로 인해 측정 시간(ms) 자체는 실행할 때마다 달라질 수 있다. 따라서 측정한 수치는 환경이 다른 시스템에도 같은 값이 나타난다는 보장을 할 수 없다. 그럼에도 불구하고 같은 실행 환경 안에서 네 가지 호출 규약을 동일한 로직으로 반복 측정했으므로 상대적 순위나 평균적인 비율 같은 비교 지표는 유의미하다고 할 수 있다. 다시 말해, 값의 절대치는 참고용이지만 호출 규약 간 상대 성능 차이를 파악하는 목적에는 충분하다.테스트 시 발생하는 변수를 최소화하기 위해 불필요한 백그라운드 애플리케이션과 서비스를 모두 종료하고 네트워크를 차단하였으며 각각의 설정들을 별도로 빌드해 수치 테이블을 생성했다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;br /&gt;1-1. Release &amp;amp; samples = 10,000 &amp;amp; iterations = 1,000,000&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;br /&gt;1-1-1. /Od Optimization&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bB6Abj/btsPoTrvWaV/SXjK36W335gwCPZ7q6m0p0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bB6Abj/btsPoTrvWaV/SXjK36W335gwCPZ7q6m0p0/img.png&quot; data-alt=&quot;[이미지37] All Samples (Release &amp;amp;amp; /Od &amp;amp;amp; samples = 10,000 &amp;amp;amp; iterations = 1,000,000)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bB6Abj/btsPoTrvWaV/SXjK36W335gwCPZ7q6m0p0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbB6Abj%2FbtsPoTrvWaV%2FSXjK36W335gwCPZ7q6m0p0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;757&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지37] All Samples (Release &amp;amp; /Od &amp;amp; samples = 10,000 &amp;amp; iterations = 1,000,000)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dpgp7x/btsPoUwPFJ3/o0zmvo2p9DKAidKOgh3bU0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dpgp7x/btsPoUwPFJ3/o0zmvo2p9DKAidKOgh3bU0/img.png&quot; data-alt=&quot;[이미지38] Performance (Release &amp;amp;amp; /Od &amp;amp;amp; samples = 10,000 &amp;amp;amp; iterations = 1,000,000)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dpgp7x/btsPoUwPFJ3/o0zmvo2p9DKAidKOgh3bU0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdpgp7x%2FbtsPoUwPFJ3%2Fo0zmvo2p9DKAidKOgh3bU0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;757&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지38] Performance (Release &amp;amp; /Od &amp;amp; samples = 10,000 &amp;amp; iterations = 1,000,000)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;Convention&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;mean (ms)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;std&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;min&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;(ms)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;max&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;(ms)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;cdecl&amp;nbsp;(int)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;3.406&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;1.011&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;2.343&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;11.461&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;fastcall&amp;nbsp;(int)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;3.451&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;0.810&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;2.507&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;10.238&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;stdcall&amp;nbsp;(int)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;3.412&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;0.929&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;2.329&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;10.034&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;vectorcall&amp;nbsp;(int)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;3.421&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;0.796&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;2.501&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;9.525&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;cdecl&amp;nbsp;(float)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;6.916&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;1.134&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;5.186&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;13.202&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;fastcall&amp;nbsp;(float)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;6.922&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;1.297&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;5.139&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;17.399&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;stdcall&amp;nbsp;(float)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;6.995&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;1.228&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;5.191&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;17.996&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;vectorcall&amp;nbsp;(float)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;5.029&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;1.015&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;3.724&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;12.245&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr data-ke-style=&quot;style6&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1-1-2. /O1 Optimization&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c5ygXF/btsPp2tOyMm/eI31KRn0CVyfKYRJjdwMY0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c5ygXF/btsPp2tOyMm/eI31KRn0CVyfKYRJjdwMY0/img.png&quot; data-alt=&quot;[이미지39] All Samples (Release &amp;amp;amp; /O1 &amp;amp;amp; samples = 10,000 &amp;amp;amp; iterations = 1,000,000)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c5ygXF/btsPp2tOyMm/eI31KRn0CVyfKYRJjdwMY0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc5ygXF%2FbtsPp2tOyMm%2FeI31KRn0CVyfKYRJjdwMY0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;757&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지39] All Samples (Release &amp;amp; /O1 &amp;amp; samples = 10,000 &amp;amp; iterations = 1,000,000)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FRqeD/btsPqQfhFuJ/aY5dP3LevXwLxsgkOdqna0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FRqeD/btsPqQfhFuJ/aY5dP3LevXwLxsgkOdqna0/img.png&quot; data-alt=&quot;[이미지40] Performance (Release &amp;amp;amp; /O1 &amp;amp;amp; samples = 10,000 &amp;amp;amp; iterations = 1,000,000)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FRqeD/btsPqQfhFuJ/aY5dP3LevXwLxsgkOdqna0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFRqeD%2FbtsPqQfhFuJ%2FaY5dP3LevXwLxsgkOdqna0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;757&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지40] Performance (Release &amp;amp; /O1 &amp;amp; samples = 10,000 &amp;amp; iterations = 1,000,000)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 153px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;Convention&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;mean&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;(ms)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;std&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;min&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;(ms)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;max&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;(ms)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;cdecl&amp;nbsp;(int)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;2.779&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.923&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;1.868&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;10.109&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;fastcall&amp;nbsp;(int)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;2.353&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.582&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;1.701&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;6.346&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;stdcall&amp;nbsp;(int)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;2.458&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.631&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;1.760&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;6.564&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;vectorcall&amp;nbsp;(int)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;2.342&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.577&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;1.714&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;5.745&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;cdecl&amp;nbsp;(float)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;6.643&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;1.429&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;4.919&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;13.806&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;fastcall&amp;nbsp;(float)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;6.331&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;1.084&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;4.917&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;10.431&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;stdcall&amp;nbsp;(float)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;6.383&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;1.132&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;4.923&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;12.397&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;vectorcall&amp;nbsp;(float)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;4.162&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.901&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;3.189&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;8.749&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr data-ke-style=&quot;style6&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1-1-3. /O2 Optimization&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7IBme/btsPrc3s0Kn/TWk9CJBB1ixmpb5Abox4AK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7IBme/btsPrc3s0Kn/TWk9CJBB1ixmpb5Abox4AK/img.png&quot; data-alt=&quot;[이미지41] All Samples (Release &amp;amp;amp; /O2 &amp;amp;amp; samples = 10,000 &amp;amp;amp; iterations = 1,000,000)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7IBme/btsPrc3s0Kn/TWk9CJBB1ixmpb5Abox4AK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7IBme%2FbtsPrc3s0Kn%2FTWk9CJBB1ixmpb5Abox4AK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;757&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지41] All Samples (Release &amp;amp; /O2 &amp;amp; samples = 10,000 &amp;amp; iterations = 1,000,000)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/W3nH5/btsPqWNhdqP/h1i1WBGkCa8AFyoXna7xg0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/W3nH5/btsPqWNhdqP/h1i1WBGkCa8AFyoXna7xg0/img.png&quot; data-alt=&quot;[이미지42] Performance (Release &amp;amp;amp; /O2 &amp;amp;amp; samples = 10,000 &amp;amp;amp; iterations = 1,000,000)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/W3nH5/btsPqWNhdqP/h1i1WBGkCa8AFyoXna7xg0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FW3nH5%2FbtsPqWNhdqP%2Fh1i1WBGkCa8AFyoXna7xg0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;757&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지42] Performance (Release &amp;amp; /O2 &amp;amp; samples = 10,000 &amp;amp; iterations = 1,000,000)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 153px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;Convention&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;mean&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;&amp;nbsp;(ms)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;std&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;min&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;&amp;nbsp;(ms)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;max&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;&amp;nbsp;(ms)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;cdecl&amp;nbsp;(int)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.691&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.562&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.390&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;8.392&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;fastcall&amp;nbsp;(int)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.634&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.254&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.405&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;6.452&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;stdcall&amp;nbsp;(int)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.646&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.255&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.382&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;5.160&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;vectorcall&amp;nbsp;(int)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.640&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.236&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.405&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;4.885&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;cdecl&amp;nbsp;(float)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;4.282&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.877&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;3.199&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;8.758&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;fastcall&amp;nbsp;(float)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;4.250&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.864&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;3.191&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;7.601&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;stdcall&amp;nbsp;(float)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;4.278&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.863&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;3.199&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;7.656&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;vectorcall&amp;nbsp;(float)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;4.260&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.873&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;3.181&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;8.707&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr data-ke-style=&quot;style6&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1-1-4. /Ox Optimization&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0fV7e/btsPpTqm8a4/7pDeCuOOJM9aUjDvNnzUc1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0fV7e/btsPpTqm8a4/7pDeCuOOJM9aUjDvNnzUc1/img.png&quot; data-alt=&quot;[이미지43] All Samples (Release &amp;amp;amp; /Ox &amp;amp;amp; samples = 10,000 &amp;amp;amp; iterations = 1,000,000)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0fV7e/btsPpTqm8a4/7pDeCuOOJM9aUjDvNnzUc1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0fV7e%2FbtsPpTqm8a4%2F7pDeCuOOJM9aUjDvNnzUc1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;757&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지43] All Samples (Release &amp;amp; /Ox &amp;amp; samples = 10,000 &amp;amp; iterations = 1,000,000)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cbaj2L/btsPqVOnsar/nKw8Kh3oNNkYltxo2tnYG0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cbaj2L/btsPqVOnsar/nKw8Kh3oNNkYltxo2tnYG0/img.png&quot; data-alt=&quot;[이미지44] Performance (Release &amp;amp;amp; /Ox &amp;amp;amp; samples = 10,000 &amp;amp;amp; iterations = 1,000,000)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cbaj2L/btsPqVOnsar/nKw8Kh3oNNkYltxo2tnYG0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcbaj2L%2FbtsPqVOnsar%2FnKw8Kh3oNNkYltxo2tnYG0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;757&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지44] Performance (Release &amp;amp; /Ox &amp;amp; samples = 10,000 &amp;amp; iterations = 1,000,000)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 153px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;Convention&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;mean (ms)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;std&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;min&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;(ms)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;max&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;(ms)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;cdecl&amp;nbsp;(int)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.795&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.725&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.421&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;8.409&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;fastcall&amp;nbsp;(int)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.651&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.362&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.382&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;5.303&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;stdcall&amp;nbsp;(int)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.626&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.402&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.379&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;6.035&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;vectorcall&amp;nbsp;(int)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.671&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.420&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.411&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;5.267&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;cdecl&amp;nbsp;(float)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;4.429&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.919&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;3.197&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;8.633&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;fastcall&amp;nbsp;(float)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;4.392&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.910&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;3.185&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;8.277&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;stdcall&amp;nbsp;(float)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;4.400&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.912&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;3.195&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;8.399&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;vectorcall&amp;nbsp;(float)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;4.366&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.913&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;3.186&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;8.801&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dBh2rR/btsPp9sZiP5/wuVYmmWaVH7Tk2a8Pyqaf1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dBh2rR/btsPp9sZiP5/wuVYmmWaVH7Tk2a8Pyqaf1/img.png&quot; data-alt=&quot;[이미지45] All Optimization Performance (Release &amp;amp;amp; samples = 10,000 &amp;amp;amp; iterations = 1,000,000)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dBh2rR/btsPp9sZiP5/wuVYmmWaVH7Tk2a8Pyqaf1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdBh2rR%2FbtsPp9sZiP5%2FwuVYmmWaVH7Tk2a8Pyqaf1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;757&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지45] All Optimization Performance (Release &amp;amp; samples = 10,000 &amp;amp; iterations = 1,000,000)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1-2. Debug &amp;amp; samples = 10,000 &amp;amp; iterations = 1,000,000&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;br /&gt;1-2-1. /Od Optimization&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dqYBRt/btsPpArgxs5/vKKbovZq8AiJ0H80VDcMx0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dqYBRt/btsPpArgxs5/vKKbovZq8AiJ0H80VDcMx0/img.png&quot; data-alt=&quot;[이미지46] All Samples (Debug &amp;amp;amp; /Od &amp;amp;amp; samples = 10,000 &amp;amp;amp; iterations = 1,000,000)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dqYBRt/btsPpArgxs5/vKKbovZq8AiJ0H80VDcMx0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdqYBRt%2FbtsPpArgxs5%2FvKKbovZq8AiJ0H80VDcMx0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;757&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지46] All Samples (Debug &amp;amp; /Od &amp;amp; samples = 10,000 &amp;amp; iterations = 1,000,000)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uGRpu/btsPql1awqs/McoNYyCPuuF2aM7khvWy61/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uGRpu/btsPql1awqs/McoNYyCPuuF2aM7khvWy61/img.png&quot; data-alt=&quot;[이미지47] Performance (Debug &amp;amp;amp; /Od &amp;amp;amp; samples = 10,000 &amp;amp;amp; iterations = 1,000,000)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uGRpu/btsPql1awqs/McoNYyCPuuF2aM7khvWy61/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuGRpu%2FbtsPql1awqs%2FMcoNYyCPuuF2aM7khvWy61%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;757&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지47] Performance (Debug &amp;amp; /Od &amp;amp; samples = 10,000 &amp;amp; iterations = 1,000,000)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 153px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;Convention&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;mean&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;(ms)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;std&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;min&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;(ms)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;max (ms)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;cdecl&amp;nbsp;(int)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;4.714&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;1.344&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;3.201&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;20.964&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;fastcall&amp;nbsp;(int)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;4.700&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;1.160&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;3.115&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;12.287&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;stdcall&amp;nbsp;(int)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;4.471&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;1.172&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;3.017&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;12.307&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;vectorcall&amp;nbsp;(int)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;4.456&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;1.089&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;3.064&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;12.875&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;cdecl&amp;nbsp;(float)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;8.763&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;1.604&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;5.955&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;19.541&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;fastcall&amp;nbsp;(float)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;8.311&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;2.277&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;5.910&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;24.668&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;stdcall&amp;nbsp;(float)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;8.827&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;2.722&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;5.882&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;34.158&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;vectorcall&amp;nbsp;(float)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;5.747&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;1.060&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;4.438&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;11.250&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr data-ke-style=&quot;style6&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1-2-2. /O1 Optimization&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgoBvm/btsPpkbf5dO/kFKlpVCSA0CrOM2IbjUiQK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgoBvm/btsPpkbf5dO/kFKlpVCSA0CrOM2IbjUiQK/img.png&quot; data-alt=&quot;[이미지48] All Samples (Debug &amp;amp;amp; /O1 &amp;amp;amp; samples = 10,000 &amp;amp;amp; iterations = 1,000,000)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgoBvm/btsPpkbf5dO/kFKlpVCSA0CrOM2IbjUiQK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgoBvm%2FbtsPpkbf5dO%2FkFKlpVCSA0CrOM2IbjUiQK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;757&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지48] All Samples (Debug &amp;amp; /O1 &amp;amp; samples = 10,000 &amp;amp; iterations = 1,000,000)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cfNIV6/btsPoYsPjwe/7p3d1YbQIA2rPL0KkfYrcK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cfNIV6/btsPoYsPjwe/7p3d1YbQIA2rPL0KkfYrcK/img.png&quot; data-alt=&quot;[이미지49] Performance (Debug &amp;amp;amp; /O1 &amp;amp;amp; samples = 10,000 &amp;amp;amp; iterations = 1,000,000)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cfNIV6/btsPoYsPjwe/7p3d1YbQIA2rPL0KkfYrcK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcfNIV6%2FbtsPoYsPjwe%2F7p3d1YbQIA2rPL0KkfYrcK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;757&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지49] Performance (Debug &amp;amp; /O1 &amp;amp; samples = 10,000 &amp;amp; iterations = 1,000,000)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 153px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;Convention&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;mean&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;(ms)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;std&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;min&lt;span style=&quot;color: #ffffff;&quot;&gt;&amp;nbsp;(ms)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;max&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;(ms)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;cdecl&amp;nbsp;(int)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;4.493&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;1.471&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;2.505&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;22.439&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;fastcall&amp;nbsp;(int)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;3.676&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;1.463&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;1.856&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;16.887&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;stdcall&amp;nbsp;(int)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;3.992&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;1.491&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;2.154&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;19.551&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;vectorcall&amp;nbsp;(int)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;3.272&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;1.141&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;1.815&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;10.341&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;cdecl&amp;nbsp;(float)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;6.915&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;1.809&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;4.924&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;26.329&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;fastcall&amp;nbsp;(float)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;6.651&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;1.296&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;4.908&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;13.354&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;stdcall&amp;nbsp;(float)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;7.004&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;1.731&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;4.911&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;29.354&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;vectorcall&amp;nbsp;(float)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;4.196&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.937&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;3.183&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;9.347&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr data-ke-style=&quot;style6&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1-2-3. /O2 Optimization&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dICX3A/btsPrbpZYgW/gY8tBJX8AwmKZfxRhoBud0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dICX3A/btsPrbpZYgW/gY8tBJX8AwmKZfxRhoBud0/img.png&quot; data-alt=&quot;[이미지50] All Samples (Debug &amp;amp;amp; /O2 &amp;amp;amp; samples = 10,000 &amp;amp;amp; iterations = 1,000,000)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dICX3A/btsPrbpZYgW/gY8tBJX8AwmKZfxRhoBud0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdICX3A%2FbtsPrbpZYgW%2FgY8tBJX8AwmKZfxRhoBud0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;757&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지50] All Samples (Debug &amp;amp; /O2 &amp;amp; samples = 10,000 &amp;amp; iterations = 1,000,000)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oC3a6/btsPpYkQlXr/oR3zsc67sLVp4aruXEYaKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oC3a6/btsPpYkQlXr/oR3zsc67sLVp4aruXEYaKk/img.png&quot; data-alt=&quot;[이미지51] Performance (Debug &amp;amp;amp; /O2 &amp;amp;amp; samples = 10,000 &amp;amp;amp; iterations = 1,000,000)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oC3a6/btsPpYkQlXr/oR3zsc67sLVp4aruXEYaKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoC3a6%2FbtsPpYkQlXr%2FoR3zsc67sLVp4aruXEYaKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;757&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지51] Performance (Debug &amp;amp; /O2 &amp;amp; samples = 10,000 &amp;amp; iterations = 1,000,000)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;Convention&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;mean (ms)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;std&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;min&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;(ms)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;max&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;(ms)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;cdecl&amp;nbsp;(int)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;3.050&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;0.911&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;2.162&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;10.216&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;fastcall&amp;nbsp;(int)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;2.457&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;0.618&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;1.812&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;6.956&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;stdcall&amp;nbsp;(int)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;2.531&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;0.647&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;1.820&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;6.550&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;vectorcall&amp;nbsp;(int)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;2.419&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;0.602&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;1.802&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;6.021&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;cdecl&amp;nbsp;(float)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;6.487&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;1.169&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;4.920&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;13.162&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;fastcall&amp;nbsp;(float)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;6.487&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;1.174&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;4.903&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;12.287&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;stdcall&amp;nbsp;(float)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;6.465&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;1.153&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;4.911&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;10.911&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;vectorcall&amp;nbsp;(float)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;4.130&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;0.878&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;3.182&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; text-align: justify;&quot;&gt;7.617&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr data-ke-style=&quot;style6&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1-2-4. /Ox Optimization&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uUuGw/btsPpdXJ7Ty/Syu6K5ve9VdcjkKLk3jkSk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uUuGw/btsPpdXJ7Ty/Syu6K5ve9VdcjkKLk3jkSk/img.png&quot; data-alt=&quot;[이미지52] All Samples (Debug &amp;amp;amp; /Ox &amp;amp;amp; samples = 10,000 &amp;amp;amp; iterations = 1,000,000)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uUuGw/btsPpdXJ7Ty/Syu6K5ve9VdcjkKLk3jkSk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuUuGw%2FbtsPpdXJ7Ty%2FSyu6K5ve9VdcjkKLk3jkSk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;757&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지52] All Samples (Debug &amp;amp; /Ox &amp;amp; samples = 10,000 &amp;amp; iterations = 1,000,000)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d9iqUi/btsPqxtASeg/lmaLZTcyKaa6RM28QgHsM0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d9iqUi/btsPqxtASeg/lmaLZTcyKaa6RM28QgHsM0/img.png&quot; data-alt=&quot;[이미지53] Performance (Debug &amp;amp;amp; /Ox &amp;amp;amp; samples = 10,000 &amp;amp;amp; iterations = 1,000,000)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d9iqUi/btsPqxtASeg/lmaLZTcyKaa6RM28QgHsM0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd9iqUi%2FbtsPqxtASeg%2FlmaLZTcyKaa6RM28QgHsM0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;757&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지53] Performance (Debug &amp;amp; /Ox &amp;amp; samples = 10,000 &amp;amp; iterations = 1,000,000)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 153px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;Convention&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;mean (ms)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;std&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;min&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;(ms)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;max&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;(ms)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;cdecl&amp;nbsp;(int)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;3.165&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.898&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;2.175&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;10.480&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;fastcall&amp;nbsp;(int)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;2.538&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.572&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;1.819&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;6.288&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;stdcall&amp;nbsp;(int)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;2.654&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.608&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;1.890&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;6.271&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;vectorcall&amp;nbsp;(int)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;2.518&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.570&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;1.809&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;5.869&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;cdecl&amp;nbsp;(float)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;6.610&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;1.144&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;4.932&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;12.458&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;fastcall&amp;nbsp;(float)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;6.574&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;1.139&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;4.926&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;13.941&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;stdcall&amp;nbsp;(float)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;6.568&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;1.132&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;4.894&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;11.032&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;vectorcall&amp;nbsp;(float)&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;4.232&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;0.860&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;3.190&lt;/td&gt;
&lt;td style=&quot;width: 20.0%; height: 17px; text-align: justify;&quot;&gt;7.682&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bR8Vrr/btsPoVpiyHs/QWUytki9iVGlvPJTpj8Rr1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bR8Vrr/btsPoVpiyHs/QWUytki9iVGlvPJTpj8Rr1/img.png&quot; data-alt=&quot;[이미지54] All Optimization Performance (Debug &amp;amp;amp; samples = 10,000 &amp;amp;amp; iterations = 1,000,000)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bR8Vrr/btsPoVpiyHs/QWUytki9iVGlvPJTpj8Rr1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbR8Vrr%2FbtsPoVpiyHs%2FQWUytki9iVGlvPJTpj8Rr1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;757&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지54] All Optimization Performance (Debug &amp;amp; samples = 10,000 &amp;amp; iterations = 1,000,000)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1-3. 수치 분석&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;수치를 분석하기에 앞서, 함수 호출 규약의 성능을 비교하기에 가장 적절한 최적화 수준이 무엇인지를 먼저 판단할 필요가 있다. 최적화가 충분히 적용되지 않은 경우, 일부 어셈블리 코드에서는 함수 호출 규약이 갖는 고유한 이점이 드러나지 않거나 왜곡될 수 있다. 반대로, 최적화가 과도하게 적용된 경우에는 함수 호출 자체가 제거되거나 인라인 처리되어, 규약 간 차이가 모두 상쇄되어 동일한 성능으로 수렴하는 상황이 발생할 수 있다. 따라서 수치를 올바르게 해석하려면 최적화가 적용되지 않은 상태, 최적화가 과도하게 적용된 상태, 분석에 적절한 상태를 구분하여 각각의 결과를 비교 분석해야 한다. 그래야만 함수 호출 규약 간 성능 차이를 정확하게 파악할 수 있다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;br /&gt;1-3-1. 최적화가 적용되지 않은 상태 (Release /Od, Debug /Od)&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;786&quot; data-origin-height=&quot;240&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dodppP/btsPqK7zdy5/nSHcJACMDq4IiLY3LlM2n0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dodppP/btsPqK7zdy5/nSHcJACMDq4IiLY3LlM2n0/img.png&quot; data-alt=&quot;[이미지55] Callee mov Stack&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dodppP/btsPqK7zdy5/nSHcJACMDq4IiLY3LlM2n0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdodppP%2FbtsPqK7zdy5%2FnSHcJACMDq4IiLY3LlM2n0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;786&quot; height=&quot;240&quot; data-origin-width=&quot;786&quot; data-origin-height=&quot;240&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지55] Callee mov Stack&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;/Od로 최적화를 적용하지 않는 경우 Callee에서 인자를 사용할 때 Stack으로 옮기는 동작이 추가된다. 즉, Register를 사용한다는 이점이 사라져 버린다. 이는 __fastcall, __vectorcall 규약에서 정수형 인자를 사용 할 때, Release, Debug 모두에서 나타난다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2773&quot; data-origin-height=&quot;2817&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4zO0Y/btsPoWPmEOw/NlHJB2MgyLEpu8iXiYNzA1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4zO0Y/btsPoWPmEOw/NlHJB2MgyLEpu8iXiYNzA1/img.jpg&quot; data-alt=&quot;[이미지56] /Od Optimization&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4zO0Y/btsPoWPmEOw/NlHJB2MgyLEpu8iXiYNzA1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4zO0Y%2FbtsPoWPmEOw%2FNlHJB2MgyLEpu8iXiYNzA1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2773&quot; height=&quot;2817&quot; data-origin-width=&quot;2773&quot; data-origin-height=&quot;2817&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지56] /Od Optimization&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 정수형 인자의 경우 /Od에서는 ECX, EDX를 사용하는 이점이 없어지기 때문에 Release, Debug에서 모든 함수호출 규약의 성능이 동일하게 나타난다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;875&quot; data-origin-height=&quot;274&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tRrh1/btsPqWfR5DZ/L0rptWTNyKq7sX6yGo4gyK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tRrh1/btsPqWfR5DZ/L0rptWTNyKq7sX6yGo4gyK/img.png&quot; data-alt=&quot;[이미지57] __vectorcall Callee&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tRrh1/btsPqWfR5DZ/L0rptWTNyKq7sX6yGo4gyK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtRrh1%2FbtsPqWfR5DZ%2FL0rptWTNyKq7sX6yGo4gyK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;875&quot; height=&quot;274&quot; data-origin-width=&quot;875&quot; data-origin-height=&quot;274&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지57] __vectorcall Callee&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;__vectorcall의 부동소수점 인자도 마찬가지로 Stack을 거치기 때문에 레지스터를 사용한다는 이점이 사라진다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3016&quot; data-origin-height=&quot;1850&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rriF6/btsPp4S5D8O/EKl3DIq1aFImMJq54xbsUk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rriF6/btsPp4S5D8O/EKl3DIq1aFImMJq54xbsUk/img.jpg&quot; data-alt=&quot;[이미지58] __vectorcall vs others Callee&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rriF6/btsPp4S5D8O/EKl3DIq1aFImMJq54xbsUk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrriF6%2FbtsPp4S5D8O%2FEKl3DIq1aFImMJq54xbsUk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3016&quot; height=&quot;1850&quot; data-origin-width=&quot;3016&quot; data-origin-height=&quot;1850&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지58] __vectorcall vs others Callee&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;__vectorcall의 경우 Callee에서 값을 반환 할 때, addss 명령어를 사용한다. 반면, __vectorcall을 제외한 다른 함수 호출 규약의 경우 fld을 사용한다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;484&quot; data-origin-height=&quot;413&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/85xfN/btsPpQ8C7sb/vuNfYTd1FkKZA6tlfcpYJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/85xfN/btsPpQ8C7sb/vuNfYTd1FkKZA6tlfcpYJk/img.png&quot; data-alt=&quot;[이미지59] __vectorcall vs others Caller&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/85xfN/btsPpQ8C7sb/vuNfYTd1FkKZA6tlfcpYJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F85xfN%2FbtsPpQ8C7sb%2FvuNfYTd1FkKZA6tlfcpYJk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;484&quot; height=&quot;413&quot; data-origin-width=&quot;484&quot; data-origin-height=&quot;413&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지59] __vectorcall vs others Caller&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;call 이후 반환값을 사용할 때에도 차이가 발생하는데, __vectorcall의 경우 movss, 다른 규약의 경우 fstp를 사용한다는 점이다. Caller에서 __vectorcall 이외의 다른 규약은 인자를 전달할 때 더 복잡한 과정을 거치게 되는데, Callee에서 인자를 사용할 때와 결합해 보면 __vectorcall 규약과 다른 규약의 차이점은 push ecx(Stack 공간 확보)밖에 없었다. 이는 앞서 정수형 인자의 실행속도가 동일하게 나타난다는 점을 근거로 실행 속도에는 큰 영향을 주지 않는것으로 판단된다(ecx, edx 사용으로 push가 2번 없어졌기 때문). 따라서 눈에 나타나는 차이점은 명령어 사용의 차이점 밖에 확인하지 못했다. 문제는 두 명령어 모두 Stack을 거치기 때문에 왜 __vectorcall이 빠르게 나타나는지의 이유를 알 수 없다는 점이다. 이 부분은 정확하게 판단하기 힘들어 GPT의 도움을 받았다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;왜&amp;nbsp;둘&amp;nbsp;다&amp;nbsp;스택을&amp;nbsp;거치는데도&amp;nbsp;__vectorcall 이&amp;nbsp;더&amp;nbsp;빠른가?&amp;nbsp;(GPT)&lt;/p&gt;
&lt;div style=&quot;background-color: #fafafa; color: #333333;&quot; data-text-less=&quot;닫기&quot; data-text-more=&quot;더보기&quot; data-ke-type=&quot;moreLess&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p style=&quot;color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;구분 __vectorcall (디버그 빌드에서 관찰) __cdecl / __stdcall / __fastcall (float 반환)&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;반환 경로&lt;/td&gt;
&lt;td&gt;movss xmm0, [result] &amp;ensp;&amp;rarr;&amp;ensp;movss [result], xmm0&amp;mdash;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;SSE(Load + Store)&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;2 &amp;micro;op&lt;/td&gt;
&lt;td&gt;fld [result] &amp;ensp;&amp;rarr;&amp;ensp;fstp [result]&amp;mdash;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;x87 FPU&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;2 &amp;micro;op + 80‑bit&amp;rarr;32‑bit 변환&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;micro;op latency (대략)&lt;/td&gt;
&lt;td&gt;movss load &amp;asymp; 4 cyc&amp;emsp;movss store &amp;asymp; 4 cyc (병렬)&lt;/td&gt;
&lt;td&gt;fld &amp;asymp; 6‑8 cyc&amp;emsp;fstp &amp;asymp; 8‑12 cyc (연속)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;파이프라인&lt;/td&gt;
&lt;td&gt;최신 SSE 로드/스토어 포트 (Port 0/2/3) &amp;rarr;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;OOO 겹침 가능&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;레거시 x87 파이프라인 (Port 0 한정, &amp;mu;‑code 도움) &amp;rarr;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;직렬화 경향&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;변환 비용&lt;/td&gt;
&lt;td&gt;32‑bit &amp;rarr; 32‑bit 그대로&lt;/td&gt;
&lt;td&gt;80‑bit 내부 정밀도 &amp;harr; 32‑bit 변환 + 라운딩&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Store‑to‑Load FW 패널티&amp;sup1;&lt;/td&gt;
&lt;td&gt;없음 (Load&amp;rarr;계산&amp;rarr;Store)&lt;/td&gt;
&lt;td&gt;Load&amp;ndash;Store 사이에 FPU pop, 더 긴 의존 사슬&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Caller 후속 사용&lt;/td&gt;
&lt;td&gt;이미 XMM0 에 있음 &amp;rarr; SSE 명령 즉시 사용&lt;/td&gt;
&lt;td&gt;메모리 저장 후 다시&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;movss 로 XMM0 재로딩&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;필요&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote style=&quot;background-color: #000000; color: #333333; text-align: center;&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p style=&quot;color: #666666;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;sup1;&amp;nbsp;Store‑to‑Load&amp;nbsp;Forwarding 패널티: push/fstp 등&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;Store &amp;rarr; 직후 Load&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;패턴에서 3‑5 cycle 지연이 추가되는 현상.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p style=&quot;color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;1. &lt;b&gt;SSE movss&amp;nbsp;vs&amp;nbsp;x87 fld/fstp의 구조적 차이&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;SSE movss&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;파이프라인 2 포트를 사용해 Load&amp;nbsp;+&amp;nbsp;Store 를&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;병렬&lt;/b&gt;로 실행할 수 있다.&lt;/li&gt;
&lt;li&gt;4 byte 그대로 옮기므로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;형변환&amp;middot;라운딩이 전혀 없다&lt;/b&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;x87 fld/fstp&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;x87 스택 레지스터는 80‑bit 내부 정밀도(1‑sign + 15‑exp + 64‑mant).&lt;/li&gt;
&lt;li&gt;fld 는 32‑bit&amp;nbsp;&amp;rarr;&amp;nbsp;80‑bit 변환, fstp 는 80‑bit&amp;nbsp;&amp;rarr;&amp;nbsp;32‑bit 변환 + 스택 팝.&lt;/li&gt;
&lt;li&gt;인텔 &amp;mu;아키텍처에서 x87 명령은 대부분&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&amp;mu;‑code assist&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;로 Port 0 에서만 실행 &amp;rarr;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;병렬성 낮음&lt;/b&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p style=&quot;color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;2. &lt;b&gt;&amp;ldquo;같이 스택을 건다&amp;rdquo;의 함정&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디버그 모드 홈‑슬롯 때문에 둘 다 메모리를 쓰지만&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;메모리‑트래픽량과 수행 순서&lt;/b&gt;가 다르다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;vectorcall&lt;/b&gt;&amp;nbsp;:
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;연산 결과가 이미 XMM0 지연값에 있음.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Store&lt;/b&gt;(movss)&amp;nbsp;1 회만 하면 홈‑슬롯 완.&lt;/li&gt;
&lt;li&gt;Caller 가 결과를 바로 XMM0 로 이용하면&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;Load를 건너뛴다.&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;기존 규약&lt;/b&gt;&amp;nbsp;:
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;연산 결과가 x87 ST(0).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Store&lt;/b&gt;(fstp)&amp;nbsp;&amp;rarr; 메모리.&lt;/li&gt;
&lt;li&gt;Caller 가 SSE 레지스터가 필요하면 다시&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;Load&lt;/b&gt;(movss).&lt;/li&gt;
&lt;li&gt;Load 가 바로 앞 Store 를 읽어야 하므로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;S‑to‑L FW 패널티&lt;/b&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; 실질적으로 &amp;ldquo;Store 1 + Load 0&amp;rdquo; 대 &amp;ldquo;Store 1 + Load 1 + FW 패널티&amp;rdquo; 차이가 된다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p style=&quot;color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;3. &lt;b&gt;정수 길드와 달리 float 길드에서 격차가 큰 이유&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;정수 함수&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;반환은 EAX 로 통일 &amp;rarr; 모든 규약이&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;GPR mov 1 회&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;로 끝난다.&lt;br /&gt;/Od 가 스필을 만들더라도 GPR 경로와 x87 변환 같은 추가 작업 이 없다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;float 함수&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;는 규약마다 반환 채널이 갈린다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;vectorcall : XMM0 규정&lt;/li&gt;
&lt;li&gt;나머지 : x87 ST(0) 규정&lt;br /&gt;&amp;rArr; 디버그 빌드에서도&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;계산 결과가 어느 도메인(SSE or x87)에 있느냐&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;차이가 그대로 남고,&lt;br /&gt;x87 &amp;harr;&amp;nbsp;SSE 컨버전&amp;middot;레거시 파이프라인 지연이 성능 차로 나타난다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p style=&quot;color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;4.&amp;nbsp;&lt;b&gt;직관적 숫자 시뮬레이션&lt;/b&gt;&lt;/p&gt;
스텝 vectorcall (cycle) cdecl (cycle) 비고
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;결과 준비&lt;/td&gt;
&lt;td&gt;0 (이미 XMM0)&lt;/td&gt;
&lt;td&gt;0‑1 (x87)&lt;/td&gt;
&lt;td&gt;addss vs addss 차이 무시&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Store 홈슬롯&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;&amp;nbsp;movss vs fstp&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Caller 재‑Load&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;+4&amp;nbsp;+&amp;nbsp;FW&amp;nbsp;3&lt;/td&gt;
&lt;td&gt;vectorcall 생략&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;합계&lt;/td&gt;
&lt;td&gt;&lt;b&gt;&amp;asymp; 4&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;&amp;asymp; 16‑17&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;4&amp;times;100 만 &amp;rarr; 4 ms vs 16 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4 ms 대 16 ms = 측정 결과에서 &amp;ldquo;4 배 차이&amp;rdquo; 로 확인 가능.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p style=&quot;color: #000000;&quot; data-ke-size=&quot;size18&quot;&gt;정리 한 문장&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #000000; color: #333333; text-align: center;&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p style=&quot;color: #666666;&quot; data-ke-size=&quot;size16&quot;&gt;디버그 빌드라도 __vectorcall 은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;최신 SSE 경로(빠른 movss 2 &amp;micro;op, 변환 없음)&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;로 반환값을 처리하지만 다른 규약은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;느린 x87 fld/fstp(80&amp;rarr;32 bit 변환 + 레거시 파이프라인 + Store&amp;rarr;Load 패널티)&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;를 거치므로, 둘 다 스택을 스치는 것처럼 보여도 메모리 왕복과 마이크로아키텍처 지연이 훨씬 적은 vectorcall 이 압도적으로 빠르게 측정된다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2773&quot; data-origin-height=&quot;2866&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b6xWnr/btsPrd9uNxx/TjnKa5hqP4zd10sd4swr6k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b6xWnr/btsPrd9uNxx/TjnKa5hqP4zd10sd4swr6k/img.jpg&quot; data-alt=&quot;[이미지60] /Od Optimization&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b6xWnr/btsPrd9uNxx/TjnKa5hqP4zd10sd4swr6k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb6xWnr%2FbtsPrd9uNxx%2FTjnKa5hqP4zd10sd4swr6k%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2773&quot; height=&quot;2866&quot; data-origin-width=&quot;2773&quot; data-origin-height=&quot;2866&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지60] /Od Optimization&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;/Od 최적화 환경에서는 반환값 처리 방식의 차이로 인해 부동소수점 연산의 경우 __vectorcall이 다른 호출 규약보다 더 나은 성능을 보이는 경향이 있다. 하지만 중요한 점은 이러한 성능 차이가 실제 함수 호출 규약 자체의 성능 우위 때문이라기보다는 레지스터 사용 제한, 반환 경로(x87 vs SSE)의 차이에 기인한다는 것이다. 따라서 /Od 환경에서 관측된 성능 차이를 호출 규약 간 성능 차이로 결론짓는 것은 적절하지 않다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style6&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1-3-2. 최적화가 과도하게 적용된 상태 (Release /O2, /Ox, Debug /O2, /Ox)&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;681&quot; data-origin-height=&quot;488&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kUDmw/btsPpkh5XQE/qd9OoUZPH0k3xjsrA0jPRK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kUDmw/btsPpkh5XQE/qd9OoUZPH0k3xjsrA0jPRK/img.png&quot; data-alt=&quot;[이미지61] __fastcall Caller Optimization&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kUDmw/btsPpkh5XQE/qd9OoUZPH0k3xjsrA0jPRK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkUDmw%2FbtsPpkh5XQE%2Fqd9OoUZPH0k3xjsrA0jPRK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;681&quot; height=&quot;488&quot; data-origin-width=&quot;681&quot; data-origin-height=&quot;488&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지61] __fastcall Caller Optimization&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Release에서는 최적화가 적용되면서 컴파일러가 함수 호출 자체를 제거하거나 인라인 처리하는 경우가 많다. 특히 단순한 함수의 경우 컴파일러는 별도의 call 없이 해당 함수의 연산 결과를 바로 계산하거나, 결과 값을 그대로 다음 연산으로 넘긴다(printf 인자). 위 [이미지61]는 처음 예제 코드에 해당하며, 성능 평가에 사용된 테스트 함수가 아니다. 최적화가 어떻게 나타나는지에 대한 예시이며, 어떻게 최적화가 이루어질지는 코드 구성에 따라 달라진다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;583&quot; data-origin-height=&quot;129&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Qjfvs/btsPp6QRrkS/nbC4pn92U6mUEWrwlYZeJK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Qjfvs/btsPp6QRrkS/nbC4pn92U6mUEWrwlYZeJK/img.png&quot; data-alt=&quot;[이미지62] Release /O2 Optimization&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Qjfvs/btsPp6QRrkS/nbC4pn92U6mUEWrwlYZeJK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQjfvs%2FbtsPp6QRrkS%2FnbC4pn92U6mUEWrwlYZeJK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;583&quot; height=&quot;129&quot; data-origin-width=&quot;583&quot; data-origin-height=&quot;129&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지62] Release /O2 Optimization&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 [이미지62]는 실제 성능평가에 사용된 정수형 __vectorcall의 테스트 함수에 해당한다. 테스트 함수를 보면 레지스터를 이용해서 인자를 전달하는 것으로 봐서 함수 호출 규약 성능평가에 적절한 것으로 보인다(Callee에서도 레지스터를 사용한다). 한가지 주목할 만한 점이 있는데 함수 리턴값을 EDI에 넣는다는 것이다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;351&quot; data-origin-height=&quot;162&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vZ7RB/btsPrayctSj/WKbZWujsRi3ion1PhFZJRk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vZ7RB/btsPrayctSj/WKbZWujsRi3ion1PhFZJRk/img.png&quot; data-alt=&quot;[이미지62] Release /O2 Optimization&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vZ7RB/btsPrayctSj/WKbZWujsRi3ion1PhFZJRk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvZ7RB%2FbtsPrayctSj%2FWKbZWujsRi3ion1PhFZJRk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;351&quot; height=&quot;162&quot; data-origin-width=&quot;351&quot; data-origin-height=&quot;162&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지62] Release /O2 Optimization&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 최적화 된 코드를 분석해 보면 반복문이 나타난다. 처음 ECX에 0x0F4240의 값을 넣는 것을 확인할 수 있는데, 이는 1,000,000에 해당하는 값으로 iterations에 해당한다. 코드를 보면 EAX에 EDI( __vectorcall 정수형 덧셈 반환값)를 누산하고 있다. jne 조건부 분기로 어디로 jmp하는지를 살펴보면 0x4014B4인 누산하는 부분이다. 즉, 처음 함수를 호출해 정수형 덧셈을 한번만 진행한 다음, 이후 함수를 거치지 않고 반환 값만 누산하는 동작을 수행한다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/W3nH5/btsPqWNhdqP/h1i1WBGkCa8AFyoXna7xg0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/W3nH5/btsPqWNhdqP/h1i1WBGkCa8AFyoXna7xg0/img.png&quot; data-alt=&quot;[이미지63] Performance (Release &amp;amp;amp; /O2 &amp;amp;amp; samples = 10,000 &amp;amp;amp; iterations = 1,000,000)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/W3nH5/btsPqWNhdqP/h1i1WBGkCa8AFyoXna7xg0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FW3nH5%2FbtsPqWNhdqP%2Fh1i1WBGkCa8AFyoXna7xg0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;757&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지63] Performance (Release &amp;amp; /O2 &amp;amp; samples = 10,000 &amp;amp; iterations = 1,000,000)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 결과 모든 성능이 동일하게 나타난다. 실제 함수 호출 규약에 대한 연산은 한번만 진행하고, 그 반환값을 누산하는 코드로 최적화가 이루어 졌기 때문에 같은 동작을 하고 있기 때문이다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;583&quot; data-origin-height=&quot;254&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ywOc6/btsPpZEsNNM/ARqowa8zOJY8kKVGJsBYv1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ywOc6/btsPpZEsNNM/ARqowa8zOJY8kKVGJsBYv1/img.png&quot; data-alt=&quot;[이미지64] Release /O1 Optimization&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ywOc6/btsPpZEsNNM/ARqowa8zOJY8kKVGJsBYv1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FywOc6%2FbtsPpZEsNNM%2FARqowa8zOJY8kKVGJsBYv1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;583&quot; height=&quot;254&quot; data-origin-width=&quot;583&quot; data-origin-height=&quot;254&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지64] Release /O1 Optimization&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;/O1 최적화의 경우 iterations 값 만큼 반복을 수행할 때, 함수 호출도 같이 포함되는 것을 확인할 수 있다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 153px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 25.0%; height: 17px; text-align: justify;&quot;&gt;Convention&lt;/td&gt;
&lt;td style=&quot;width: 25.0%; height: 17px; text-align: justify;&quot;&gt;Release /O1&lt;/td&gt;
&lt;td style=&quot;width: 25.0%; height: 17px; text-align: justify;&quot;&gt;Release /O2&lt;/td&gt;
&lt;td style=&quot;width: 25.0%; height: 17px; text-align: justify;&quot;&gt;Release /Ox&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 25.0%; height: 17px; text-align: justify;&quot;&gt;__cdecl&amp;nbsp;(Release)&lt;/td&gt;
&lt;td style=&quot;width: 25.0%; height: 17px; text-align: justify;&quot;&gt;X&lt;/td&gt;
&lt;td style=&quot;width: 25.0%; height: 17px; text-align: justify;&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;width: 25.0%; height: 17px; text-align: justify;&quot;&gt;O&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 25.0%; height: 17px; text-align: justify;&quot;&gt;__stdcall&amp;nbsp;(Release)&lt;/td&gt;
&lt;td style=&quot;width: 25.0%; height: 17px; text-align: justify;&quot;&gt;X&lt;/td&gt;
&lt;td style=&quot;width: 25.0%; height: 17px; text-align: justify;&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;width: 25.0%; height: 17px; text-align: justify;&quot;&gt;O&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 25.0%; height: 17px; text-align: justify;&quot;&gt;__fastcall&amp;nbsp;(Release)&lt;/td&gt;
&lt;td style=&quot;width: 25.0%; height: 17px; text-align: justify;&quot;&gt;X&lt;/td&gt;
&lt;td style=&quot;width: 25.0%; height: 17px; text-align: justify;&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;width: 25.0%; height: 17px; text-align: justify;&quot;&gt;O&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 25.0%; height: 17px; text-align: justify;&quot;&gt;__vectorcall&amp;nbsp;(Release)&lt;/td&gt;
&lt;td style=&quot;width: 25.0%; height: 17px; text-align: justify;&quot;&gt;X&lt;/td&gt;
&lt;td style=&quot;width: 25.0%; height: 17px; text-align: justify;&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;width: 25.0%; height: 17px; text-align: justify;&quot;&gt;O&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 25.0%; height: 17px; text-align: justify;&quot;&gt;__cdecl&amp;nbsp;(Debug)&lt;/td&gt;
&lt;td style=&quot;width: 25.0%; height: 17px; text-align: justify;&quot;&gt;X&lt;/td&gt;
&lt;td style=&quot;width: 25.0%; height: 17px; text-align: justify;&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;width: 25.0%; height: 17px; text-align: justify;&quot;&gt;O&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 25.0%; height: 17px; text-align: justify;&quot;&gt;__stdcall&amp;nbsp;(Debug)&lt;/td&gt;
&lt;td style=&quot;width: 25.0%; height: 17px; text-align: justify;&quot;&gt;X&lt;/td&gt;
&lt;td style=&quot;width: 25.0%; height: 17px; text-align: justify;&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;width: 25.0%; height: 17px; text-align: justify;&quot;&gt;O&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 25.0%; height: 17px; text-align: justify;&quot;&gt;__fastcall&amp;nbsp;(Debug)&lt;/td&gt;
&lt;td style=&quot;width: 25.0%; height: 17px; text-align: justify;&quot;&gt;X&lt;/td&gt;
&lt;td style=&quot;width: 25.0%; height: 17px; text-align: justify;&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;width: 25.0%; height: 17px; text-align: justify;&quot;&gt;O&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 25.0%; height: 17px; text-align: justify;&quot;&gt;__vectorcall&amp;nbsp;(Debug)&lt;/td&gt;
&lt;td style=&quot;width: 25.0%; height: 17px; text-align: justify;&quot;&gt;X&lt;/td&gt;
&lt;td style=&quot;width: 25.0%; height: 17px; text-align: justify;&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;width: 25.0%; height: 17px; text-align: justify;&quot;&gt;O&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 표는 최적화가 함수 호출에 영향을 주는지의 상태를 표시한 결과다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style6&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1-3-3. 분석에 적절한 상태(Release /O1, Debug /O1)&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4544&quot; data-origin-height=&quot;2931&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/y1b7Y/btsPpwJlMVF/0waZKFpcyidpFvC8viKJa0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/y1b7Y/btsPpwJlMVF/0waZKFpcyidpFvC8viKJa0/img.jpg&quot; data-alt=&quot;[이미지65] Debug /O1 int test function&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/y1b7Y/btsPpwJlMVF/0waZKFpcyidpFvC8viKJa0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fy1b7Y%2FbtsPpwJlMVF%2F0waZKFpcyidpFvC8viKJa0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4544&quot; height=&quot;2931&quot; data-origin-width=&quot;4544&quot; data-origin-height=&quot;2931&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지65] Debug /O1 int test function&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;5292&quot; data-origin-height=&quot;2840&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JqHfP/btsPqGYFJ9k/UPIjBZB8csjvbkPzbyYfzk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JqHfP/btsPqGYFJ9k/UPIjBZB8csjvbkPzbyYfzk/img.jpg&quot; data-alt=&quot;[이미지66] Debug /O1 float test function&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JqHfP/btsPqGYFJ9k/UPIjBZB8csjvbkPzbyYfzk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJqHfP%2FbtsPqGYFJ9k%2FUPIjBZB8csjvbkPzbyYfzk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;5292&quot; height=&quot;2840&quot; data-origin-width=&quot;5292&quot; data-origin-height=&quot;2840&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지66] Debug /O1 float test function&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Debug 또는 Release 빌드에 /O1 최적화를 적용하면, Caller와 Callee 간의 인수 전달 순서와 방식은 최적화되지 않고 그대로 유지된다. 또한 함수 호출 자체도 최적화되지 않기 때문에, 반복 횟수인 iterations만큼 함수가 실제로 호출된다는 점이 보장된다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FRqeD/btsPqQfhFuJ/aY5dP3LevXwLxsgkOdqna0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FRqeD/btsPqQfhFuJ/aY5dP3LevXwLxsgkOdqna0/img.png&quot; data-alt=&quot;[이미지67] Performance (Release &amp;amp;amp; /O1 &amp;amp;amp; samples = 10,000 &amp;amp;amp; iterations = 1,000,000)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FRqeD/btsPqQfhFuJ/aY5dP3LevXwLxsgkOdqna0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFRqeD%2FbtsPqQfhFuJ%2FaY5dP3LevXwLxsgkOdqna0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;757&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지67] Performance (Release &amp;amp; /O1 &amp;amp; samples = 10,000 &amp;amp; iterations = 1,000,000)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Release 빌드에서는 함수 호출 자체는 최적화되지 않더라도 주변 코드가 광범위하게 최적화되기 때문에, 호출 규약에 따른 성능 차이는 상대적으로 작게 나타난다. 이러한 이유로 함수 호출 규약 간의 성능을 명확히 비교하기 위해서는 Debug 빌드에 /O1 최적화를 적용한 상태가 가장 적절한 분석 환경이라 할 수 있다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgoBvm/btsPpkbf5dO/kFKlpVCSA0CrOM2IbjUiQK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgoBvm/btsPpkbf5dO/kFKlpVCSA0CrOM2IbjUiQK/img.png&quot; data-alt=&quot;[이미지68] All Samples (Debug &amp;amp;amp; /O1 &amp;amp;amp; samples = 10,000 &amp;amp;amp; iterations = 1,000,000)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgoBvm/btsPpkbf5dO/kFKlpVCSA0CrOM2IbjUiQK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgoBvm%2FbtsPpkbf5dO%2FkFKlpVCSA0CrOM2IbjUiQK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;757&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지68] All Samples (Debug &amp;amp; /O1 &amp;amp; samples = 10,000 &amp;amp; iterations = 1,000,000)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cfNIV6/btsPoYsPjwe/7p3d1YbQIA2rPL0KkfYrcK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cfNIV6/btsPoYsPjwe/7p3d1YbQIA2rPL0KkfYrcK/img.png&quot; data-alt=&quot;[이미지69] Performance (Debug &amp;amp;amp; /O1 &amp;amp;amp; samples = 10,000 &amp;amp;amp; iterations = 1,000,000)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cfNIV6/btsPoYsPjwe/7p3d1YbQIA2rPL0KkfYrcK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcfNIV6%2FbtsPoYsPjwe%2F7p3d1YbQIA2rPL0KkfYrcK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;757&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지69] Performance (Debug &amp;amp; /O1 &amp;amp; samples = 10,000 &amp;amp; iterations = 1,000,000)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 153px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;Convention&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;mean&amp;nbsp;&lt;span style=&quot;color: #ffffff;&quot;&gt;(ms)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;std&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;min&lt;span style=&quot;color: #ffffff;&quot;&gt;&amp;nbsp;(ms)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;max&amp;nbsp;&lt;span style=&quot;color: #ffffff;&quot;&gt;(ms)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;cdecl&amp;nbsp;(int)&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;4.493&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;1.471&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;2.505&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;22.439&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;fastcall&amp;nbsp;(int)&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;3.676&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;1.463&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;1.856&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;16.887&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;stdcall&amp;nbsp;(int)&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;3.992&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;1.491&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;2.154&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;19.551&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;vectorcall&amp;nbsp;(int)&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;3.272&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;1.141&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;1.815&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;10.341&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;cdecl&amp;nbsp;(float)&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;6.915&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;1.809&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;4.924&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;26.329&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;fastcall&amp;nbsp;(float)&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;6.651&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;1.296&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;4.908&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;13.354&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;stdcall&amp;nbsp;(float)&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;7.004&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;1.731&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;4.911&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;29.354&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;vectorcall&amp;nbsp;(float)&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;4.196&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;0.937&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;3.183&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;9.347&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;max(최대값)은 오버헤드에 따라 값의 변동성이 크기 때문에 신뢰할 수 있는 지표로 보기 어렵다. 따라서 mean(평균), std(표준편차), min(최소 실행 시간) 세 가지 지표에 가중치를 부여하여, int와 float 각각에 대한 성능 순위를 평가한다. 각각의 수치가 낮을수록 더 좋은 성능으로 평가한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 성능 평가&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dFlBn4/btsPpSk5WQA/nZmVXNncjIhMAEtrBwkiw0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dFlBn4/btsPpSk5WQA/nZmVXNncjIhMAEtrBwkiw0/img.png&quot; data-alt=&quot;[이미지70] Calling Convention Performance Score by Weight Configuration(INT)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dFlBn4/btsPpSk5WQA/nZmVXNncjIhMAEtrBwkiw0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdFlBn4%2FbtsPpSk5WQA%2FnZmVXNncjIhMAEtrBwkiw0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;757&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지70] Calling Convention Performance Score by Weight Configuration(INT)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9LoCJ/btsPqSkhORx/BCJtVDkKi4ZfKroy2W0DIK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9LoCJ/btsPqSkhORx/BCJtVDkKi4ZfKroy2W0DIK/img.png&quot; data-alt=&quot;[이미지71] Calling Convention Performance Score by Weight Configuration(FLOAT)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9LoCJ/btsPqSkhORx/BCJtVDkKi4ZfKroy2W0DIK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9LoCJ%2FbtsPqSkhORx%2FBCJtVDkKi4ZfKroy2W0DIK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;757&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지71] Calling Convention Performance Score by Weight Configuration(FLOAT)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가중치 0.1단위를 모두 조합했을 때 나타나는 그래프는 위와 같다. 그래프의 수치가 높을 수록 더 좋은 성능을 의미한다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ztJUx/btsPqJVaf5X/xlX2gRiWQcWWJjVYSyry91/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ztJUx/btsPqJVaf5X/xlX2gRiWQcWWJjVYSyry91/img.png&quot; data-alt=&quot;[이미지72] Aggregated Normalized Score (FLOAT &amp;amp;amp; INT)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ztJUx/btsPqJVaf5X/xlX2gRiWQcWWJjVYSyry91/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FztJUx%2FbtsPqJVaf5X%2FxlX2gRiWQcWWJjVYSyry91%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;757&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지72] Aggregated Normalized Score (FLOAT &amp;amp; INT)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 스코어를 종합했을 때 나타나는 그래프는 위와 같다. 이 그래프는 평균(mean), 최소값(min), 그리고 표준편차(std)를 모두 포함한 가중치 기반 점수를 반영한 결과이며, 표준편차가 포함되었기 때문에 실행 시간의 일관성(안정성) 또한 평가 기준에 영향을 준다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bE23JQ/btsPoUYjDjg/3RjT2bmjrhhq9ruZBDbKUK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bE23JQ/btsPoUYjDjg/3RjT2bmjrhhq9ruZBDbKUK/img.png&quot; data-alt=&quot;[이미지73] Aggregated Normalized Score (FLOAT &amp;amp;amp; INT) no std&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bE23JQ/btsPoUYjDjg/3RjT2bmjrhhq9ruZBDbKUK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbE23JQ%2FbtsPoUYjDjg%2F3RjT2bmjrhhq9ruZBDbKUK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;757&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;757&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지73] Aggregated Normalized Score (FLOAT &amp;amp; INT) no std&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[이미지 73]은 표준편차를 제외하고 평균 및 최소 실행 시간만을 기준으로 산출한 호출 규약별 성능 점수를 나타낸다. 정수형(int)에서는 __vectorcall과 __fastcall이 레지스터 기반 인수 전달 방식을 사용함에 따라 __stdcall과 __cdecl보다 높은 점수를 기록하였다. 다만, 이들 간의 성능 차이는 상대적으로 크지 않으며, 레지스터를 사용하는 여부가 정수 연산 성능에 영향을 주긴 하지만 절대적인 차이를 유발하지는 않음을 보여준다. 이는 사용할 수 있는 정수형 레지스터가 2개에 불과하며, 그 외 인수는 스택을 통해 전달된다는 구조적 제약에 기인한 것으로, 반복 횟수(SAMPLES)가 증가할수록 이 차이는 더 뚜렷하게 나타날 가능성이 있다. 반면, 부동소수점(float)에서는 __vectorcall을 제외한 나머지 호출 규약의 점수가 급격히 낮게 나타났으며, 이는 부동소수점 인자를 XMM 레지스터로 직접 전달할 수 있는 __vectorcall의 구조적 이점이 평균 및 최소 실행 시간 기준에서 절대적인 우위를 제공함을 시사한다. 해당 성능 평가에서는 테스트 함수의 인자를 4개로 고정하였기 때문에, 인수 전달 매체의 차이가 성능에 미치는 영향을 명확히 관찰할 수 있다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 실험적 한계 (GPT)&lt;/h2&gt;
&lt;div style=&quot;background-color: #fafafa; color: #333333;&quot; data-text-less=&quot;닫기&quot; data-text-more=&quot;더보기&quot; data-ke-type=&quot;moreLess&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p style=&quot;color: #000000;&quot; data-ke-size=&quot;size18&quot;&gt;1.&amp;nbsp;테스트 함수의 과도한 단순화&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;단일 연산‧단일 경로&lt;/b&gt;: 네 개의 스칼라 값을 더해 반환하는 1 라인 함수는 분기&amp;middot;예외&amp;middot;메모리 접근&amp;middot;API 호출이 전혀 없다. 이 때문에 프로시저 진입&amp;middot;탈출 비용만 반영되고, 실제 호출 경로에서 흔한&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;스택 언와인딩, 예외 처리, TLS 접근, 호출 후 메모리 동기화&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;등의 비용이 배제된다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;현대 코드 특성 미반영&lt;/b&gt;: GUI 이벤트 루프나 서버 핸들러처럼 다단 분기&amp;middot;콜백이 얽힌 상황, 가변 인자&amp;nbsp;(printf류), inlined lambda 등 &amp;ldquo;리얼 월드&amp;rdquo; 함수 호출 패턴을 반영하지 못한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;영향&lt;/b&gt;: 측정값이 지나치게 작아 상대표준편차가 커지고, 호출 규약 차이가 실제 애플리케이션에서 체감되는 정도를 과대‧과소 추정할 위험이 높다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #000000;&quot; data-ke-size=&quot;size18&quot;&gt;2.&amp;nbsp;자료형과 인자 수의 고정&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;데이터 폭 다양성 부족&lt;/b&gt;: double, __m128(SIMD), 포인터 체인, 대형 구조체(pass‑by‑value) 등 타입별 레지스터 분배 정책이 달라지는 시나리오가 배제됐다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;5 개 이상 인자 부재&lt;/b&gt;: x86&amp;nbsp;fastcall&amp;nbsp;(ECX, EDX) 이후, stdcall/cdecl의 stack‑spill 패널티, vectorcall 의 XMM0‑3 확장 이점이&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;인자 5 +&amp;nbsp;부터 급격히 달라지지만&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;실험에는 포함되지 않았다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;영향&lt;/b&gt;: 데이터 타입 및 인자 수가 늘어날수록 레지스터와 스택 간 마찰이 커지는데, 본 실험은 그 비선형적 성능 저하 구간을 포착하지 못한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #000000;&quot; data-ke-size=&quot;size18&quot;&gt;3.&amp;nbsp;측정 환경&amp;middot;타이머 오차 미고려&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;시스템 이벤트&lt;/b&gt;: DPC(Deferred&amp;nbsp;Procedure&amp;nbsp;Call)&amp;middot;SMI(System&amp;nbsp;Management&amp;nbsp;Interrupt)&amp;middot;OS scheduler tick은 QueryPerformanceCounter(QPC) 값에 수 &amp;micro;s~ms 단위 노이즈를 추가한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;전력 관리‧부스트 주파수&lt;/b&gt;: 모바일 CPU의 P‑state 전환은 동일 반복 내에서도 클럭을 변동시켜 결과 분산을 키운다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;미티게이션 부재&lt;/b&gt;: 코어 고정, 하이퍼스레딩 off, HPET/QPC 재확인, IRQL 상승과 같은 보정 절차가 명시되지 않았다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;영향&lt;/b&gt;: 측정값에 비결정적 잡음이 섞여 평균&amp;middot;최소&amp;middot;최대 값 신뢰도가 저하되고, 규약별 미세 차이가 노이즈에 묻힐 위험이 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #000000;&quot; data-ke-size=&quot;size18&quot;&gt;4.&amp;nbsp;단일 하드웨어&amp;middot;컴파일러 버전에 종속&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;CPU 다양성 부재&lt;/b&gt;: Out‑of‑order&amp;nbsp;폭, &amp;mu;op 캐시, &amp;mu;op fusion, 레지스터 리네이밍 버퍼 크기가 다른 AMD Zen4나 Intel Alder Lake&amp;nbsp;P‑core&amp;nbsp;/&amp;nbsp;E‑core 구성에서 결과가 달라질 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;컴파일러 특성 차이&lt;/b&gt;: Clang / ICC는 인라인 힌트, 레지스터 재배치, 호출 규약 자동 선택(Hot/Cold split) 정도가 MSVC와 다르다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;영향&lt;/b&gt;: 특정 uArch + MSVC&amp;nbsp;에만 최적화된 결과라, 크로스‑플랫폼 라이브러리나 다양한 배포 환경을 목표로 하는 프로젝트에는 직결 적용하기 어렵다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #000000;&quot; data-ke-size=&quot;size18&quot;&gt;5.&amp;nbsp;반복 횟수(iterations)&amp;middot;샘플 수(SAMPLES) 제약&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;노트북 TDP&amp;nbsp;제한&lt;/b&gt;: 장시간 high‑frequency loop&amp;nbsp;실행 시 써멀 스로틀로 클럭이 하락해&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;later sample drift&lt;/b&gt;가 발생한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;통계력 부족&lt;/b&gt;: 반복&amp;middot;샘플 수가 적으면 신뢰 구간(95 % CI)이 넓어져 호출 규약 간 차이가 유의미하지 않을 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;캐시 웜‑업 미포착&lt;/b&gt;: 작은 loop&amp;nbsp;count는 L1/L2/L3 캐시 오염&amp;middot;재충전을 적게 발생시켜, DRAM latency 의존도가 큰 실제 workload와 괴리된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #000000;&quot; data-ke-size=&quot;size18&quot;&gt;6.&amp;nbsp;마이크로아키텍처 요인 해석 한계&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;정량 데이터 결여&lt;/b&gt;: x87&amp;rarr;SSE&amp;nbsp;move, store‑forward 비활성(hit-under-miss), &amp;mu;op 분할 등의 하드웨어 카운터를 수집하지 않아 원인 분석이 정성적 추론에 머무른다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;인과 추정 불확실성&lt;/b&gt;: 특정 규약이 빠르다/느리다는 현상은 확인했지만, 파이프라인&amp;nbsp;stalls, &amp;micro;op cache&amp;nbsp;miss 비율, branch mis‑pred 등 구체적 병목 트레이스가 결여되어 재현&amp;middot;최적화 지침으로 활용하기 어렵다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #000000;&quot; data-ke-size=&quot;size18&quot;&gt;7.&amp;nbsp;런타임 안정성(분산) 반영 부족&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;std 제외 or 포함 기준 불명확&lt;/b&gt;: 표준편차를 사용한 지표와 제외 지표가 혼재하며, 어떤 시나리오에서 안정성이 더 중요하다는 계량적 근거가 없다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;실제 서비스 품질 지표와 괴리&lt;/b&gt;: 게임&amp;middot;실시간 스트리밍과 같이 P99 latency를 중시하는 워크로드에서는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;최대값(스파이크)&lt;/b&gt;&amp;nbsp;이 더 중요한데, 본 실험은 평균&amp;middot;최소 위주로 해석했다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;영향&lt;/b&gt;: &amp;ldquo;평균이 빠르다&amp;rdquo;는 결론이 곧 &amp;ldquo;서비스 지연이 안정적이다&amp;rdquo;로 이어지지 않으므로, 운영 품질 관점의 의사결정에는 제한적으로만 활용 가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Project/Toy</category>
      <category>Calling Convention</category>
      <category>x32</category>
      <category>__cdecl</category>
      <category>__fastcall</category>
      <category>__stdcall</category>
      <category>__vectorcall</category>
      <category>함수 호출 규약</category>
      <author>kj0on</author>
      <guid isPermaLink="true">https://kj0on.tistory.com/52</guid>
      <comments>https://kj0on.tistory.com/52#entry52comment</comments>
      <pubDate>Thu, 31 Jul 2025 16:44:08 +0900</pubDate>
    </item>
    <item>
      <title>[Definition] 라이브러리 (Library)</title>
      <link>https://kj0on.tistory.com/49</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;0. 유래&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라이브러리는 여러 프로그램에서 공통으로 재사용하려고 묶어 둔 코드의 집합이다. 초창기엔 물리 미디어(천공 카드, 자기선, 펀치 테이프)에 저장된 재사용 가능한 루틴의 모음이었고, 오늘날엔 정적/동적 바이너리, 패키지, 모듈, 프레임워크, 표준 라이브러리 등으로 발전했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;0-1. 타임라인&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;0-1-1. 1837 ~ 1889: 해석 기관&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;Each formula would require its own set of cards, and by degrees the engine would have a library of its own.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;찰스 배비지의 해석기관(The Analytical Engine)의 설계는 연산(operations) 카드와 숫자(cards of numbers)를 분리해 조합하는 방식을 전제했고, 이는 재사용 가능한 절차 모듈의 축적이라는 아이디어로 이어졌다. 아들인 H. P. Babbage는 &quot;각 공식(formula)은 자체 카드 묶음이 필요하며, 기관은 자체적인 도서관(library)을 갖게 된다&quot;고 논문에 기술했고, 이것이 라이브러리라는 개념의 가장 이른 표현 중 하나가 되었다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;0-1-2. 1947: IAS 서브루틴 라이브러리&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;골드스타인과 폰 노이만은 IAS 컴퓨터에서 자주 쓰이는 서브루틴을 자기선, 자기테이프에 저장해 와이어 도서관처럼 재사용하자는 구상을 내놓았다. 이는 오늘날의 바이너리 라이브러리처럼, 외부에 저장된 코드 집합을 필요할 때 불러오는 발상과 유사하다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;0-1-3. 1949 ~ 1951: EDSAC 펀치테이프 서브루틴 캐비닛&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;EDSAC에서는 서브루틴을 펀치테이프로 제작해 철제 캐비닛에 보관하고, 필요한 루틴을 복사해 프로그램에 붙이는 방식을 사용했다. 1951년 윌크스 휠러 길(Wilkes Wheeler Gill)의 교과서에서 이 방식이 체계적으로 정리되며, 라이브러리 활용이 교육의 일부로 자리잡았다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;0-1-4. 1959 ~ 1965: COBOL 라이브러리와 JOVIAL COMPOOL&amp;nbsp;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;COBOL은 COPY 문으로 공통 정의부를 재사용하는 초기 소스 라이브러리 문화를 만들었고, 군용 언어 JOVIAL은 COMPOOL이라는 표준 형식으로 모듈 간 공유 데이터를 관리했다. 이는 코드와 인터페이스를 분리해 배포하는 관례를 정착시켰다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;0-1-5. 1958 ~ 1990: FORTRAN의 발전&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;FORTRAN II부터 독립 컴파일과 링커 결합이 일반화되며 목적코드 라이브러리가 주류가 되었고, FORTRAN 90에서는 모듈과 명시적 인터페이스를 도입해 타입 검증과 안전성을 높였다. 이는 현대 빌드 체계의 기반을 마련했다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;0-1-6. 1964 ~ 1970년대: IBM System/360의 라이브러리 체계&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;System/360은&amp;nbsp;PDS&amp;middot;MACLIB&amp;middot;로드모듈&amp;nbsp;형태로&amp;nbsp;소스,&amp;nbsp;매크로,&amp;nbsp;실행&amp;nbsp;파일을&amp;nbsp;관리하고,&amp;nbsp;링키지&amp;nbsp;에디터로&amp;nbsp;재배치와&amp;nbsp;심볼&amp;nbsp;해소를&amp;nbsp;표준화했다.&amp;nbsp;이는&amp;nbsp;기업&amp;nbsp;환경에서의&amp;nbsp;대규모&amp;nbsp;라이브러리&amp;nbsp;관리&amp;nbsp;모델이&amp;nbsp;되었다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;0-1-7. 1967: Simula&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Simula 67은 클래스 개념을 도입해 객체를 재사용 가능한 라이브러리 형태로 축적할 수 있게 했고, 이는 Smalltalk&amp;middot;C++로 이어지며 루틴 집합에서 타입과 행위의 집합으로 라이브러리 개념을 확장했다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;0-1-8. 1969 ~ 1990년대: 동적 링크의 확산&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Multics는 재진입 가능한 세그먼트와 런타임 심볼 결합으로 동적 링크를 실용화했고, UNIX는 ELF 공유 라이브러리(.so), Windows는 DLL로 확산시켰다. 이를 통해 메모리 절약과 런타임 결합이 가능해졌다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;0-1-9. 1988 ~ 2001: 프레임워크 배포 모델&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NeXTSTEP과 macOS는 라이브러리, 헤더, 리소스를 하나의 번들(framework)로 묶어 배포하는 방식을 도입했다. 이는 단순한 코드 집합을 넘어 UI, 리소스를 포함한 제품화된 라이브러리 개념으로 발전했다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;0-1-10. 1994 ~ 1998: 표준 라이브러리의 등장&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C++ STL과 Java SE 표준 라이브러리가 제정되며, 언어 표준과 함께 방대한 기능 집합을 제공하는 구조가 정착됐다. 이를 통해 개발자는 도메인 코드에 집중하고, 공통 기능은 표준 라이브러리에 의존할 수 있게 되었다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;0-1-11. 1992 ~ 2005: 언어별 중앙 저장소 출현&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CTAN(TeX), CPAN(Perl), CRAN(R), Maven Central(Java) 등 공개 저장소가 등장해 라이브러리 검색, 의존성 관리, 배포가 인터넷 기반에서 이루어졌다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;0-1-12. 현재&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PyPI(Python), npm(JavaScript), NuGet(.NET), Cargo(Rust) 등 언어별 공식 패키지 관리자와 중앙 저장소는 의존성 해소, 버전 관리, 빌드 재현성, 보안 검증을 통합적으로 지원하며, 이를 통해 라이브러리 배포, 관리가 표준화되었다. 동시에 libc, glibc, .NET BCL, Python 표준 라이브러리 등 언어&amp;middot;플랫폼별 표준 라이브러리가 최소 기능 집합을 안정적으로 제공해, 개발자가 핵심 로직 구현에 집중할 수 있는 기반을 마련하고 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;1. 정의&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Library.jpg&quot; data-origin-width=&quot;3151&quot; data-origin-height=&quot;1236&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cmfmfF/btsPNjaop0h/46g5RwAUwwDksaq0gFbQ8K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cmfmfF/btsPNjaop0h/46g5RwAUwwDksaq0gFbQ8K/img.jpg&quot; data-alt=&quot;[이미지1] Library&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cmfmfF/btsPNjaop0h/46g5RwAUwwDksaq0gFbQ8K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcmfmfF%2FbtsPNjaop0h%2F46g5RwAUwwDksaq0gFbQ8K%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3151&quot; height=&quot;1236&quot; data-filename=&quot;Library.jpg&quot; data-origin-width=&quot;3151&quot; data-origin-height=&quot;1236&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지1] Library&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;라이브러리(Library)는 소프트웨어 개발 시 활용되는 코드와 데이터 자원의 모음을 가리키며, 여러 프로그램에서 공통으로 사용될 수 있는 함수, 클래스 등의 실행 코드나 소스 코드를 포함한다. 특정 기능을 구현한 코드를 미리 묶어놓은 재사용 가능한 모듈로서, 프로그램에서 필요할 때 가져다가 쓸 수 있도록 한 것이다. 하나의 라이브러리를 여러 응용 프로그램이나 다른 라이브러리가 참조하여 사용함으로써, 개발자는 해당 기능을 일일이 새로 작성하지 않아도 된다. 라이브러리를 사용하는 프로그래머는 그 내부 구현을 알 필요 없이 제공되는 인터페이스(API)만으로 기능을 호출할 수 있고, 이는 복잡한 시스템 호출이나 알고리즘도 쉽게 활용할 수 있게 한다. 이는 구현 언어나 OS에 상관없이 공통으로 쓰이는 소프트웨어 구성 개념이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;321&quot; data-origin-height=&quot;159&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baC0J0/btsPMNcj7bo/DJqvUqzRQaJ53rMHAskbnk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baC0J0/btsPMNcj7bo/DJqvUqzRQaJ53rMHAskbnk/img.png&quot; data-alt=&quot;[이미지2] printf&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baC0J0/btsPMNcj7bo/DJqvUqzRQaJ53rMHAskbnk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaC0J0%2FbtsPMNcj7bo%2FDJqvUqzRQaJ53rMHAskbnk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;321&quot; height=&quot;159&quot; data-origin-width=&quot;321&quot; data-origin-height=&quot;159&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지2] printf&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;printf는 C 표준 라이브러리에 포함된 출력 함수로, 문자열을 서식 지정과 함께 표준 출력에 보내는 역할을 한다. C 프로그램에서 #include &amp;lt;stdio.h&amp;gt;를 선언하면, 컴파일러는 해당 헤더 파일을 통해 printf의 함수 원형과 필요한 매크로 정의를 알게 된다. 실제 printf의 내부 구현 코드는 소스 파일에 포함되어 있지 않고, 컴파일 후 링크 단계에서 C 표준 라이브러리의 바이너리에 있는 printf 구현이 결합된다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;761&quot; data-origin-height=&quot;384&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cekYHy/btsPLcjWRZ8/KuFrWxREAcLNTEM5qjv98K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cekYHy/btsPLcjWRZ8/KuFrWxREAcLNTEM5qjv98K/img.png&quot; data-alt=&quot;[이미지3] __stdio_common_vfprintf&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cekYHy/btsPLcjWRZ8/KuFrWxREAcLNTEM5qjv98K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcekYHy%2FbtsPLcjWRZ8%2FKuFrWxREAcLNTEM5qjv98K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;761&quot; height=&quot;384&quot; data-origin-width=&quot;761&quot; data-origin-height=&quot;384&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지3] __stdio_common_vfprintf&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;개발자는 printf 내부에서 버퍼처리 방식과 시스템 호출 등 어떻게 동작하는지를 몰라도, 제공되는 인터페이스(API)만 알고 사용하면 된다. 이를 통해 복잡한 입출력 제어 코드를 매번 작성할 필요 없이, 라이브러리에 이미 구현된 검증된 함수를 재사용할 수 있는 것이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1287&quot; data-origin-height=&quot;738&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cGBlHx/btsPOEeoOsd/ykxKXysHHRz8KwxoshUwK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cGBlHx/btsPOEeoOsd/ykxKXysHHRz8KwxoshUwK0/img.png&quot; data-alt=&quot;[이미지4] Xrefs graph from test&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cGBlHx/btsPOEeoOsd/ykxKXysHHRz8KwxoshUwK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcGBlHx%2FbtsPOEeoOsd%2FykxKXysHHRz8KwxoshUwK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1287&quot; height=&quot;738&quot; data-origin-width=&quot;1287&quot; data-origin-height=&quot;738&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지4] Xrefs graph from test&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;main 함수에서 test_fun을 호출하는 경우, IDA에서 &quot;Xrefs graph from...&quot; 메뉴를 선택하면 호출 관계를 시각적으로 보여주는 그래프를 생성할 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1900&quot; data-origin-height=&quot;889&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bag0SH/btsPOl61Mwv/EtxWCfDymSJwG10VfjVCcK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bag0SH/btsPOl61Mwv/EtxWCfDymSJwG10VfjVCcK/img.png&quot; data-alt=&quot;[이미지5] Xrefs graph from&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bag0SH/btsPOl61Mwv/EtxWCfDymSJwG10VfjVCcK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbag0SH%2FbtsPOl61Mwv%2FEtxWCfDymSJwG10VfjVCcK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1900&quot; height=&quot;889&quot; data-origin-width=&quot;1900&quot; data-origin-height=&quot;889&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지5] Xrefs graph from&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;위 이미지는 [이미지4]와 동일하게 &quot;Xrefs graph from...&quot; 메뉴를 선택해서 나타낸 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;printf의&lt;/span&gt; 그래프이다. printf 호출이 실제로 내부에서 거치는 함수 호출 관계를 그래프로 나타낸 것으로, 단일 API 호출이 얼마나 복잡한 내부 구조와 많은 하위 함수 호출로 이루어져 있는지를 잘 보여준다. 예시로 표시된 __stdio_common_vfprintf 함수는 printf 계열 함수의 핵심 처리부로, 서식 문자열 해석, 인자 변환, 버퍼 관리, 로케일 처리, 그리고 최종적으로 운영체제의 시스템 호출을 거쳐 출력 장치에 데이터를 전달한다. 이처럼 겉보기에는 간단한 라이브러리 함수 호출 하나가 내부적으로는 수백, 수천개의 경로와 함수 호출로 연결되어 있다. 위와 같은 복잡한 기능을 printf를 사용할 때마다 매번 직접 구현하는 것은 현실적으로 불가능하다. 이러한 과정을 이미 구현해 둔 표준 라이브러리를 사용하면, 복잡한 내부 동작을 직접 구현하지 않더라도 단지 printf(); 한 줄로 동일한 기능을 손쉽게 수행할 수 있다. 이는 라이브러리가 제공하는 추상화 덕분에 가능한 것으로, 개발자는 내부 구조를 알 필요 없이 간단한 API 호출만으로 복잡한 기능을 재사용할 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 84px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 42.3255%; height: 21px;&quot;&gt;라이브러리&lt;/td&gt;
&lt;td style=&quot;width: 57.6745%; height: 21px;&quot;&gt;특징&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 42.3255%; height: 21px;&quot;&gt;정적 라이브러리 (Static&amp;nbsp;Library)&lt;/td&gt;
&lt;td style=&quot;width: 57.6745%; height: 21px;&quot;&gt;컴파일/링크&amp;nbsp;시&amp;nbsp;실행&amp;nbsp;파일에&amp;nbsp;붙여&amp;nbsp;넣는&amp;nbsp;방식.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 42.3255%; height: 21px;&quot;&gt;동적/공유 라이브러리 (Shared/Dynamic&amp;nbsp;Library)&lt;/td&gt;
&lt;td style=&quot;width: 57.6745%; height: 21px;&quot;&gt;실행할&amp;nbsp;때&amp;nbsp;따로&amp;nbsp;로드해서&amp;nbsp;쓰는&amp;nbsp;방식.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 42.3255%; height: 21px;&quot;&gt;헤더 온리 (Headers-only)&lt;/td&gt;
&lt;td style=&quot;width: 57.6745%; height: 21px;&quot;&gt;C/C++에서 템플릿, 인라인로만 구성해 헤더 포함만으로 쓰는 형태.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라이브러리는 구현, 배포 방식에 따라 정적 라이브러리(Static Library), 동적/공유 라이브러리(Shared/Dynamic Library),&amp;nbsp;&amp;nbsp;헤더 온리(Headers-only)로 구분된다. 정적 라이브러리는 컴파일 시 목적 코드에 병합되어 실행 파일에 포함되므로 배포 시 별도 라이브러리가 필요 없으며, 동적/공유 라이브러리는 실행 시 로더가 외부 파일을 로드해 메모리를 공유하므로 파일 크기를 줄이고 업데이트가 용이하다. 헤더 온리는 구현이 전부 헤더 파일에 포함되어 있어 별도의 링크 과정 없이 소스 코드에 직접 포함해 사용할 수 있는 형태다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 라이선스&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;978&quot; data-origin-height=&quot;530&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/X5hKb/btsPMIhmWyD/6YrKmkkcKc2U1O0eWaTEqk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/X5hKb/btsPMIhmWyD/6YrKmkkcKc2U1O0eWaTEqk/img.png&quot; data-alt=&quot;[이미지6] 라이선스 비교표 (https://olis.or.kr/license/compareGuide.do)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/X5hKb/btsPMIhmWyD/6YrKmkkcKc2U1O0eWaTEqk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FX5hKb%2FbtsPMIhmWyD%2F6YrKmkkcKc2U1O0eWaTEqk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;978&quot; height=&quot;530&quot; data-origin-width=&quot;978&quot; data-origin-height=&quot;530&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지6] 라이선스 비교표 (https://olis.or.kr/license/compareGuide.do)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라이브러리를 사용할 때는 해당 라이브러리가 채택한 라이선스를 확인하고 그 조건을 준수할 수 있는지 검토해야 한다. 실제로 오픈소스 라이선스에는 매우 다양한 유형이 있으며, 자유로운 사용을 보장하는 관대한 라이선스부터 소스 코드 공개를 의무화하거나 상업적 이용을 제한하는 엄격한 라이선스까지 존재한다. 이러한 조건을 무시하고 라이브러리를 사용할 경우, 라이선스 위반으로 법적 제재를 받을 수 있으며, 특히 상업적 제품의 경우 소스코드를 공개해야 하거나 손해배상 책임을 질 수 있는 상황이 발생할 수 있다. 따라서 라이브러리를 사용하기 전에는 해당 라이선스의 조건을 파악하여 사용하는 것이 바람직하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2-1. 주요 라이선스&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2-1-1. 퍼블릭 도메인 라이선스&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;퍼블릭 도메인 라이선스는 저작권 등 법적 권리를 포기하거나 혹은 이에 준하는 최소한의 조건만 두어 누구나 해당 저작물을 자유롭게 사용&amp;middot;변경&amp;middot;재배포할 수 있도록 하는 방식이다. 사실상 제약이 거의 없어서 상업적&amp;middot;비상업적 용도 모두 자유롭다. 다만, CC0 라이선스는 저작권은 포기하지만 특허 권리는 허락하거나 인정하지 않는다고 명시한다. 즉, 이 코드는 아무 제한 없이 써도 되지만, 특허 문제까지는 책임지지 않는다는 개념이다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 90px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 7.32558%; height: 21px;&quot;&gt;라이선스&lt;/td&gt;
&lt;td style=&quot;width: 40.2711%; height: 21px;&quot;&gt;출처&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 35px;&quot;&gt;
&lt;td style=&quot;width: 7.32558%; height: 35px;&quot;&gt;CC0-1.0&lt;/td&gt;
&lt;td style=&quot;width: 40.2711%; height: 35px;&quot;&gt;&lt;a href=&quot;https://creativecommons.org/publicdomain/zero/1.0/legalcode.en&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://creativecommons.org/publicdomain/zero/1.0/legalcode.en&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 7.32558%; height: 17px;&quot;&gt;Unlicense&lt;/td&gt;
&lt;td style=&quot;width: 40.2711%; height: 17px;&quot;&gt;&lt;a href=&quot;https://unlicense.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://unlicense.org/&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 7.32558%; height: 17px;&quot;&gt;0BSD&lt;/td&gt;
&lt;td style=&quot;width: 40.2711%; height: 17px;&quot;&gt;&lt;a href=&quot;https://spdx.org/licenses/0BSD.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://spdx.org/licenses/0BSD.html&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2-1-2. 허용형 라이선스&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;허용형 라이선스는 소스 코드 원본이든, 컴파일된 실행 파일이든 거의 제한 없이 사용, 수정, 재배포할 수 있게 해준다. 사용자가 지켜야 하는 의무는 두 가지로, 첫째는 원래 저작권 표시와 라이선스 문구를 그대로 남겨두는 것, 둘째는 사용하다가&amp;nbsp;오류가&amp;nbsp;발생하거나,&amp;nbsp;데이터가&amp;nbsp;손실되거나,&amp;nbsp;시스템이&amp;nbsp;손상되는&amp;nbsp;등의&amp;nbsp;문제가&amp;nbsp;생겨도&amp;nbsp;제작자는&amp;nbsp;법적&amp;nbsp;책임을&amp;nbsp;지지&amp;nbsp;않는다는 &quot;보증 부인&quot; 문구를 유지하는 것이다. 특허와 관련해서는 MIT, BSD 라이선스는 별도 언급이 없지만, Apache 2.0 라이선스는 특허 사용 권리를 명확히 허용하며, 특허 분쟁이 발생하면 그 권리를 취소하는 조항까지 포함한다. 즉, 출처만 남기고, 문제가 생기면 책임은 사용자에게 있다는 조건으로 거의 모든 용도에 자유롭게 쓸 수 있는 라이선스다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 115px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 12.8682%; height: 21px;&quot;&gt;라이선스&lt;/td&gt;
&lt;td style=&quot;width: 42.4031%; height: 21px;&quot;&gt;출처&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 43px;&quot;&gt;
&lt;td style=&quot;width: 12.8682%; height: 43px;&quot;&gt;MIT&amp;nbsp;License&lt;/td&gt;
&lt;td style=&quot;width: 42.4031%; height: 43px;&quot;&gt;&lt;a href=&quot;https://opensource.org/license/mit&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://opensource.org/license/mit&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 12.8682%; height: 17px;&quot;&gt;3-Clause&amp;nbsp;BSD&amp;nbsp;License&lt;/td&gt;
&lt;td style=&quot;width: 42.4031%; height: 17px;&quot;&gt;&lt;a href=&quot;https://opensource.org/license/bsd-3-clause&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://opensource.org/license/bsd-3-clause&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 12.8682%; height: 17px;&quot;&gt;Apache License 2.0&lt;/td&gt;
&lt;td style=&quot;width: 42.4031%; height: 17px;&quot;&gt;&lt;a href=&quot;https://www.apache.org/licenses/LICENSE-2.0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.apache.org/licenses/LICENSE-2.0&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 12.8682%; height: 17px;&quot;&gt;Boost-1.0&lt;/td&gt;
&lt;td style=&quot;width: 42.4031%; height: 17px;&quot;&gt;&lt;a href=&quot;https://www.boost.org/doc/user-guide/bsl.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.boost.org/doc/user-guide/bsl.html&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 12.8682%;&quot;&gt;zlib&lt;/td&gt;
&lt;td style=&quot;width: 42.4031%;&quot;&gt;&lt;a href=&quot;https://zlib.net/zlib_license.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://zlib.net/zlib_license.html&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2-1-3. 약한 카피레프트형 라이선스&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;약한 카피레프트형 라이선스는 라이브러리나 모듈 자체를 수정했을 경우에는 그 변경 내용을 공개해야 하지만, 해당 라이브러리를 그대로 가져다 쓰면서 별도의 파일로 만든 애플리케이션에 대해서는 일부 조건을 지키면 다른 라이선스를 적용할 수 있도록 허용한다. 대표적으로 LGPL, MPL, EPL, CDDL 등이 이에 해당하며, 주로 오픈소스 라이브러리를 상용 프로그램과 함께 사용할 수 있도록 만든 규칙이다. 즉, 라이브러리를 수정했다면 그 부분은 공개해야 하지만, 그냥 불러다 쓰는 프로그램은 자유롭게 라이선스를 정해도 된다는 방식이다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 6.86045%;&quot;&gt;라이선스&lt;/td&gt;
&lt;td style=&quot;width: 40.5038%;&quot;&gt;출처&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 6.86045%;&quot;&gt;LGPL-2.1&lt;/td&gt;
&lt;td style=&quot;width: 40.5038%;&quot;&gt;&lt;a href=&quot;https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 6.86045%;&quot;&gt;LGPL-3.0&lt;/td&gt;
&lt;td style=&quot;width: 40.5038%;&quot;&gt;&lt;a href=&quot;https://www.gnu.org/licenses/lgpl-3.0.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.gnu.org/licenses/lgpl-3.0.html&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 6.86045%;&quot;&gt;MPL-2.0&lt;/td&gt;
&lt;td style=&quot;width: 40.5038%;&quot;&gt;&lt;a href=&quot;https://www.mozilla.org/en-US/MPL/2.0/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.mozilla.org/en-US/MPL/2.0/&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 6.86045%;&quot;&gt;EPL-2.0&lt;/td&gt;
&lt;td style=&quot;width: 40.5038%;&quot;&gt;&lt;a href=&quot;https://www.eclipse.org/legal/epl-2.0/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.eclipse.org/legal/epl-2.0/&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 6.86045%;&quot;&gt;CDDL-1.0&lt;/td&gt;
&lt;td style=&quot;width: 40.5038%;&quot;&gt;&lt;a href=&quot;https://opensource.org/license/cddl-1-0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://opensource.org/license/cddl-1-0&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2-1-4. 강한 카피레프트 라이선스&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;강한 카피레프트 라이선스는 해당 소프트웨어를 수정하거나 다른 코드와 결합해 만든 파생물 전체에 원래와 동일하거나 호환되는 라이선스를 적용하도록 요구하는 방식이다. 대표적으로 GPL 계열이 이에 해당하며, 이를 사용한 소프트웨어는 배포 시 전체 소스 코드를 공개해야 한다. 특히 AGPL은 여기에 더해, 프로그램을 네트워크 서비스 형태(웹 서비스 등)로만 제공하더라도 소스 코드를 사용자에게 제공해야 한다. 즉, 이 코드를 쓰면, 완성된 프로그램 전체를 똑같이 오픈소스로 공개해야 한다는 규칙이다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 6.86046%;&quot;&gt;라이선스&lt;/td&gt;
&lt;td style=&quot;width: 39.6899%;&quot;&gt;출처&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 6.86046%;&quot;&gt;GPL-3.0&lt;/td&gt;
&lt;td style=&quot;width: 39.6899%;&quot;&gt;&lt;a href=&quot;https://www.gnu.org/licenses/gpl-3.0.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.gnu.org/licenses/gpl-3.0.html&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 6.86046%;&quot;&gt;AGPL-3.0&lt;/td&gt;
&lt;td style=&quot;width: 39.6899%;&quot;&gt;&lt;a href=&quot;https://www.gnu.org/licenses/agpl-3.0.en.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.gnu.org/licenses/agpl-3.0.en.html&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;3. C의 라이브러리&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;C.png&quot; data-origin-width=&quot;570&quot; data-origin-height=&quot;630&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d63Zt0/btsPJffcVgQ/v03GtPsc58RaMzo9ZfQGD1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d63Zt0/btsPJffcVgQ/v03GtPsc58RaMzo9ZfQGD1/img.png&quot; data-alt=&quot;[이미지7] C&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d63Zt0/btsPJffcVgQ/v03GtPsc58RaMzo9ZfQGD1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd63Zt0%2FbtsPJffcVgQ%2Fv03GtPsc58RaMzo9ZfQGD1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;200&quot; height=&quot;221&quot; data-filename=&quot;C.png&quot; data-origin-width=&quot;570&quot; data-origin-height=&quot;630&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지7] C&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;C 언어에서의 라이브러리는 특정 기능을 수행하는 함수들을 미리 구현하고 컴파일한 오브젝트 코드의 집합으로, 개발자가 동일한 기능을 매번 새로 작성하지 않고 재사용할 수 있도록 설계된 코드 자원이다. 절차형 언어인 C에서는 이러한 라이브러리가 주로 함수 형태로 구성되며, 표준 입출력, 문자열 처리, 수학 연산, 메모리 관리 등 다양한 기능을 포함한다. 프로그램 작성 시 개발자는 필요한 라이브러리를 링크하여 해당 함수들을 호출할 수 있으며, 이 과정에서 실제 함수 구현부는 컴파일된 바이너리에서 가져와 실행된다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;3-1. 표준 라이브러리&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;C의 표준 라이브러리 는 ISO/IEC 9899가 규정한 Clause 7 Library에 해당하며, 표준 헤더 파일을 통해 제공되는 함수, 매크로, 형식, 객체의 집합으로 정의된다. 각 기능에 접근하기 위해 대응되는 헤더 파일을 통해 인터페이스를 제공한다. 이 라이브러리는 저수준에서 빈번히 사용되는 기능을 중심으로 구성되어 있으며, 전체 규모가 작고 범위가 제한적이다. 현대의 많은 언어가 표준 라이브러리에서 다양한 고수준 기능을 제공하는 것과 달리, C 표준 라이브러리는 이식성과 최소화에 초점을 맞춘 미니멀리즘 설계를 따른다. 이로 인해 새로운 플랫폼으로의 포팅이 용이해졌지만, 표준에 없는 기능을 구현하려면 운영체제별 API나 서드파티 라이브러리에 의존해야 한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;3-2. 표준 패키지 관리자&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;791&quot; data-origin-height=&quot;426&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b2fMe4/btsPO3ziowR/lHCmOShZkVvsKMjQIHItL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b2fMe4/btsPO3ziowR/lHCmOShZkVvsKMjQIHItL0/img.png&quot; data-alt=&quot;[이미지8] vcpkg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b2fMe4/btsPO3ziowR/lHCmOShZkVvsKMjQIHItL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb2fMe4%2FbtsPO3ziowR%2FlHCmOShZkVvsKMjQIHItL0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;791&quot; height=&quot;426&quot; data-origin-width=&quot;791&quot; data-origin-height=&quot;426&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지8] vcpkg&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1493&quot; data-origin-height=&quot;396&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bOAXr3/btsPOpWPvVh/AFvUfwKrX8M0dfgPxLVN21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bOAXr3/btsPOpWPvVh/AFvUfwKrX8M0dfgPxLVN21/img.png&quot; data-alt=&quot;[이미지9] conan&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bOAXr3/btsPOpWPvVh/AFvUfwKrX8M0dfgPxLVN21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbOAXr3%2FbtsPOpWPvVh%2FAFvUfwKrX8M0dfgPxLVN21%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1493&quot; height=&quot;396&quot; data-origin-width=&quot;1493&quot; data-origin-height=&quot;396&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지9] conan&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;C 언어는 역사적으로 표준화된 패키지 관리자가 존재하지 않았기 때문에, 라이브러리 배포와 의존성 관리는 개발자가 직접 수행해야 했다. 필요한 라이브러리의 소스 코드를 받아 직접 컴파일하거나, 운영체제의 패키지 관리자를 통해 미리 빌드된 패키지를 설치하는 방식이 일반적이었다. 그러나 C/C++ 전용 패키지 관리 도구가 등장하면서 이 과정이 점차 자동화되고 있다. 대표적으로 Microsoft의 vcpkg는 2천 개 이상의 오픈소스 라이브러리를 지원하며 Windows, Linux, macOS에서 동일한 방식으로 설치 및 관리를 할 수 있고, Conan은 중앙 서버 기반의 패키지 공유 생태계를 제공하여 다양한 빌드 설정과 플랫폼을 지원한다. 이 밖에도 HPC(고성능 컴퓨팅) 환경에 특화된 Spack 등이 존재하며, 이러한 도구들은 빌드 스크립트 작성, 의존성 해결, 버전 관리 등을 통합적으로 제공함으로써 C/C++ 라이브러리 관리의 편의성을 크게 향상시키고 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-3. 라이브러리&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 28.2558%;&quot;&gt;카테고리&lt;/td&gt;
&lt;td style=&quot;width: 71.7442%;&quot;&gt;라이브러리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 28.2558%;&quot;&gt;표준&amp;middot;런타임&lt;/td&gt;
&lt;td style=&quot;width: 71.7442%;&quot;&gt;libc&amp;nbsp;(ISO&amp;nbsp;C),&amp;nbsp;glibc,&amp;nbsp;musl,&amp;nbsp;uClibc-ng,&amp;nbsp;newlib,&amp;nbsp;dietlibc,&amp;nbsp;Bionic,&amp;nbsp;MSVCRT,&amp;nbsp;UCRT,&amp;nbsp;Apple&amp;nbsp;libSystem,&amp;nbsp;OpenBSD&amp;nbsp;libc,&amp;nbsp;FreeBSD&amp;nbsp;libc,&amp;nbsp;NetBSD&amp;nbsp;libc,&amp;nbsp;MinGW-w64&amp;nbsp;CRT,&amp;nbsp;CloudABI-libc,&amp;nbsp;WASI-libc,&amp;nbsp;Cosmopolitan&amp;nbsp;libc&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 28.2558%;&quot;&gt;시스템 인터페이스&lt;span style=&quot;background-color: #efefef; color: #333333; text-align: start;&quot;&gt;&amp;middot;&lt;/span&gt;OS 서비스&lt;/td&gt;
&lt;td style=&quot;width: 71.7442%;&quot;&gt;libsystemd,&amp;nbsp;libudev,&amp;nbsp;libselinux,&amp;nbsp;libsepol,&amp;nbsp;libseccomp,&amp;nbsp;libcap,&amp;nbsp;libacl,&amp;nbsp;libattr,&amp;nbsp;libkmod,&amp;nbsp;libpam,&amp;nbsp;libusb,&amp;nbsp;libusb-1.0,&amp;nbsp;libftdi,&amp;nbsp;hidapi,&amp;nbsp;libdrm,&amp;nbsp;libevdev,&amp;nbsp;libinput,&amp;nbsp;libpci,&amp;nbsp;libpciaccess,&amp;nbsp;libspdk,&amp;nbsp;libtracefs,&amp;nbsp;libbpf,&amp;nbsp;libdwarf,&amp;nbsp;libunwind,&amp;nbsp;libvmi,&amp;nbsp;libssh,&amp;nbsp;libssh2,&amp;nbsp;libpty,&amp;nbsp;libnfs,&amp;nbsp;libfuse3,&amp;nbsp;libexplain&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 28.2558%;&quot;&gt;스레딩&amp;middot;동시성&amp;middot;이벤트&lt;/td&gt;
&lt;td style=&quot;width: 71.7442%;&quot;&gt;pthreads,&amp;nbsp;tinycthread,&amp;nbsp;libdispatch&amp;nbsp;(GCD),&amp;nbsp;OpenMP&amp;nbsp;runtimes&amp;nbsp;(libgomp,&amp;nbsp;iomp),&amp;nbsp;Intel&amp;nbsp;TBB,&amp;nbsp;liburcu,&amp;nbsp;jemalloc&amp;nbsp;(thd-cache),&amp;nbsp;mimalloc,&amp;nbsp;tcmalloc,&amp;nbsp;rpmalloc,&amp;nbsp;hoard,&amp;nbsp;libevent,&amp;nbsp;libev,&amp;nbsp;libuv,&amp;nbsp;libtask,&amp;nbsp;libco,&amp;nbsp;libfiber,&amp;nbsp;libmill,&amp;nbsp;libdill,&amp;nbsp;libasyncns&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 28.2558%;&quot;&gt;네트워킹&amp;middot;통신&amp;nbsp;스택&lt;/td&gt;
&lt;td style=&quot;width: 71.7442%;&quot;&gt;libcurl,&amp;nbsp;wget2-lib,&amp;nbsp;c-ares,&amp;nbsp;libwebsockets,&amp;nbsp;libnghttp2,&amp;nbsp;ngtcp2,&amp;nbsp;quiche-c,&amp;nbsp;libhttpserver,&amp;nbsp;civetweb,&amp;nbsp;mongoose-c,&amp;nbsp;h2o,&amp;nbsp;libcoap,&amp;nbsp;libmqtt-paho,&amp;nbsp;mosquitto&amp;nbsp;client,&amp;nbsp;nanomsg,&amp;nbsp;nng,&amp;nbsp;ZeroMQ&amp;nbsp;(libzmq),&amp;nbsp;libnanomsg-nngcompat,&amp;nbsp;libnats,&amp;nbsp;libevhtp,&amp;nbsp;libuhttpd,&amp;nbsp;libstrophe&amp;nbsp;(XMPP),&amp;nbsp;libusu,&amp;nbsp;libpcap,&amp;nbsp;libnet,&amp;nbsp;libdnet,&amp;nbsp;gnutls,&amp;nbsp;OpenSSL,&amp;nbsp;LibreSSL,&amp;nbsp;BoringSSL,&amp;nbsp;mbedTLS,&amp;nbsp;wolfSSL,&amp;nbsp;BearSSL,&amp;nbsp;s2n-tls&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 28.2558%;&quot;&gt;데이터&amp;nbsp;직렬화&amp;middot;파일&amp;nbsp;형식&lt;/td&gt;
&lt;td style=&quot;width: 71.7442%;&quot;&gt;protobuf-c,&amp;nbsp;nanopb,&amp;nbsp;flatbuffers-c,&amp;nbsp;Cap&amp;rsquo;n&amp;nbsp;Proto&amp;nbsp;(C&amp;nbsp;port),&amp;nbsp;Thrift&amp;nbsp;(C&amp;nbsp;binding),&amp;nbsp;Avro-c,&amp;nbsp;msgpack-c,&amp;nbsp;tinyCBOR,&amp;nbsp;libcbor,&amp;nbsp;UBJSON-c,&amp;nbsp;RapidJSON-C&amp;nbsp;wrapper,&amp;nbsp;cJSON,&amp;nbsp;parson,&amp;nbsp;json-c,&amp;nbsp;jsmn,&amp;nbsp;yajl,&amp;nbsp;jansson,&amp;nbsp;tomlc99,&amp;nbsp;libtoml,&amp;nbsp;inih,&amp;nbsp;libconfig,&amp;nbsp;libconfuse,&amp;nbsp;libinih,&amp;nbsp;libcsv,&amp;nbsp;libxls,&amp;nbsp;libxlsxwriter,&amp;nbsp;libbson,&amp;nbsp;libxml2,&amp;nbsp;expat,&amp;nbsp;libexpatpp,&amp;nbsp;libfastxml,&amp;nbsp;libyaml,&amp;nbsp;libsyck,&amp;nbsp;libyajl,&amp;nbsp;libtomlplusplus&amp;nbsp;C-wrapper,&amp;nbsp;libplist,&amp;nbsp;libpdfium&amp;nbsp;C-api,&amp;nbsp;libzip,&amp;nbsp;libtar,&amp;nbsp;libarchive&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 28.2558%;&quot;&gt;데이터베이스&amp;middot;스토리지&lt;/td&gt;
&lt;td style=&quot;width: 71.7442%;&quot;&gt;SQLite3,&amp;nbsp;libpq&amp;nbsp;(PostgreSQL),&amp;nbsp;MySQL&amp;nbsp;Connector/C,&amp;nbsp;MariaDB&amp;nbsp;Connector/C,&amp;nbsp;ODBC&amp;nbsp;(unixODBC),&amp;nbsp;Firebird&amp;nbsp;ibase&amp;nbsp;client,&amp;nbsp;Oracle&amp;nbsp;ODPI-C,&amp;nbsp;Berkeley&amp;nbsp;DB,&amp;nbsp;GDBM,&amp;nbsp;LMDB,&amp;nbsp;Lightning&amp;nbsp;DB,&amp;nbsp;LevelDB-C,&amp;nbsp;RocksDB-C,&amp;nbsp;DuckDB-C,&amp;nbsp;UnQLite,&amp;nbsp;Tokyocabinet,&amp;nbsp;Kyotocabinet,&amp;nbsp;Redis&amp;nbsp;hiredis,&amp;nbsp;Aerospike&amp;nbsp;C&amp;nbsp;client,&amp;nbsp;Cassandra&amp;nbsp;DataStax&amp;nbsp;C/C++&amp;nbsp;driver,&amp;nbsp;MongoDB&amp;nbsp;libmongoc,&amp;nbsp;Couchbase&amp;nbsp;libcouchbase,&amp;nbsp;FoundationDB&amp;nbsp;API&amp;nbsp;C,&amp;nbsp;bbolt-c&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 28.2558%;&quot;&gt;압축&amp;middot;아카이브&amp;middot;파일&amp;nbsp;시스템&lt;/td&gt;
&lt;td style=&quot;width: 71.7442%;&quot;&gt;zlib,&amp;nbsp;zlib-ng,&amp;nbsp;libdeflate,&amp;nbsp;miniz,&amp;nbsp;lz4,&amp;nbsp;lz4hc,&amp;nbsp;lzo,&amp;nbsp;liblzma/xz,&amp;nbsp;bzip2,&amp;nbsp;brotli,&amp;nbsp;zstd,&amp;nbsp;snappy-c,&amp;nbsp;libbsc,&amp;nbsp;libzpaq,&amp;nbsp;libarchive,&amp;nbsp;libzip,&amp;nbsp;libtar,&amp;nbsp;lib7zip,&amp;nbsp;squishfs-lib,&amp;nbsp;libfuse,&amp;nbsp;f2fs-lib,&amp;nbsp;exfatprogs-lib&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 28.2558%;&quot;&gt;암호&amp;middot;보안&amp;middot;해시&lt;/td&gt;
&lt;td style=&quot;width: 71.7442%;&quot;&gt;libsodium,&amp;nbsp;NaCl&amp;nbsp;(reference&amp;nbsp;C),&amp;nbsp;libgcrypt,&amp;nbsp;Nettle,&amp;nbsp;Botan&amp;nbsp;C&amp;nbsp;API,&amp;nbsp;Cryptlib,&amp;nbsp;tiny-AES-c,&amp;nbsp;libtomcrypt,&amp;nbsp;libmd,&amp;nbsp;libressl-libcrypto,&amp;nbsp;GPGME,&amp;nbsp;libscrypt,&amp;nbsp;argon2-c,&amp;nbsp;libbcrypt,&amp;nbsp;mbedTLS&amp;nbsp;PSA,&amp;nbsp;BearSSL,&amp;nbsp;libkeccak,&amp;nbsp;cifra,&amp;nbsp;libsha3,&amp;nbsp;CCHash,&amp;nbsp;Blake3-c,&amp;nbsp;XXHash-c&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 28.2558%;&quot;&gt;수학&amp;middot;과학&amp;nbsp;계산&lt;/td&gt;
&lt;td style=&quot;width: 71.7442%;&quot;&gt;GSL,&amp;nbsp;cephes,&amp;nbsp;BLAS&amp;nbsp;(cBLAS),&amp;nbsp;LAPACK,&amp;nbsp;OpenBLAS,&amp;nbsp;ATLAS,&amp;nbsp;Eigen&amp;nbsp;C&amp;nbsp;API,&amp;nbsp;Armadillo&amp;nbsp;C&amp;nbsp;API,&amp;nbsp;FFTW3,&amp;nbsp;KISS&amp;nbsp;FFT,&amp;nbsp;FFTS,&amp;nbsp;fftsg,&amp;nbsp;PocketFFT-c,&amp;nbsp;GMP,&amp;nbsp;MPFR,&amp;nbsp;MPC,&amp;nbsp;MPIR,&amp;nbsp;qd,&amp;nbsp;libcerf,&amp;nbsp;SuiteSparse&amp;nbsp;(CHOLMOD,&amp;nbsp;UMFPACK),&amp;nbsp;PETSc,&amp;nbsp;SLEPc,&amp;nbsp;ARPACK-NG,&amp;nbsp;OpenCV&amp;nbsp;core&amp;nbsp;C,&amp;nbsp;libtorch&amp;nbsp;C&amp;nbsp;API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 28.2558%;&quot;&gt;DSP&amp;middot;오디오&lt;/td&gt;
&lt;td style=&quot;width: 71.7442%;&quot;&gt;ALSA-lib,&amp;nbsp;PulseAudio&amp;nbsp;lib,&amp;nbsp;PortAudio,&amp;nbsp;Libsoundio,&amp;nbsp;JACK,&amp;nbsp;OpenAL&amp;nbsp;Soft,&amp;nbsp;RTAudio,&amp;nbsp;libsndfile,&amp;nbsp;libsox,&amp;nbsp;libsamplerate,&amp;nbsp;libvorbis,&amp;nbsp;libopus,&amp;nbsp;libflac,&amp;nbsp;libfaad2,&amp;nbsp;libmpg123,&amp;nbsp;libmad,&amp;nbsp;wavpack,&amp;nbsp;libspeex,&amp;nbsp;libspandsp,&amp;nbsp;libcdio,&amp;nbsp;libao,&amp;nbsp;miniaudio,&amp;nbsp;dr_wav,&amp;nbsp;dr_flac&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 28.2558%;&quot;&gt;그래픽&amp;middot;이미지&amp;middot;GUI&lt;/td&gt;
&lt;td style=&quot;width: 71.7442%;&quot;&gt;SDL2,&amp;nbsp;Allegro5,&amp;nbsp;SFML/C&amp;nbsp;wrapper&amp;nbsp;(CSFML),&amp;nbsp;Raylib,&amp;nbsp;GLFW,&amp;nbsp;EGL,&amp;nbsp;Vulkan-Loader,&amp;nbsp;GLEW,&amp;nbsp;glad,&amp;nbsp;FreeType,&amp;nbsp;HarfBuzz,&amp;nbsp;Cairo,&amp;nbsp;Skia,&amp;nbsp;agg,&amp;nbsp;NanoVG,&amp;nbsp;Nuklear,&amp;nbsp;Dear&amp;nbsp;ImGui&amp;nbsp;(C-binding&amp;nbsp;cimgui),&amp;nbsp;LVGL,&amp;nbsp;IUP,&amp;nbsp;GTK&amp;nbsp;2/3/4,&amp;nbsp;Qt&amp;nbsp;(C++&amp;nbsp;API&amp;nbsp;&amp;amp;&amp;nbsp;C&amp;nbsp;wrappers),&amp;nbsp;wxWidgets,&amp;nbsp;FLTK,&amp;nbsp;libui,&amp;nbsp;tinyfiledialogs,&amp;nbsp;libpng,&amp;nbsp;libjpeg-turbo,&amp;nbsp;libjpeg-xl,&amp;nbsp;libtiff,&amp;nbsp;libwebp,&amp;nbsp;libavif,&amp;nbsp;libjxl-dec,&amp;nbsp;libheif,&amp;nbsp;libspng,&amp;nbsp;lodepng,&amp;nbsp;stb_image,&amp;nbsp;stb_truetype,&amp;nbsp;libgd,&amp;nbsp;librsvg,&amp;nbsp;openjpeg,&amp;nbsp;leptonica&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 28.2558%;&quot;&gt;비디오&amp;middot;멀티미디어&lt;/td&gt;
&lt;td style=&quot;width: 71.7442%;&quot;&gt;FFmpeg&amp;nbsp;(libavcodec,&amp;nbsp;libavformat,&amp;nbsp;libavutil,&amp;nbsp;libswscale,&amp;nbsp;libswresample,&amp;nbsp;libavfilter),&amp;nbsp;GStreamer,&amp;nbsp;libv4l2,&amp;nbsp;libcamera,&amp;nbsp;x264,&amp;nbsp;x265,&amp;nbsp;libvpx,&amp;nbsp;libaom,&amp;nbsp;dav1d,&amp;nbsp;libtheora,&amp;nbsp;openh264,&amp;nbsp;rav1e‐c,&amp;nbsp;schroedinger,&amp;nbsp;liboggz,&amp;nbsp;libdash,&amp;nbsp;libass,&amp;nbsp;libbluray&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 28.2558%;&quot;&gt;게임&amp;middot;물리&amp;middot;엔진&lt;/td&gt;
&lt;td style=&quot;width: 71.7442%;&quot;&gt;Box2D-c,&amp;nbsp;Chipmunk2D,&amp;nbsp;Bullet&amp;nbsp;Physics&amp;nbsp;(C&amp;nbsp;API),&amp;nbsp;ODE,&amp;nbsp;PhysFS,&amp;nbsp;ENet,&amp;nbsp;RakNet-c,&amp;nbsp;libenet,&amp;nbsp;Godot-GDNative‐C,&amp;nbsp;cocos2d-x&amp;nbsp;C&amp;nbsp;binding,&amp;nbsp;mango-C&amp;nbsp;game-lib,&amp;nbsp;regl,&amp;nbsp;tinygl,&amp;nbsp;dr_gamepad&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 28.2558%;&quot;&gt;임베디드&amp;middot;IoT&amp;middot;하드웨어&amp;nbsp;제어&lt;/td&gt;
&lt;td style=&quot;width: 71.7442%;&quot;&gt;FreeRTOS,&amp;nbsp;Zephyr&amp;nbsp;RTOS,&amp;nbsp;RIOT&amp;nbsp;OS&amp;nbsp;libs,&amp;nbsp;lwIP,&amp;nbsp;mbedTLS,&amp;nbsp;tinyUSB,&amp;nbsp;libopencm3,&amp;nbsp;CMSIS-DSP/CMSIS-RTOS-RTX,&amp;nbsp;pico-sdk,&amp;nbsp;wiringPi,&amp;nbsp;pigpio,&amp;nbsp;bcm2835,&amp;nbsp;libgpiod,&amp;nbsp;libsoc,&amp;nbsp;OpenOCD&amp;nbsp;JTAG&amp;nbsp;libs,&amp;nbsp;libmodbus,&amp;nbsp;libiec60870,&amp;nbsp;Paho&amp;nbsp;MQTT&amp;nbsp;C,&amp;nbsp;libcoap,&amp;nbsp;ThingsBoard&amp;nbsp;C&amp;nbsp;SDK&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 28.2558%;&quot;&gt;로깅&amp;middot;유틸리티&amp;middot;CLI&lt;/td&gt;
&lt;td style=&quot;width: 71.7442%;&quot;&gt;zlog,&amp;nbsp;log4c,&amp;nbsp;glog,&amp;nbsp;plog-c-wrapper,&amp;nbsp;syslog-ng&amp;nbsp;lib,&amp;nbsp;spdlog-c-wrapper,&amp;nbsp;klib&amp;nbsp;(ksort/kvps/kh),&amp;nbsp;uthash,&amp;nbsp;utlist,&amp;nbsp;sds,&amp;nbsp;kvec,&amp;nbsp;kitsune-string,&amp;nbsp;libcli,&amp;nbsp;linenoise,&amp;nbsp;argp,&amp;nbsp;argtable3,&amp;nbsp;docopt-c,&amp;nbsp;subcmd,&amp;nbsp;getopt-tclap-c,&amp;nbsp;libprogressbar,&amp;nbsp;libpwquality,&amp;nbsp;libuuid,&amp;nbsp;libmagic,&amp;nbsp;libmime,&amp;nbsp;libpcre2,&amp;nbsp;Oniguruma&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 28.2558%;&quot;&gt;테스트&amp;middot;벤치마킹&amp;middot;프로파일링&lt;/td&gt;
&lt;td style=&quot;width: 71.7442%;&quot;&gt;Check,&amp;nbsp;CUnit,&amp;nbsp;Unity,&amp;nbsp;cmocka,&amp;nbsp;Criterion,&amp;nbsp;MinUnit,&amp;nbsp;&amp;micro;Test,&amp;nbsp;Google&amp;nbsp;Benchmark&amp;nbsp;(C++&amp;nbsp;API&amp;nbsp;with&amp;nbsp;C&amp;nbsp;tests),&amp;nbsp;Catch2-C,&amp;nbsp;doctest-C,&amp;nbsp;gperftools,&amp;nbsp;valgrind,&amp;nbsp;Callgrind,&amp;nbsp;Cachegrind,&amp;nbsp;massif-viz,&amp;nbsp;perf&amp;nbsp;(libperf),&amp;nbsp;oprofile,&amp;nbsp;ftrace,&amp;nbsp;SystemTap&amp;nbsp;libdtrace,&amp;nbsp;libcoverage-gcov,&amp;nbsp;Sanitizers&amp;nbsp;(ASan,&amp;nbsp;UBSan,&amp;nbsp;TSan),&amp;nbsp;Frankencoverage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 28.2558%;&quot;&gt;빌드&amp;middot;패키징&amp;middot;배포&lt;/td&gt;
&lt;td style=&quot;width: 71.7442%;&quot;&gt;Autotools&amp;nbsp;(autoconf,&amp;nbsp;automake,&amp;nbsp;libtool),&amp;nbsp;CMake,&amp;nbsp;Meson,&amp;nbsp;Ninja,&amp;nbsp;SCons,&amp;nbsp;Waf,&amp;nbsp;QMake,&amp;nbsp;XMake,&amp;nbsp;Bazel&amp;nbsp;(C&amp;nbsp;rules),&amp;nbsp;Premake,&amp;nbsp;build2,&amp;nbsp;Make,&amp;nbsp;GNU&amp;nbsp;Make,&amp;nbsp;BSD&amp;nbsp;make,&amp;nbsp;vcpkg,&amp;nbsp;Conan,&amp;nbsp;Hunter,&amp;nbsp;CPM.cmake,&amp;nbsp;Spack,&amp;nbsp;pkg-config,&amp;nbsp;cget,&amp;nbsp;Teaport&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 28.2558%;&quot;&gt;파서&amp;middot;정규식&amp;middot;컴파일러&amp;nbsp;툴체인&lt;/td&gt;
&lt;td style=&quot;width: 71.7442%;&quot;&gt;Flex,&amp;nbsp;Bison,&amp;nbsp;Lemon,&amp;nbsp;Ragel,&amp;nbsp;RE2-C,&amp;nbsp;PCRE2,&amp;nbsp;Oniguruma,&amp;nbsp;TRE-regex,&amp;nbsp;libfsm,&amp;nbsp;PEGTL-C-wrapper,&amp;nbsp;Parsifal,&amp;nbsp;Tree-Sitter&amp;nbsp;C,&amp;nbsp;LibClang&amp;nbsp;(C&amp;nbsp;Indexing),&amp;nbsp;LLVM&amp;nbsp;libLLVM,&amp;nbsp;libtcc&amp;nbsp;(Tiny&amp;nbsp;C&amp;nbsp;Compiler&amp;nbsp;libtcc),&amp;nbsp;cparser,&amp;nbsp;lld-c,&amp;nbsp;libjit,&amp;nbsp;QBE,&amp;nbsp;dynasm-c,&amp;nbsp;TinyCC&amp;nbsp;musl,&amp;nbsp;libelf,&amp;nbsp;elftools-libelfin,&amp;nbsp;cxxdemangle-c&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 28.2558%;&quot;&gt;머신러닝&amp;middot;컴퓨터비전&lt;/td&gt;
&lt;td style=&quot;width: 71.7442%;&quot;&gt;OpenCV&amp;nbsp;(C&amp;nbsp;legacy&amp;nbsp;API),&amp;nbsp;dlib-c,&amp;nbsp;Darknet&amp;nbsp;C,&amp;nbsp;tiny-dnn-c,&amp;nbsp;TensorFlow&amp;nbsp;C&amp;nbsp;API,&amp;nbsp;ONNX&amp;nbsp;Runtime&amp;nbsp;C,&amp;nbsp;TensorRT&amp;nbsp;C++,&amp;nbsp;MXNet&amp;nbsp;C&amp;nbsp;predict,&amp;nbsp;ncnn,&amp;nbsp;MNN,&amp;nbsp;TFLite&amp;nbsp;C,&amp;nbsp;LibTorch&amp;nbsp;C,&amp;nbsp;libsvm,&amp;nbsp;Caffe&amp;nbsp;C&amp;nbsp;wrapper,&amp;nbsp;ImageMagick&amp;nbsp;MagickCore,&amp;nbsp;libtesseract-OCR&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 28.2558%;&quot;&gt;기타&amp;nbsp;도메인&amp;nbsp;특화&lt;/td&gt;
&lt;td style=&quot;width: 71.7442%;&quot;&gt;libgit2,&amp;nbsp;libarchive-zip,&amp;nbsp;libxlsxwriter,&amp;nbsp;libxls,&amp;nbsp;libssh2,&amp;nbsp;libimobiledevice,&amp;nbsp;libplist,&amp;nbsp;libqoi,&amp;nbsp;libexif,&amp;nbsp;libgphoto2,&amp;nbsp;libraw,&amp;nbsp;libgeotiff,&amp;nbsp;proj-c,&amp;nbsp;GDAL-C,&amp;nbsp;libspatialite,&amp;nbsp;cairo-pdf,&amp;nbsp;libharu,&amp;nbsp;mupdf-fitz,&amp;nbsp;libtic,&amp;nbsp;ncurses,&amp;nbsp;termbox-c,&amp;nbsp;libvterm,&amp;nbsp;libtwolame,&amp;nbsp;libsndfile-py,&amp;nbsp;libsrt,&amp;nbsp;libsoxr,&amp;nbsp;libserialport,&amp;nbsp;gphoto2,&amp;nbsp;libiec61850,&amp;nbsp;openscad&amp;nbsp;CSG-lib,&amp;nbsp;libigl-c&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;4. C++의 라이브러리&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;C++.png&quot; data-origin-width=&quot;459&quot; data-origin-height=&quot;517&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bIUk5i/btsPFXmIs6A/rnkSjHjXKuUF8t5mDdWsI1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bIUk5i/btsPFXmIs6A/rnkSjHjXKuUF8t5mDdWsI1/img.png&quot; data-alt=&quot;[이미지10] C++&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bIUk5i/btsPFXmIs6A/rnkSjHjXKuUF8t5mDdWsI1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbIUk5i%2FbtsPFXmIs6A%2FrnkSjHjXKuUF8t5mDdWsI1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;200&quot; height=&quot;225&quot; data-filename=&quot;C++.png&quot; data-origin-width=&quot;459&quot; data-origin-height=&quot;517&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지10] C++&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;C++ 언어에서의 라이브러리는 C와 마찬가지로 미리 컴파일된 코드의 묶음이지만, 함수뿐 아니라 클래스와 템플릿까지 포함하는 확장된 형태를 가진다. C++은 C를 포함하는 상위 호환 언어이므로 C의 함수 라이브러리 개념을 그대로 계승하면서, 여러 프로그램에서 공통으로 쓸 수 있는 클래스나 자료형에 상관없이 동작하는 템플릿 코드도 함께 묶어 제공한다. 특히 C++ 표준 라이브러리는 클래스와 함수의 집합으로 구성되며, 표준 템플릿 라이브러리(STL)처럼 컨테이너, 알고리즘, 반복자 등을 클래스와 템플릿 기반으로 구현해 제공한다. 이러한 라이브러리는 일반적으로 헤더 파일에 인터페이스와 템플릿 구현을 포함하고, 나머지 구현은 라이브러리로 컴파일되어 배포된다. 또한 템플릿 기반의 헤더 전용 라이브러리도 흔히 사용되며, 이 경우 모든 코드가 헤더에 포함되어 컴파일 시 직접 인라인 확장된다. 이처럼 C++ 라이브러리는 C의 절차적 함수 중심 구조를 확장하여, 객체지향적 클래스 라이브러리와 제네릭 템플릿 코드를 함께 제공하는 것이 특징이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;4-1. 표준 라이브러리&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;C++ 표준 라이브러리는 C 표준 라이브러리의 대부분을 포함하면서도, STL(Standard Template Library)과 같은 제네릭 라이브러리를 통해 자료구조와 알고리즘을 추가로 제공한다. 이를 통해 개발자는 벡터, 리스트, 맵 등 다양한 컨테이너와 정렬, 탐색 같은 알고리즘을 표준만으로도 바로 활용할 수 있다. 표준 라이브러리의 설계 철학은 언어 핵심을 보조하는 필수 기능 위주로 구성하는 최소주의에 있으며, 특수한 분야의 고급 기능보다는 프로그래밍에 반드시 필요한 기본 도구와 범용 기능에 집중한다. 결과적으로 규모와 범위는 C보다는 확장되었지만, Java나 Python처럼 광범위한 분야를 아우르는 방대한 표준 라이브러리에 비하면 중간 수준의 크기와 범위를 가진다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;4-2.&lt;span&gt;&amp;nbsp;표준&lt;/span&gt; 패키지 관리자&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;791&quot; data-origin-height=&quot;426&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b2fMe4/btsPO3ziowR/lHCmOShZkVvsKMjQIHItL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b2fMe4/btsPO3ziowR/lHCmOShZkVvsKMjQIHItL0/img.png&quot; data-alt=&quot;[이미지11] vcpkg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b2fMe4/btsPO3ziowR/lHCmOShZkVvsKMjQIHItL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb2fMe4%2FbtsPO3ziowR%2FlHCmOShZkVvsKMjQIHItL0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;791&quot; height=&quot;426&quot; data-origin-width=&quot;791&quot; data-origin-height=&quot;426&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지11] vcpkg&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1493&quot; data-origin-height=&quot;396&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bOAXr3/btsPOpWPvVh/AFvUfwKrX8M0dfgPxLVN21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bOAXr3/btsPOpWPvVh/AFvUfwKrX8M0dfgPxLVN21/img.png&quot; data-alt=&quot;[이미지12] conan&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bOAXr3/btsPOpWPvVh/AFvUfwKrX8M0dfgPxLVN21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbOAXr3%2FbtsPOpWPvVh%2FAFvUfwKrX8M0dfgPxLVN21%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1493&quot; height=&quot;396&quot; data-origin-width=&quot;1493&quot; data-origin-height=&quot;396&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지12] conan&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C++ 언어는 역사적으로 표준화된 패키지 관리자가 존재하지 않았기 때문에, 라이브러리 배포와 의존성 관리는 개발자가 직접 수행해야 했다. 필요한 라이브러리의 소스 코드를 받아 직접 컴파일하거나, 운영체제의 패키지 관리자를 통해 미리 빌드된 패키지를 설치하는 방식이 일반적이었다. 그러나 C/C++ 전용 패키지 관리 도구가 등장하면서 이 과정이 점차 자동화되고 있다. 대표적으로 Microsoft의 vcpkg는 2천 개 이상의 오픈소스 라이브러리를 지원하며 Windows, Linux, macOS에서 동일한 방식으로 설치 및 관리를 할 수 있고, Conan은 중앙 서버 기반의 패키지 공유 생태계를 제공하여 다양한 빌드 설정과 플랫폼을 지원한다. 이 밖에도 HPC(고성능 컴퓨팅) 환경에 특화된 Spack 등이 존재하며, 이러한 도구들은 빌드 스크립트 작성, 의존성 해결, 버전 관리 등을 통합적으로 제공함으로써 C/C++ 라이브러리 관리의 편의성을 크게 향상시키고 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;4-3. 라이브러리&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 438px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 27.3256%; height: 21px;&quot;&gt;카테고리&lt;/td&gt;
&lt;td style=&quot;width: 72.6744%; height: 21px;&quot;&gt;라이브러리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 52px;&quot;&gt;
&lt;td style=&quot;width: 27.3256%; height: 52px;&quot;&gt;표준&amp;middot;런타임&lt;/td&gt;
&lt;td style=&quot;width: 72.6744%; height: 52px;&quot;&gt;C++&amp;nbsp;Standard&amp;nbsp;Library(STL&amp;nbsp;+&amp;nbsp;RANGES&amp;nbsp;+&amp;nbsp;FMT&amp;nbsp;+&amp;nbsp;SPACESHIP),&amp;nbsp;libc++&amp;nbsp;(LLVM),&amp;nbsp;libstdc++,&amp;nbsp;MSVC&amp;nbsp;STL,&amp;nbsp;libc++&amp;nbsp;(Apple),&amp;nbsp;libstdc++-d11,&amp;nbsp;EASTL,&amp;nbsp;EA-STL,&amp;nbsp;Folly&amp;nbsp;Core,&amp;nbsp;Abseil-base,&amp;nbsp;Boost.Core&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 52px;&quot;&gt;
&lt;td style=&quot;width: 27.3256%; height: 52px;&quot;&gt;컨테이너&amp;middot;알고리즘&lt;/td&gt;
&lt;td style=&quot;width: 72.6744%; height: 52px;&quot;&gt;range-v3,&amp;nbsp;boost::container,&amp;nbsp;folly::F14,&amp;nbsp;EASTL&amp;nbsp;containers,&amp;nbsp;plf::colony,&amp;nbsp;robin-hood-hashing,&amp;nbsp;ska::flat_hash_map,&amp;nbsp;hopscotch-map,&amp;nbsp;sorted_vector,&amp;nbsp;Brigand,&amp;nbsp;Brigand-Hana,&amp;nbsp;nanorange,&amp;nbsp;ETL&amp;nbsp;(Embedded&amp;nbsp;TL)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 52px;&quot;&gt;
&lt;td style=&quot;width: 27.3256%; height: 52px;&quot;&gt;동시성&amp;middot;태스크&amp;middot;메모리&lt;/td&gt;
&lt;td style=&quot;width: 72.6744%; height: 52px;&quot;&gt;Intel&amp;nbsp;oneTBB,&amp;nbsp;HPX,&amp;nbsp;Taskflow,&amp;nbsp;concurrencpp,&amp;nbsp;libdispatch&amp;nbsp;(GCD),&amp;nbsp;cppcoro,&amp;nbsp;Boost.Fiber,&amp;nbsp;Boost.Thread,&amp;nbsp;BS::thread_pool,&amp;nbsp;readerwriterqueue,&amp;nbsp;libcds,&amp;nbsp;jemalloc-cpp,&amp;nbsp;mimalloc,&amp;nbsp;tcmalloc,&amp;nbsp;rpmalloc,&amp;nbsp;hoard,&amp;nbsp;hazard-eras,&amp;nbsp;folly::Executor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 70px;&quot;&gt;
&lt;td style=&quot;width: 27.3256%; height: 70px;&quot;&gt;네트워크&amp;middot;RPC&amp;middot;메시징&lt;/td&gt;
&lt;td style=&quot;width: 72.6744%; height: 70px;&quot;&gt;Asio(stand-alone),&amp;nbsp;Boost.Asio/Beast,&amp;nbsp;gRPC-C++,&amp;nbsp;cpp-httplib,&amp;nbsp;C++&amp;nbsp;REST&amp;nbsp;SDK(Casablanca),&amp;nbsp;cpr,&amp;nbsp;Crow,&amp;nbsp;Pistache,&amp;nbsp;Restbed,&amp;nbsp;POCO-Net,&amp;nbsp;websocketpp,&amp;nbsp;SimpleWebServer,&amp;nbsp;uWebSockets-cpp,&amp;nbsp;brpc,&amp;nbsp;nanomsg,&amp;nbsp;nng,&amp;nbsp;ZeroMQ-cpp&amp;nbsp;(cppzmq),&amp;nbsp;libtins,&amp;nbsp;ENet++,&amp;nbsp;IXWebSocket,&amp;nbsp;libcurlpp,&amp;nbsp;libssh-cpp,&amp;nbsp;libwebsockets,&amp;nbsp;ICE,&amp;nbsp;Wangle&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 70px;&quot;&gt;
&lt;td style=&quot;width: 27.3256%; height: 70px;&quot;&gt;직렬화&amp;middot;파일포맷&lt;/td&gt;
&lt;td style=&quot;width: 72.6744%; height: 70px;&quot;&gt;nlohmann/json,&amp;nbsp;RapidJSON,&amp;nbsp;simdjson-cpp,&amp;nbsp;Boost.JSON,&amp;nbsp;cereal,&amp;nbsp;protobuf-C++,&amp;nbsp;FlatBuffers,&amp;nbsp;Cap&amp;rsquo;n&amp;nbsp;Proto-cpp,&amp;nbsp;Thrift-cpp,&amp;nbsp;MsgPack-C++,&amp;nbsp;BSON-CXX,&amp;nbsp;YAML-CPP,&amp;nbsp;toml++,&amp;nbsp;HOCON-cpp,&amp;nbsp;libconfig++/libconfuse++,&amp;nbsp;TinyXML-2,&amp;nbsp;pugixml,&amp;nbsp;libxlsxwriter-cpp,&amp;nbsp;PDFium-cpp,&amp;nbsp;libzippp,&amp;nbsp;libarchive-cpp&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 70px;&quot;&gt;
&lt;td style=&quot;width: 27.3256%; height: 70px;&quot;&gt;데이터베이스&amp;middot;스토리지&lt;/td&gt;
&lt;td style=&quot;width: 72.6744%; height: 70px;&quot;&gt;SQLite&amp;nbsp;(C++&amp;nbsp;wrapper&amp;nbsp;sqlite_modern_cpp),&amp;nbsp;SOCI,&amp;nbsp;ODB&amp;nbsp;ORM,&amp;nbsp;libpqxx(PostgreSQL),&amp;nbsp;mysql-connector-cpp,&amp;nbsp;MariaDB-connector-cpp,&amp;nbsp;leveldb-cpp-wrapper,&amp;nbsp;rocksdb-cpp,&amp;nbsp;DuckDB-cpp,&amp;nbsp;LMDB++(lmdb++),&amp;nbsp;redis-hiredis-cpp,&amp;nbsp;cassandra-cpp-driver,&amp;nbsp;couchbase-cbpp,&amp;nbsp;FoundationDB-API-C++&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 27.3256%; height: 17px;&quot;&gt;암호&amp;middot;보안&amp;middot;해시&lt;/td&gt;
&lt;td style=&quot;width: 72.6744%; height: 17px;&quot;&gt;OpenSSL-cpp&amp;nbsp;wrappers&amp;nbsp;(asio::ssl,&amp;nbsp;QSslSocket),&amp;nbsp;Botan,&amp;nbsp;libsodium-cpp,&amp;nbsp;mbedtls-cpp,&amp;nbsp;wolfSSL-cpp,&amp;nbsp;BearSSL-cpp,&amp;nbsp;Crypto++/cryptopp,&amp;nbsp;libbcrypt-cpp,&amp;nbsp;argon2-cpp,&amp;nbsp;s2n-tls-cpp,&amp;nbsp;hash-library&amp;nbsp;(xxhash-cpp,&amp;nbsp;blake3-cpp)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 27.3256%; height: 17px;&quot;&gt;수학&amp;middot;과학&amp;middot;통계&lt;/td&gt;
&lt;td style=&quot;width: 72.6744%; height: 17px;&quot;&gt;Eigen,&amp;nbsp;Blaze,&amp;nbsp;Armadillo,&amp;nbsp;xtensor,&amp;nbsp;dynet,&amp;nbsp;CGAL,&amp;nbsp;Boost.Math,&amp;nbsp;Boost.Multiprecision,&amp;nbsp;CERES-Solver,&amp;nbsp;SuiteSparse,&amp;nbsp;PETSc-cpp,&amp;nbsp;GSL-numeric,&amp;nbsp;GMP++(gmpxx),&amp;nbsp;MPFR-cpp,&amp;nbsp;FFTW++/kissfft-cpp,&amp;nbsp;qd-cpp,&amp;nbsp;SymEngine-cpp&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 27.3256%; height: 17px;&quot;&gt;머신러닝&amp;middot;딥러닝&amp;middot;컴퓨터비전&lt;/td&gt;
&lt;td style=&quot;width: 72.6744%; height: 17px;&quot;&gt;LibTorch(C++&amp;nbsp;API&amp;nbsp;of&amp;nbsp;PyTorch),&amp;nbsp;TensorFlow&amp;nbsp;C++&amp;nbsp;API,&amp;nbsp;ONNX-Runtime-C++,&amp;nbsp;MXNet-cpp,&amp;nbsp;ncnn,&amp;nbsp;MNN-cpp,&amp;nbsp;tiny-dnn,&amp;nbsp;DLib,&amp;nbsp;OpenCV&amp;nbsp;4&amp;nbsp;(C++),&amp;nbsp;Halide,&amp;nbsp;EDDL-cpp,&amp;nbsp;Darknet-cpp&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 27.3256%;&quot;&gt;그래픽&amp;middot;GUI&amp;middot;이미지&lt;/td&gt;
&lt;td style=&quot;width: 72.6744%;&quot;&gt;Qt&amp;nbsp;(Widgets/Qt&amp;nbsp;Quick/QML),&amp;nbsp;wxWidgets,&amp;nbsp;GTKmm,&amp;nbsp;FLTK-cpp,&amp;nbsp;Dear&amp;nbsp;ImGui,&amp;nbsp;imgui-SFML,&amp;nbsp;NanoGUI,&amp;nbsp;Nuklear-cpp,&amp;nbsp;SFML,&amp;nbsp;SDL2-cpp,&amp;nbsp;GLFW,&amp;nbsp;bgfx,&amp;nbsp;Ogre3D,&amp;nbsp;Skia-cpp,&amp;nbsp;Cairo-cpp,&amp;nbsp;FreeType-cpp,&amp;nbsp;HarfBuzz-cpp,&amp;nbsp;libpng++/libjpg-turbo-cpp,&amp;nbsp;stb-image-cpp,&amp;nbsp;LodePNG-cpp,&amp;nbsp;libheif-cpp,&amp;nbsp;libwebp-cpp,&amp;nbsp;librsvg-cpp&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 27.3256%;&quot;&gt;비디오&amp;middot;오디오&amp;middot;멀티미디어&lt;/td&gt;
&lt;td style=&quot;width: 72.6744%;&quot;&gt;FFmpeg&amp;nbsp;(lav*,&amp;nbsp;swresample)&amp;nbsp;C++&amp;nbsp;wrappers&amp;nbsp;(ffmpeg-cpp,&amp;nbsp;libavif-cpp),&amp;nbsp;GStreamer-cpp(gst-cpp),&amp;nbsp;OpenAL-Soft-cpp,&amp;nbsp;PortAudio-cpp,&amp;nbsp;RtAudio,&amp;nbsp;JUCE,&amp;nbsp;libsndfile-cpp,&amp;nbsp;libvorbis-cpp,&amp;nbsp;libopus-cpp,&amp;nbsp;libtheora-cpp,&amp;nbsp;x264-cpp,&amp;nbsp;x265-cpp,&amp;nbsp;libvpx-cpp,&amp;nbsp;dav1d-cpp&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 27.3256%;&quot;&gt;게임&amp;middot;물리&amp;middot;엔진&lt;/td&gt;
&lt;td style=&quot;width: 72.6744%;&quot;&gt;Box2D-cpp,&amp;nbsp;Chipmunk2D-cpp,&amp;nbsp;Bullet&amp;nbsp;Physics-C&amp;nbsp;API,&amp;nbsp;ODE-cpp,&amp;nbsp;PhysX-sdk,&amp;nbsp;EnTT&amp;nbsp;(ECS),&amp;nbsp;ECSY-cpp,&amp;nbsp;bgfx,&amp;nbsp;Godot-GDNative-cpp,&amp;nbsp;Cocos2d-x,&amp;nbsp;Urho3D,&amp;nbsp;Panda3D-cpp,&amp;nbsp;RenderDoc-cpp&amp;nbsp;(capture&amp;nbsp;API)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 27.3256%;&quot;&gt;임베디드&amp;middot;IoT&amp;middot;하드웨어&lt;/td&gt;
&lt;td style=&quot;width: 72.6744%;&quot;&gt;Zephyr-libc-pp,&amp;nbsp;FreeRTOS-cpp&amp;nbsp;wrappers,&amp;nbsp;mbed-OS-cpp,&amp;nbsp;pico-sdk-cpp,&amp;nbsp;wiringPi-cpp,&amp;nbsp;pigpio-cpp,&amp;nbsp;libgpiod-cpp,&amp;nbsp;tinyUSB-cpp,&amp;nbsp;libmodbus-cpp,&amp;nbsp;libiec60870-cpp,&amp;nbsp;MQTT-Paho-cpp,&amp;nbsp;libcoap-cpp&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 27.3256%;&quot;&gt;로깅&amp;middot;유틸리티&amp;middot;CLI&lt;/td&gt;
&lt;td style=&quot;width: 72.6744%;&quot;&gt;spdlog,&amp;nbsp;Boost.Log,&amp;nbsp;easylogging++,&amp;nbsp;loguru,&amp;nbsp;plog,&amp;nbsp;fmt,&amp;nbsp;date-cpp,&amp;nbsp;HowardHinnant/chrono,&amp;nbsp;CLI11,&amp;nbsp;cxxopts,&amp;nbsp;docopt-cpp,&amp;nbsp;argparse-cpp,&amp;nbsp;linenoise-ng-cpp,&amp;nbsp;termcolor-cpp,&amp;nbsp;rang,&amp;nbsp;tabulate-cpp,&amp;nbsp;progressbar-cpp,&amp;nbsp;Catch2-(test&amp;nbsp;+&amp;nbsp;BBD),&amp;nbsp;GoogleTest(gTest/gMock),&amp;nbsp;doctest,&amp;nbsp;Benchmark,&amp;nbsp;nanobench&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 27.3256%;&quot;&gt;파싱&amp;middot;컴파일러&amp;middot;리플렉션&lt;/td&gt;
&lt;td style=&quot;width: 72.6744%;&quot;&gt;LLVM/Clang&amp;nbsp;libclang,&amp;nbsp;libtooling,&amp;nbsp;Cling,&amp;nbsp;libfmt,&amp;nbsp;PEGTL,&amp;nbsp;Spirit-X3,&amp;nbsp;Lexy,&amp;nbsp;Boost.Spirit,&amp;nbsp;ANTLR4-cpp-runtime,&amp;nbsp;Flex/Bison++,&amp;nbsp;RE2-cpp,&amp;nbsp;PCRE2-cpp,&amp;nbsp;Oniguruma-cpp,&amp;nbsp;cxxreflect,&amp;nbsp;meta-cpp-reflection,&amp;nbsp;DynASM-cpp,&amp;nbsp;libelfin-cpp,&amp;nbsp;elftools-libdwarf-cpp&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 27.3256%;&quot;&gt;테스트&amp;middot;프로파일&amp;middot;디버그&lt;/td&gt;
&lt;td style=&quot;width: 72.6744%;&quot;&gt;Valgrind, Cachegrind, Callgrind, gperftools, Tracy profiler, VTune Amplifier, Perfetto-cpp, Sanitizers(ASan/TSan/UBSan) C++, cpp-mem-prof, Google Benchmark, Celero, Criterion-cpp, Catch2-bench, cpp-coverage-gcov&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 27.3256%;&quot;&gt;빌드&amp;middot;패키징&amp;middot;배포&lt;/td&gt;
&lt;td style=&quot;width: 72.6744%;&quot;&gt;CMake(+FetchContent), Meson, Bazel(rules-cpp), Ninja, Premake5, build2, QMake, SCons, Waf, XMake, vcpkg, Conan, Hunter, Spack, CPM.cmake, pkg-config, Buck2-cpp&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 27.3256%;&quot;&gt;문서&amp;middot;코드생성&lt;/td&gt;
&lt;td style=&quot;width: 72.6744%;&quot;&gt;Doxygen, Sphinx-breathe-cpp, Standardese, Inja(template), Jinja2-cpp, Code-gen(Protocol Buf protoc-cpp, gRPC codegen-cpp), Clang-AST-Match-tooling&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;5. Python의 라이브러리&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Python.png&quot; data-origin-width=&quot;165&quot; data-origin-height=&quot;165&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkGF9d/btsPJgFcc01/Ag9xSHxg6EKe4Er3Ponaak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkGF9d/btsPJgFcc01/Ag9xSHxg6EKe4Er3Ponaak/img.png&quot; data-alt=&quot;[이미지13] Python&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkGF9d/btsPJgFcc01/Ag9xSHxg6EKe4Er3Ponaak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkGF9d%2FbtsPJgFcc01%2FAg9xSHxg6EKe4Er3Ponaak%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;200&quot; height=&quot;200&quot; data-filename=&quot;Python.png&quot; data-origin-width=&quot;165&quot; data-origin-height=&quot;165&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지13] Python&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Python에서 라이브러리는 하나 이상의 모듈이나 패키지로 구성된, 재사용 가능한 코드 묶음을 의미한다. Python에서는 이러한 라이브러리가 주로 소스 코드(.py)나 바이트코드(.pyc) 형태로 제공되며, import 문을 사용해 프로그램 실행 중(runtime)에 불러와 사용한다. 라이브러리 내부에는 함수, 클래스, 변수 등이 정의되어 있고, 필요할 때 이를 호출하거나 인스턴스화하여 기능을 활용한다. Python도 객체지향을 지원하므로 많은 라이브러리가 클래스 집합 형태로 제공되지만, C/C++와 달리 컴파일, 링크 과정을 거치지 않고 인터프리터가 런타임에 직접 해석하여 실행한다. 이 덕분에 개발자는 라이브러리 코드를 손쉽게 수정하거나 즉시 반영할 수 있으며, 한 번 작성한 라이브러리를 여러 스크립트에서 공유해 재사용할 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;5-1. 표준 라이브러리&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Python 표준 라이브러리는 &quot;배터리가 장착된(batteries included)&quot; 언어라는 별명을 뒷받침할 만큼 방대하며, 수백 개의 모듈로 구성되어 다양한 분야의 기능을 기본 제공한다. 이러한 모듈 중 일부는 C 언어로 구현되어 인터프리터에 내장된 빌트인 모듈이고, 나머지는 Python 코드로 작성되어 배포되는 표준 모듈이다. 구조적으로 각 모듈은 독립적으로 동작하지만 필요 시 상호 의존성을 통해 기능을 확장하며, 특히 운영체제 차이를 추상화하는 API가 많아 플랫폼 간 이식성을 높인다. 결과적으로, 방대한 외부 라이브러리(PyPI)와 결합하면 규모는 더욱 거대해지지만, 표준 라이브러리만으로도 상당수의 일반적인 프로그래밍 과제를 해결할 수 있을 만큼 크고 종합적이다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;5-2.&lt;span&gt;&amp;nbsp;표준&lt;/span&gt; 패키지 관리자&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1428&quot; data-origin-height=&quot;632&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KbngV/btsPOl1fGUp/UeoHLQkLPawwoho3e8AAwk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KbngV/btsPOl1fGUp/UeoHLQkLPawwoho3e8AAwk/img.png&quot; data-alt=&quot;[이미지14] PyPI&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KbngV/btsPOl1fGUp/UeoHLQkLPawwoho3e8AAwk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKbngV%2FbtsPOl1fGUp%2FUeoHLQkLPawwoho3e8AAwk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1428&quot; height=&quot;632&quot; data-origin-width=&quot;1428&quot; data-origin-height=&quot;632&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지14] PyPI&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Python의 표준 패키지 관리자는 PyPI(Python Package Index)로, 사용자는 pip 명령어를 통해 여기에 등록된 패키지를 손쉽게 설치, 업데이트, 삭제할 수 있다. 2025년 현재 PyPI에는 60만 개가 넘는 패키지가 등록되어 있으며, 이는 과학 계산, 웹 개발, 데이터 분석, 머신러닝, 네트워크 프로그래밍 등 다양한 분야를 포괄한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;5-3. 라이브러리&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 472px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 26.8605%; height: 21px;&quot;&gt;카테고리&lt;/td&gt;
&lt;td style=&quot;width: 73.1395%; height: 21px;&quot;&gt;라이브러리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 35px;&quot;&gt;
&lt;td style=&quot;width: 26.8605%; height: 35px;&quot;&gt;웹 프레임워크&amp;middot;API&amp;middot;실시간&lt;/td&gt;
&lt;td style=&quot;width: 73.1395%; height: 35px;&quot;&gt;Django,&amp;nbsp;Flask,&amp;nbsp;FastAPI,&amp;nbsp;Starlette,&amp;nbsp;Sanic,&amp;nbsp;Tornado,&amp;nbsp;Quart,&amp;nbsp;Bottle,&amp;nbsp;Falcon,&amp;nbsp;Responder,&amp;nbsp;Masonite,&amp;nbsp;Vespid,&amp;nbsp;Aiohttp-web,&amp;nbsp;Cyclone,&amp;nbsp;Growler&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 35px;&quot;&gt;
&lt;td style=&quot;width: 26.8605%; height: 35px;&quot;&gt;HTTP 클라이언트&amp;middot;크롤링&lt;/td&gt;
&lt;td style=&quot;width: 73.1395%; height: 35px;&quot;&gt;requests, httpx, urllib3, treq, BeautifulSoup4, lxml, Scrapy, mechanicalsoup, PyQuery, selenium, playwright-python, pyppeteer, grab, trafilatura, newspaper3k&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 35px;&quot;&gt;
&lt;td style=&quot;width: 26.8605%; height: 35px;&quot;&gt;데이터 과학&amp;middot;배치 컴퓨팅&lt;/td&gt;
&lt;td style=&quot;width: 73.1395%; height: 35px;&quot;&gt;numpy, pandas, polars, dask, modin, vaex, datatable, scipy, pyjanitor, numexpr, bottleneck, pyarrow, fastparquet, feather-format&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 52px;&quot;&gt;
&lt;td style=&quot;width: 26.8605%; height: 52px;&quot;&gt;머신러닝&amp;middot;딥러닝&amp;middot;MLOps&lt;/td&gt;
&lt;td style=&quot;width: 73.1395%; height: 52px;&quot;&gt;scikit-learn, xgboost, lightgbm, catboost, river, PyTorch, TensorFlow/Keras, JAX, Flax, HuggingFace transformers, diffusers, pytorch-lightning, timm, fastai, deepspeed, onnxruntime, mlflow, optuna, wandb, sacred, kedro, dvc&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 35px;&quot;&gt;
&lt;td style=&quot;width: 26.8605%; height: 35px;&quot;&gt;데이터&amp;nbsp;시각화&lt;/td&gt;
&lt;td style=&quot;width: 73.1395%; height: 35px;&quot;&gt;matplotlib, seaborn, plotly, bokeh, altair, holoviews, hvPlot, pyqtgraph, graphviz, pydot, geopandas, folium, keplergl, networkx, seaborn-objects&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 26.8605%; height: 21px;&quot;&gt;자연어&amp;nbsp;처리&amp;nbsp;(NLP)&lt;/td&gt;
&lt;td style=&quot;width: 73.1395%; height: 21px;&quot;&gt;spaCy, NLTK, gensim, sentence-transformers, flair, fastText, textblob, stanza, pytext, transformers-tokenizers, polyglot, sacremoses, seqeval&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 26.8605%; height: 17px;&quot;&gt;컴퓨터 비전&amp;middot;이미지/영상&lt;/td&gt;
&lt;td style=&quot;width: 73.1395%; height: 17px;&quot;&gt;opencv-python, Pillow, scikit-image, imageio, albumentations, torchvision, detectron2, mmcv, mmpretrain, mediapipe, facenet-pytorch, super-gradients, yolov5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 26.8605%; height: 17px;&quot;&gt;오디오&amp;middot;신호 처리&lt;/td&gt;
&lt;td style=&quot;width: 73.1395%; height: 17px;&quot;&gt;librosa,&amp;nbsp;torchaudio,&amp;nbsp;pydub,&amp;nbsp;soundfile,&amp;nbsp;audiomentations,&amp;nbsp;noisereduce,&amp;nbsp;kapre,&amp;nbsp;spleeter,&amp;nbsp;pesq,&amp;nbsp;pruning-audio-tools&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 26.8605%; height: 17px;&quot;&gt;과학&amp;middot;수치&amp;middot;고성능 컴퓨팅&lt;/td&gt;
&lt;td style=&quot;width: 73.1395%; height: 17px;&quot;&gt;numba,&amp;nbsp;cython,&amp;nbsp;pybind11,&amp;nbsp;cupy,&amp;nbsp;pycuda,&amp;nbsp;mpi4py,&amp;nbsp;open3d,&amp;nbsp;simpy,&amp;nbsp;sympy,&amp;nbsp;pint,&amp;nbsp;uncertainties,&amp;nbsp;ase,&amp;nbsp;MDAnalysis&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 26.8605%; height: 17px;&quot;&gt;빅데이터&amp;middot;분산 처리&lt;/td&gt;
&lt;td style=&quot;width: 73.1395%; height: 17px;&quot;&gt;pyspark,&amp;nbsp;ray,&amp;nbsp;ray-air,&amp;nbsp;dask-distributed,&amp;nbsp;apache-beam,&amp;nbsp;flink-python,&amp;nbsp;pyhive,&amp;nbsp;luigi,&amp;nbsp;airflow,&amp;nbsp;prefect,&amp;nbsp;dagster,&amp;nbsp;lakeFS-python&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 26.8605%; height: 17px;&quot;&gt;데이터베이스&amp;middot;ORM&amp;middot;캐시&lt;/td&gt;
&lt;td style=&quot;width: 73.1395%; height: 17px;&quot;&gt;SQLAlchemy,&amp;nbsp;asyncpg,&amp;nbsp;psycopg2-binary,&amp;nbsp;mysql-connector-python,&amp;nbsp;oracledb,&amp;nbsp;pyodbc,&amp;nbsp;mongoengine,&amp;nbsp;pymongo,&amp;nbsp;redis-py,&amp;nbsp;aioredis,&amp;nbsp;cassandra-driver,&amp;nbsp;elasticsearch-py,&amp;nbsp;tinydb,&amp;nbsp;peewee,&amp;nbsp;tortoise-orm,&amp;nbsp;pony-orm,&amp;nbsp;beanie,&amp;nbsp;sqlalchemy-asyncio&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 26.8605%; height: 17px;&quot;&gt;직렬화&amp;middot;데이터 검증&amp;middot;구조화&lt;/td&gt;
&lt;td style=&quot;width: 73.1395%; height: 17px;&quot;&gt;pydantic-v2,&amp;nbsp;dataclasses-json,&amp;nbsp;orjson,&amp;nbsp;msgpack,&amp;nbsp;marshmallow,&amp;nbsp;cattrs,&amp;nbsp;avro-python-ic,&amp;nbsp;protobuf-python-grpc,&amp;nbsp;flatbuffers,&amp;nbsp;pyarrow-ipc,&amp;nbsp;h5py,&amp;nbsp;netCDF4,&amp;nbsp;zarr&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 26.8605%; height: 17px;&quot;&gt;네트워킹&amp;middot;메시징&amp;middot;원격 실행&lt;/td&gt;
&lt;td style=&quot;width: 73.1395%; height: 17px;&quot;&gt;aiohttp,&amp;nbsp;websockets,&amp;nbsp;websocket-client,&amp;nbsp;grpcio,&amp;nbsp;kombu,&amp;nbsp;celery,&amp;nbsp;rq,&amp;nbsp;dramatiq,&amp;nbsp;kafka-python,&amp;nbsp;confluent-kafka,&amp;nbsp;pyzmq,&amp;nbsp;nanomsg,&amp;nbsp;paramiko,&amp;nbsp;fabric,&amp;nbsp;asyncssh&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 26.8605%; height: 17px;&quot;&gt;보안&amp;middot;암호화&amp;middot;인증&lt;/td&gt;
&lt;td style=&quot;width: 73.1395%; height: 17px;&quot;&gt;cryptography,&amp;nbsp;pyjwt,&amp;nbsp;pynacl,&amp;nbsp;bcrypt,&amp;nbsp;passlib,&amp;nbsp;pyopenssl,&amp;nbsp;jose-py,&amp;nbsp;fido2,&amp;nbsp;tlslite-ng,&amp;nbsp;certbot,&amp;nbsp;bandit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 26.8605%; height: 17px;&quot;&gt;테스트&amp;middot;품질&amp;middot;린팅&lt;/td&gt;
&lt;td style=&quot;width: 73.1395%; height: 17px;&quot;&gt;pytest, hypothesis, nose2, unittest, behave, robotframework, coverage, pytest-cov, tox, nox, mypy, ruff, flake8, pylint, black, isort, pyinstrument, line-profiler&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 26.8605%; height: 17px;&quot;&gt;DevOps&amp;middot;클라우드 SDK&lt;/td&gt;
&lt;td style=&quot;width: 73.1395%; height: 17px;&quot;&gt;boto3,&amp;nbsp;aioboto3,&amp;nbsp;google-cloud-core,&amp;nbsp;azure-identity,&amp;nbsp;azure-storage-blob,&amp;nbsp;docker-py,&amp;nbsp;kubernetes,&amp;nbsp;ansible,&amp;nbsp;pulumi,&amp;nbsp;terraform-cdktf,&amp;nbsp;invoke,&amp;nbsp;fabric2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 26.8605%; height: 17px;&quot;&gt;CLI&amp;middot;터미널 UI&lt;/td&gt;
&lt;td style=&quot;width: 73.1395%; height: 17px;&quot;&gt;click,&amp;nbsp;typer,&amp;nbsp;argparse(std),&amp;nbsp;fire,&amp;nbsp;rich,&amp;nbsp;textual,&amp;nbsp;prompt-toolkit,&amp;nbsp;inquirer-py,&amp;nbsp;questionary,&amp;nbsp;pyfiglet,&amp;nbsp;colorama,&amp;nbsp;loguru,&amp;nbsp;halo,&amp;nbsp;tqdm,&amp;nbsp;alive-progress&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 26.8605%; height: 17px;&quot;&gt;GUI&amp;middot;데스크톱&amp;middot;웹앱&lt;/td&gt;
&lt;td style=&quot;width: 73.1395%; height: 17px;&quot;&gt;tkinter(std),&amp;nbsp;PyQt5,&amp;nbsp;PySide6,&amp;nbsp;Kivy,&amp;nbsp;wxPython,&amp;nbsp;DearPyGui,&amp;nbsp;PySimpleGUI,&amp;nbsp;flet,&amp;nbsp;eel,&amp;nbsp;Streamlit,&amp;nbsp;Dash,&amp;nbsp;Panel,&amp;nbsp;Gradio,&amp;nbsp;Voila,&amp;nbsp;NiceGUI,&amp;nbsp;customtkinter&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 26.8605%; height: 17px;&quot;&gt;게임&amp;middot;그래픽스&lt;/td&gt;
&lt;td style=&quot;width: 73.1395%; height: 17px;&quot;&gt;pygame,&amp;nbsp;pyglet,&amp;nbsp;ursina,&amp;nbsp;panda3d,&amp;nbsp;godot-python,&amp;nbsp;moderngl,&amp;nbsp;arcade,&amp;nbsp;pyopengl,&amp;nbsp;kivy-garden,&amp;nbsp;pyrr,&amp;nbsp;pybullet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 26.8605%; height: 17px;&quot;&gt;IoT&amp;middot;하드웨어 통신&lt;/td&gt;
&lt;td style=&quot;width: 73.1395%; height: 17px;&quot;&gt;micropython-unix-port,&amp;nbsp;circuitpython-libs,&amp;nbsp;RPi.GPIO,&amp;nbsp;gpiozero,&amp;nbsp;smbus2,&amp;nbsp;pyserial,&amp;nbsp;bleak,&amp;nbsp;pyusb,&amp;nbsp;pyftdi,&amp;nbsp;adafruit-blinka,&amp;nbsp;python-can&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 26.8605%;&quot;&gt;자동화&amp;middot;RPA&amp;middot;기타&lt;/td&gt;
&lt;td style=&quot;width: 73.1395%;&quot;&gt;pyautogui,&amp;nbsp;pywinauto,&amp;nbsp;keyboard,&amp;nbsp;mouse,&amp;nbsp;pygetwindow,&amp;nbsp;seleniumbase,&amp;nbsp;playwright-sync,&amp;nbsp;openpyxl,&amp;nbsp;python-docx,&amp;nbsp;reportlab,&amp;nbsp;img2pdf&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;6. JAVA의 라이브러리&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;JAVA.png&quot; data-origin-width=&quot;182&quot; data-origin-height=&quot;334&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cVrb3Z/btsPGHEdqMZ/hSXpz9kHkBeTZe8M5xwHN0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cVrb3Z/btsPGHEdqMZ/hSXpz9kHkBeTZe8M5xwHN0/img.png&quot; data-alt=&quot;[이미지15] JAVA&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cVrb3Z/btsPGHEdqMZ/hSXpz9kHkBeTZe8M5xwHN0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcVrb3Z%2FbtsPGHEdqMZ%2FhSXpz9kHkBeTZe8M5xwHN0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;200&quot; height=&quot;367&quot; data-filename=&quot;JAVA.png&quot; data-origin-width=&quot;182&quot; data-origin-height=&quot;334&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지15] JAVA&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Java 언어에서 말하는 라이브러리는 클래스의 모음 형태로 제공되며, 주로 JAR(Java Archive) 파일로 배포된다. Java는 컴파일 시 바이트코드(.class 파일)를 생성하고, 이러한 클래스 파일들을 묶은 JAR이 곧 라이브러리의 역할을 한다. Java 애플리케이션이 실행될 때 JVM(Java Virtual Machine)의 클래스로더(class loader)가 필요한 클래스를 해당 라이브러리(JAR)에서 찾아 로드하며, 이를 동적 로딩 방식으로 수행한다. 즉, C/C++과 달리 별도의 링크 단계 대신, 프로그램 실행 시점에 클래스 경로(classpath)를 따라 필요한 클래스 바이너리를 찾는 방식으로 라이브러리를 결합한다. Java 플랫폼의 기본 라이브러리 집합을 Java 표준 클래스 라이브러리(JCL, Java Class Library)라고 하며, 이는 Java 언어에서 제공하는 표준 API들의 모음이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;6-1. 표준 라이브러리&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;Java의 표준 클래스 라이브러리(JDK에 포함되는 API)는 규모 면에서 가장 방대하다. 수천 개의 클래스와 인터페이스로 구성되어 있으며, 컬렉션 프레임워크, 스레드 및 동시성, 입출력/NIO, 네트워킹, 암호화, DB 연동, GUI, XML/JSON 처리, 국제화, 정규표현식 등 언어 플랫폼 전반에 걸친 풍부한 기능을 표준으로 제공한다. Java 8 기준 약 3,700개의 클래스가 표준 API에 포함되었다는 집계가 있을 정도다. Java 프로그램은 별도의 라이브러리 없이도 대부분의 기본 기능을 표준 API로 구현 가능하며, 이는 언어의 강점인 동시에 그 방대한 규모를 보여준다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;자바 표준 라이브러리는 Java 플랫폼의 일부로서 JRE(Java Runtime Environment)에 함께 배포되며, Java 애플리케이션은 별도 설치 없이 이 표준 라이브러리를 바로 사용할 수 있다. JCL 자체도 여러 패키지로 모듈화되어 있으며, Java의 패키지(namespace) 체계를 통해 논리적으로 분류되어 있다. Java에서 표준 클래스 라이브러리는 언어 스펙의 일부로 간주되며, C나 Python의 표준 라이브러리처럼 광범위한 기능을 언어 차원에서 지원한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;6-2.&lt;span&gt;&amp;nbsp;&lt;/span&gt;표준 패키지 관리자&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;985&quot; data-origin-height=&quot;210&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PgVu1/btsPMUwJbK9/vr1bgkSJnNhNMkQpCycSe1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PgVu1/btsPMUwJbK9/vr1bgkSJnNhNMkQpCycSe1/img.png&quot; data-alt=&quot;[이미지16] Maven&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PgVu1/btsPMUwJbK9/vr1bgkSJnNhNMkQpCycSe1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPgVu1%2FbtsPMUwJbK9%2Fvr1bgkSJnNhNMkQpCycSe1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;985&quot; height=&quot;210&quot; data-origin-width=&quot;985&quot; data-origin-height=&quot;210&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지16] Maven&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;서드파티 Java 라이브러리는 일반적으로 JAR 파일을 배포 단위로 하며, Maven 중앙 저장소 등을 통해 관리된다. 빌드 도구(Maven, Gradle 등)를 사용하면 의존성으로 선언한 라이브러리 JAR들을 자동으로 다운로드하여 클래스패스에 추가해준다. Java의 라이브러리는 동적으로 JVM에 로드되므로, 버전 호환성이나 클래스 로딩 이슈가 발생할 수 있어, 빌드 도구를 통한 관리가 중요하다. Java 생태계에는 다양한 분야의 라이브러리가 존재하며, 특히 Apache 재단이나 스프링(Spring), 구글(Google) 등에서 제공하는 유명 라이브러리들이 많다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;6-3. 라이브러리&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 170px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 31.8605%; height: 17px;&quot;&gt;카테고리&lt;/td&gt;
&lt;td style=&quot;width: 68.1395%; height: 17px;&quot;&gt;라이브러리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 31.8605%; height: 17px;&quot;&gt;코어&amp;nbsp;런타임&amp;middot;공통&amp;nbsp;유틸&lt;/td&gt;
&lt;td style=&quot;width: 68.1395%; height: 17px;&quot;&gt;Guava,&amp;nbsp;Apache&amp;nbsp;Commons&amp;nbsp;{Lang,&amp;nbsp;IO,&amp;nbsp;Collections,&amp;nbsp;Text,&amp;nbsp;Math,&amp;nbsp;Compress,&amp;nbsp;Codec},&amp;nbsp;Eclipse&amp;nbsp;Collections,&amp;nbsp;FastUtil,&amp;nbsp;Vavr,&amp;nbsp;lombok,&amp;nbsp;JCTools,&amp;nbsp;Agrona,&amp;nbsp;HdrHistogram,&amp;nbsp;ClassGraph,&amp;nbsp;reflections,&amp;nbsp;Objenesis,&amp;nbsp;Javapoet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 31.8605%; height: 17px;&quot;&gt;빌드&amp;middot;패키징&amp;middot;플러그인&lt;/td&gt;
&lt;td style=&quot;width: 68.1395%; height: 17px;&quot;&gt;Maven,&amp;nbsp;Gradle,&amp;nbsp;Ant,&amp;nbsp;Ivy,&amp;nbsp;Maven&amp;nbsp;Plugin&amp;nbsp;{Compiler,&amp;nbsp;Shade,&amp;nbsp;Surefire,&amp;nbsp;Enforcer,&amp;nbsp;Versions,&amp;nbsp;Javadoc,&amp;nbsp;Spotbugs},&amp;nbsp;ProGuard,&amp;nbsp;JReleaser,&amp;nbsp;JBang,&amp;nbsp;jib,&amp;nbsp;build-buddy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 31.8605%; height: 17px;&quot;&gt;DI&amp;middot;애플리케이션&amp;nbsp;프레임워크&lt;/td&gt;
&lt;td style=&quot;width: 68.1395%; height: 17px;&quot;&gt;Spring&amp;nbsp;Framework/Boot,&amp;nbsp;Jakarta&amp;nbsp;CDI,&amp;nbsp;Guice,&amp;nbsp;Dagger2,&amp;nbsp;Micronaut,&amp;nbsp;Quarkus,&amp;nbsp;Helidon,&amp;nbsp;PicoContainer,&amp;nbsp;HK2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 31.8605%; height: 17px;&quot;&gt;웹&amp;middot;HTTP&amp;nbsp;서버&lt;/td&gt;
&lt;td style=&quot;width: 68.1395%; height: 17px;&quot;&gt;Spring&amp;nbsp;MVC,&amp;nbsp;Spring&amp;nbsp;WebFlux,&amp;nbsp;Jakarta&amp;nbsp;Servlet,&amp;nbsp;JAX-RS&amp;nbsp;{Jersey,&amp;nbsp;RESTEasy},&amp;nbsp;Vert.x‐Web,&amp;nbsp;Undertow,&amp;nbsp;Netty-HTTP,&amp;nbsp;Jetty,&amp;nbsp;Tomcat-Embed,&amp;nbsp;Dropwizard,&amp;nbsp;Ratpack,&amp;nbsp;Javalin,&amp;nbsp;SparkJava,&amp;nbsp;Vaadin,&amp;nbsp;Wicket,&amp;nbsp;JSF&amp;nbsp;{Mojarra,&amp;nbsp;PrimeFaces},&amp;nbsp;gRPC-Java,&amp;nbsp;RSocket-Java&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 31.8605%; height: 17px;&quot;&gt;Reactive&amp;nbsp;/&amp;nbsp;Actor&amp;nbsp;/&amp;nbsp;이벤트루프&lt;/td&gt;
&lt;td style=&quot;width: 68.1395%; height: 17px;&quot;&gt;Project&amp;nbsp;Reactor,&amp;nbsp;RxJava3,&amp;nbsp;Akka&amp;nbsp;{Actor,&amp;nbsp;Stream,&amp;nbsp;HTTP},&amp;nbsp;Mutiny,&amp;nbsp;vertx-reactive,&amp;nbsp;LMAX&amp;nbsp;Disruptor,&amp;nbsp;Aeron,&amp;nbsp;Chronicle-Queue&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 31.8605%; height: 17px;&quot;&gt;HTTP/REST&amp;nbsp;클라이언트&lt;/td&gt;
&lt;td style=&quot;width: 68.1395%; height: 17px;&quot;&gt;JDK&amp;nbsp;HttpClient,&amp;nbsp;OkHttp,&amp;nbsp;Apache&amp;nbsp;HttpClient5,&amp;nbsp;Retrofit2,&amp;nbsp;OpenFeign,&amp;nbsp;RESTEasy-Client,&amp;nbsp;WebClient(Spring),&amp;nbsp;Vert.x-WebClient,&amp;nbsp;Fuel,&amp;nbsp;Ktor-Client(JVM)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 31.8605%; height: 17px;&quot;&gt;직렬화&amp;middot;데이터&amp;nbsp;바인딩&lt;/td&gt;
&lt;td style=&quot;width: 68.1395%; height: 17px;&quot;&gt;Jackson&amp;nbsp;{Databind,&amp;nbsp;Kotlin,&amp;nbsp;XML,&amp;nbsp;CBOR,&amp;nbsp;Smile,&amp;nbsp;CSV},&amp;nbsp;Gson,&amp;nbsp;Moshi,&amp;nbsp;Json-B(Yasson),&amp;nbsp;Jsoniter,&amp;nbsp;Fastjson2,&amp;nbsp;SnakeYAML,&amp;nbsp;snakeyaml-engine,&amp;nbsp;Protobuf-Java,&amp;nbsp;gRPC-Stub,&amp;nbsp;Apache&amp;nbsp;Avro,&amp;nbsp;Thrift,&amp;nbsp;Kryo,&amp;nbsp;MessagePack-Java,&amp;nbsp;FlatBuffers,&amp;nbsp;BSON4Jackson,&amp;nbsp;CBOR-Jackson,&amp;nbsp;Smile,&amp;nbsp;Ion-Java&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 31.8605%; height: 17px;&quot;&gt;로깅&amp;middot;추적&lt;/td&gt;
&lt;td style=&quot;width: 68.1395%; height: 17px;&quot;&gt;SLF4J&amp;nbsp;API,&amp;nbsp;Logback-classic,&amp;nbsp;Log4j2,&amp;nbsp;tinylog2,&amp;nbsp;logbook,&amp;nbsp;Java-Util-Logging(JSR-47),&amp;nbsp;java-util-logging-bridge,&amp;nbsp;Logstash-Logback-Encoder,&amp;nbsp;Brave,&amp;nbsp;OpenTelemetry-API/SDK&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 31.8605%; height: 17px;&quot;&gt;데이터베이스&amp;middot;ORM&amp;middot;마이그레이션&lt;/td&gt;
&lt;td style=&quot;width: 68.1395%; height: 17px;&quot;&gt;JDBC,&amp;nbsp;Hibernate&amp;nbsp;ORM/JPA,&amp;nbsp;EclipseLink,&amp;nbsp;MyBatis3,&amp;nbsp;Spring&amp;nbsp;Data&amp;nbsp;{JPA,&amp;nbsp;JDBC,&amp;nbsp;Mongo,&amp;nbsp;R2DBC,&amp;nbsp;Redis},&amp;nbsp;JOOQ,&amp;nbsp;QueryDSL,&amp;nbsp;Exposed,&amp;nbsp;Blaze-Persistence,&amp;nbsp;HikariCP,&amp;nbsp;BoneCP,&amp;nbsp;Flyway,&amp;nbsp;Liquibase,&amp;nbsp;SchemaCrawler&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.8605%;&quot;&gt;NoSQL&amp;middot;KV&lt;/td&gt;
&lt;td style=&quot;width: 68.1395%;&quot;&gt;MongoDB-Driver,&amp;nbsp;Lettuce,&amp;nbsp;Jedis,&amp;nbsp;Cassandra&amp;nbsp;DataStax&amp;nbsp;Driver,&amp;nbsp;Neo4j-OGM,&amp;nbsp;Elasticsearch-HLRC,&amp;nbsp;Couchbase-SDK,&amp;nbsp;InfluxDB-Client,&amp;nbsp;DynamoDB-Enhanced&amp;nbsp;(AWS&amp;nbsp;SDK&amp;nbsp;v2),&amp;nbsp;RocksDB-JNI,&amp;nbsp;MapDB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.8605%;&quot;&gt;캐시&amp;middot;인메모리&amp;nbsp;데이터&lt;/td&gt;
&lt;td style=&quot;width: 68.1395%;&quot;&gt;Caffeine,&amp;nbsp;Ehcache3,&amp;nbsp;Hazelcast&amp;nbsp;IMDG,&amp;nbsp;Infinispan,&amp;nbsp;Apache&amp;nbsp;Ignite,&amp;nbsp;Redisson,&amp;nbsp;Chronicle-Map,&amp;nbsp;Terracotta,&amp;nbsp;JCache(JSR-107)&amp;nbsp;API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.8605%;&quot;&gt;메시징&amp;middot;통합&lt;/td&gt;
&lt;td style=&quot;width: 68.1395%;&quot;&gt;Kafka&amp;nbsp;Client,&amp;nbsp;Kafka&amp;nbsp;Streams,&amp;nbsp;RabbitMQ&amp;nbsp;Java&amp;nbsp;Client,&amp;nbsp;Pulsar&amp;nbsp;Client,&amp;nbsp;ActiveMQ&amp;nbsp;Artemis,&amp;nbsp;JMS&amp;nbsp;2.0,&amp;nbsp;Apache&amp;nbsp;Camel,&amp;nbsp;Spring&amp;nbsp;Integration,&amp;nbsp;Spring&amp;nbsp;Cloud&amp;nbsp;Stream,&amp;nbsp;gRPC,&amp;nbsp;RSocket&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.8605%;&quot;&gt;분산&amp;middot;마이크로서비스&amp;nbsp;지원&lt;/td&gt;
&lt;td style=&quot;width: 68.1395%;&quot;&gt;Spring Cloud {Config, Gateway, Netflix, Sleuth}, Netflix {Eureka, Zuul 2}, Resilience4j, Ribbon, Hystrix, Kubernetes-Client(fabric8), Istio-Client, Consul-Client, OpenFeign, Micrometer, Prometheus-Client, Zipkin, Jaeger&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.8605%;&quot;&gt;테스트&amp;middot;QA&amp;middot;모킹&lt;/td&gt;
&lt;td style=&quot;width: 68.1395%;&quot;&gt;JUnit&amp;nbsp;5,&amp;nbsp;TestNG,&amp;nbsp;AssertJ,&amp;nbsp;Mockito,&amp;nbsp;MockK,&amp;nbsp;EasyMock,&amp;nbsp;PowerMock,&amp;nbsp;REST-Assured,&amp;nbsp;WireMock,&amp;nbsp;Hoverfly-Java,&amp;nbsp;Testcontainers,&amp;nbsp;Awaitility,&amp;nbsp;Cucumber-JVM,&amp;nbsp;Spock,&amp;nbsp;ArchUnit,&amp;nbsp;JaCoCo,&amp;nbsp;Pitest,&amp;nbsp;SpotBugs,&amp;nbsp;Error-Prone,&amp;nbsp;PMD,&amp;nbsp;Checkstyle,&amp;nbsp;Revapi&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.8605%;&quot;&gt;쓰레딩&amp;middot;성능&amp;middot;동시성&lt;/td&gt;
&lt;td style=&quot;width: 68.1395%;&quot;&gt;java.util.concurrent,&amp;nbsp;CompletableFuture,&amp;nbsp;Project&amp;nbsp;Loom(Virtual&amp;nbsp;Threads),&amp;nbsp;Akka&amp;nbsp;Actor,&amp;nbsp;Netty,&amp;nbsp;ForkJoinPool,&amp;nbsp;disruptor,&amp;nbsp;Chronicle-Threads,&amp;nbsp;JMH,&amp;nbsp;jcstress,&amp;nbsp;async-profiler,&amp;nbsp;JFR&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.8605%;&quot;&gt;바이트코드&amp;middot;AOP&amp;middot;코드&amp;nbsp;생성&lt;/td&gt;
&lt;td style=&quot;width: 68.1395%;&quot;&gt;ASM,&amp;nbsp;Byte&amp;nbsp;Buddy,&amp;nbsp;Javassist,&amp;nbsp;cglib,&amp;nbsp;Spring&amp;nbsp;AOP,&amp;nbsp;AspectJ,&amp;nbsp;MapStruct,&amp;nbsp;AutoService,&amp;nbsp;AutoValue,&amp;nbsp;Immutables,&amp;nbsp;Lombok-Annotation-Processor,&amp;nbsp;Error-Prone-Checker,&amp;nbsp;Spoon&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.8605%;&quot;&gt;보안&amp;middot;암호화&amp;middot;인증&lt;/td&gt;
&lt;td style=&quot;width: 68.1395%;&quot;&gt;Bouncy&amp;nbsp;Castle,&amp;nbsp;Spring&amp;nbsp;Security&amp;nbsp;6,&amp;nbsp;Apache&amp;nbsp;Shiro,&amp;nbsp;JJWT,&amp;nbsp;jose4j,&amp;nbsp;Nimbus-JOSE-JWT,&amp;nbsp;Google&amp;nbsp;Tink-Java,&amp;nbsp;Keycloak-Adapters,&amp;nbsp;ScribeJava(OAuth),&amp;nbsp;Oshi(HW&amp;nbsp;info)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.8605%;&quot;&gt;모니터링&amp;middot;관찰가능성&lt;/td&gt;
&lt;td style=&quot;width: 68.1395%;&quot;&gt;Micrometer,&amp;nbsp;Dropwizard&amp;nbsp;Metrics,&amp;nbsp;Prometheus-Java,&amp;nbsp;OpenTelemetry-Java,&amp;nbsp;brave-instrumentation,&amp;nbsp;logging-to-Loki4j,&amp;nbsp;Grafana-client,&amp;nbsp;Elastic&amp;nbsp;APM,&amp;nbsp;Sentry-Java&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.8605%;&quot;&gt;빅데이터&amp;middot;스트림&amp;middot;배치&lt;/td&gt;
&lt;td style=&quot;width: 68.1395%;&quot;&gt;Apache&amp;nbsp;Hadoop&amp;nbsp;Client,&amp;nbsp;Spark-Core(Java&amp;nbsp;API),&amp;nbsp;Flink,&amp;nbsp;Beam&amp;nbsp;SDK-Java,&amp;nbsp;Samza,&amp;nbsp;Hazelcast&amp;nbsp;Jet,&amp;nbsp;Pulsar&amp;nbsp;Functions,&amp;nbsp;Storm,&amp;nbsp;Spring&amp;nbsp;Batch,&amp;nbsp;Quartz,&amp;nbsp;JobRunr&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.8605%;&quot;&gt;머신러닝&amp;middot;데이터사이언스&lt;/td&gt;
&lt;td style=&quot;width: 68.1395%;&quot;&gt;DeepLearning4J,&amp;nbsp;ND4J,&amp;nbsp;Tribuo,&amp;nbsp;Smile,&amp;nbsp;Mahout,&amp;nbsp;H2O-3,&amp;nbsp;XGBoost4J,&amp;nbsp;DJL(Deep&amp;nbsp;Java&amp;nbsp;Library),&amp;nbsp;Weka,&amp;nbsp;TensorFlow&amp;nbsp;Java,&amp;nbsp;JStatML,&amp;nbsp;Encog&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.8605%;&quot;&gt;검색&amp;middot;NLP&amp;middot;정보검색&lt;/td&gt;
&lt;td style=&quot;width: 68.1395%;&quot;&gt;Lucene,&amp;nbsp;SolrJ,&amp;nbsp;Elasticsearch&amp;nbsp;Client,&amp;nbsp;OpenNLP,&amp;nbsp;Stanford&amp;nbsp;CoreNLP,&amp;nbsp;LingPipe,&amp;nbsp;Deeplearning4j-NLP,&amp;nbsp;HanLP&amp;nbsp;-&amp;nbsp;Java,&amp;nbsp;Jieba-analysis,&amp;nbsp;Tika&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.8605%;&quot;&gt;GUI&amp;middot;그래픽&amp;middot;게임&lt;/td&gt;
&lt;td style=&quot;width: 68.1395%;&quot;&gt;JavaFX,&amp;nbsp;Swing,&amp;nbsp;SWT,&amp;nbsp;LWJGL&amp;nbsp;3,&amp;nbsp;LibGDX,&amp;nbsp;jMonkeyEngine,&amp;nbsp;Processing,&amp;nbsp;JOGL,&amp;nbsp;Ardor3D,&amp;nbsp;Scene&amp;nbsp;Builder,&amp;nbsp;MigLayout&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.8605%;&quot;&gt;Android&amp;nbsp;&amp;amp;&amp;nbsp;모바일&amp;nbsp;공용&lt;/td&gt;
&lt;td style=&quot;width: 68.1395%;&quot;&gt;AndroidX&amp;nbsp;Core&amp;nbsp;KTX,&amp;nbsp;AppCompat,&amp;nbsp;Material&amp;shy;Components,&amp;nbsp;Retrofit2-Converter-Gson,&amp;nbsp;Glide,&amp;nbsp;Coil-Compose,&amp;nbsp;Room,&amp;nbsp;Hilt-Android,&amp;nbsp;DataStore,&amp;nbsp;Jetpack&amp;nbsp;Compose,&amp;nbsp;RxJava3-Android,&amp;nbsp;OkHttp-Logging-Interceptor,&amp;nbsp;Lottie-Android&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.8605%;&quot;&gt;CLI&amp;middot;파싱&amp;middot;터미널&lt;/td&gt;
&lt;td style=&quot;width: 68.1395%;&quot;&gt;Picocli,&amp;nbsp;JCommander,&amp;nbsp;Commons&amp;nbsp;CLI,&amp;nbsp;args4j,&amp;nbsp;crayon,&amp;nbsp;Lanterna,&amp;nbsp;JLine3,&amp;nbsp;Konfetti,&amp;nbsp;Airframe-CLI,&amp;nbsp;Clikt4j&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.8605%;&quot;&gt;설정&amp;middot;검증&amp;middot;i18n&lt;/td&gt;
&lt;td style=&quot;width: 68.1395%;&quot;&gt;Typesafe&amp;nbsp;Config,&amp;nbsp;MicroProfile&amp;nbsp;Config,&amp;nbsp;Owner,&amp;nbsp;SmallRye&amp;nbsp;Config,&amp;nbsp;Spring&amp;nbsp;Boot&amp;nbsp;Config,&amp;nbsp;Hibernate&amp;nbsp;Validator,&amp;nbsp;Jakarta&amp;nbsp;Validation,&amp;nbsp;Valiktor,&amp;nbsp;ICU4J,&amp;nbsp;java-text-plural-rules&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.8605%;&quot;&gt;I/O&amp;middot;압축&amp;middot;파일&lt;/td&gt;
&lt;td style=&quot;width: 68.1395%;&quot;&gt;java.nio.*,&amp;nbsp;Netty-Transport,&amp;nbsp;Apache&amp;nbsp;Commons&amp;nbsp;IO,&amp;nbsp;Okio,&amp;nbsp;Zero-Copy-FileChannel,&amp;nbsp;Commons&amp;nbsp;Compress,&amp;nbsp;LZ4-Java,&amp;nbsp;zstd-jni,&amp;nbsp;Snappy-Java,&amp;nbsp;JTar,&amp;nbsp;TrueZIP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 31.8605%;&quot;&gt;문서&amp;middot;오피스&amp;middot;PDF&lt;/td&gt;
&lt;td style=&quot;width: 68.1395%;&quot;&gt;Apache&amp;nbsp;POI,&amp;nbsp;iText&amp;nbsp;7,&amp;nbsp;PDFBox,&amp;nbsp;OpenPDF,&amp;nbsp;Flying&amp;nbsp;Saucer,&amp;nbsp;Docx4j,&amp;nbsp;XDocReport,&amp;nbsp;JasperReports,&amp;nbsp;OpenCSV,&amp;nbsp;Univocity-Parsers,&amp;nbsp;Apache&amp;nbsp;FOP,&amp;nbsp;Aspose&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;7. 참고 문헌&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[1] Library (computing), &lt;a href=&quot;https://en.wikipedia.org/wiki/Library_(computing)&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://en.wikipedia.org/wiki/Library_(computing)&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[2] 오픈소스SW 라이선스 종합정보시스템, &lt;a href=&quot;https://olis.or.kr/license/introduction.do&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://olis.or.kr/license/introduction.do&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[3] vcpkg, &lt;a href=&quot;https://vcpkg.io/en/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://vcpkg.io/en/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[4] conan, &lt;a href=&quot;https://conan.io/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://conan.io/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[5] PyPI, &lt;a href=&quot;https://pypi.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://pypi.org/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[6] Maven Central, &lt;a href=&quot;https://central.sonatype.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://central.sonatype.com/&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Reversing/Definition</category>
      <category>library</category>
      <category>라이브러리</category>
      <author>kj0on</author>
      <guid isPermaLink="true">https://kj0on.tistory.com/49</guid>
      <comments>https://kj0on.tistory.com/49#entry49comment</comments>
      <pubDate>Thu, 24 Jul 2025 14:48:20 +0900</pubDate>
    </item>
    <item>
      <title>[Definition] x64 ABI</title>
      <link>https://kj0on.tistory.com/47</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 정의&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ABI (Application Binary Interface)는 어플리케이션과 운영체제 또는 컴파일된 코드 간의 상호작용 방식을 정의한 이진 수준의 규약이다. 쉽게 말해, 컴파일된 바이너리들이 서로 호환되도록 하는 규칙 모음을 뜻한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;2. x64 ABI&lt;/h2&gt;
&lt;table style=&quot;color: #333333; text-align: start; border-collapse: collapse; width: 100%; height: 414px;&quot; border=&quot;1&quot; data-ke-style=&quot;style12&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;background-color: #9b9b9b; color: #ffffff; width: 20.814%; height: 22px;&quot;&gt;규칙&lt;/td&gt;
&lt;td style=&quot;background-color: #9b9b9b; color: #ffffff; width: 20.3489%; height: 22px;&quot;&gt;역할&lt;/td&gt;
&lt;td style=&quot;background-color: #9b9b9b; color: #ffffff; width: 37.0928%; height: 22px;&quot;&gt;필수 규칙(ABI)&lt;/td&gt;
&lt;td style=&quot;background-color: #9b9b9b; color: #ffffff; width: 21.628%; height: 22px;&quot;&gt;조건부 규칙&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 66px;&quot;&gt;
&lt;td style=&quot;background-color: #efefef; width: 20.814%; height: 66px;&quot;&gt;스택 정렬 규칙&lt;/td&gt;
&lt;td style=&quot;width: 20.3489%; height: 66px;&quot;&gt;Alignment&lt;br /&gt;(정렬)&lt;/td&gt;
&lt;td style=&quot;width: 37.0928%; height: 66px;&quot;&gt;프롤로그, 에필로그을 제외한 모든 구간에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;RSP&amp;nbsp;&amp;equiv;&amp;nbsp;0&amp;nbsp;(mod&amp;nbsp;16)을 유지해야 한다.&lt;/td&gt;
&lt;td style=&quot;width: 21.628%; height: 66px;&quot;&gt;Leaf 함수는 정렬을 다시 맞출 필요가 없다.&lt;br /&gt;&lt;br /&gt;이후의 단계에서 정렬이 보장되어 있는 경우는 제한적으로 정렬을 유지하지 않아도 된다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 88px;&quot;&gt;
&lt;td style=&quot;background-color: #efefef; width: 20.814%; height: 88px;&quot;&gt;섀도우&amp;nbsp;스페이스&amp;nbsp;규칙&lt;/td&gt;
&lt;td style=&quot;background-color: #f9f9f9; width: 20.3489%; height: 88px;&quot;&gt;&lt;span style=&quot;background-color: #f9f9f9; color: #333333; text-align: start;&quot;&gt;Call Setup&lt;/span&gt;&lt;br /&gt;(호출 준비)&lt;/td&gt;
&lt;td style=&quot;background-color: #f9f9f9; width: 37.0928%; height: 88px;&quot;&gt;Caller(호출자)는 언제나 32byte Shadow Space를 확보한 상태에서 함수를 호출해야 한다. Callee(피호출자)는 해당영역을 자유롭게 덮어써도 무방하다.&lt;/td&gt;
&lt;td style=&quot;background-color: #f9f9f9; width: 21.628%; height: 88px;&quot;&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 84px;&quot;&gt;
&lt;td style=&quot;background-color: #efefef; width: 20.814%; height: 84px;&quot;&gt;레지스터&amp;nbsp;보존&amp;nbsp;규칙&lt;/td&gt;
&lt;td style=&quot;width: 20.3489%; height: 84px;&quot;&gt;Register Save&lt;br /&gt;(레지스터 보존)&lt;/td&gt;
&lt;td style=&quot;width: 37.0928%; height: 84px;&quot;&gt;Callee(피호출자)에서 비휘발성 레지스터를 사용했다면 함수 내부에서 원래 값으로 복구해야 한다.&lt;/td&gt;
&lt;td style=&quot;width: 21.628%; height: 84px;&quot;&gt;비휘발성&amp;nbsp;레지스터를&amp;nbsp;사용하지&amp;nbsp;않았다면&amp;nbsp;저장,&amp;nbsp;복구&amp;nbsp;코드가&amp;nbsp;없어도&amp;nbsp;된다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 88px;&quot;&gt;
&lt;td style=&quot;background-color: #efefef; width: 20.814%; height: 88px;&quot;&gt;언와인드 데이터 규칙&lt;/td&gt;
&lt;td style=&quot;background-color: #f9f9f9; width: 20.3489%; height: 88px;&quot;&gt;Unwind Info&lt;br /&gt;&lt;span style=&quot;background-color: #f9f9f9; color: #333333; text-align: start;&quot;&gt;(예외 복구&lt;/span&gt;)&lt;/td&gt;
&lt;td style=&quot;background-color: #f9f9f9; width: 37.0928%; height: 88px;&quot;&gt;스택,&amp;nbsp;콜,&amp;nbsp;예외,&amp;nbsp;로컬변수를&amp;nbsp;사용하는&amp;nbsp;모든&amp;nbsp;프레임&amp;nbsp;함수는&amp;nbsp;RUNTIME_FUNCTION&amp;nbsp;+&amp;nbsp;UNWIND_INFO을&amp;nbsp;기록해야&amp;nbsp;한다.&lt;/td&gt;
&lt;td style=&quot;background-color: #f9f9f9; width: 21.628%; height: 88px;&quot;&gt;Leaf 함수는 생략 가능하다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 66px;&quot;&gt;
&lt;td style=&quot;background-color: #efefef; width: 20.814%; height: 66px;&quot;&gt;함수 호출 규약&lt;/td&gt;
&lt;td style=&quot;background-color: #f9f9f9; width: 20.3489%; height: 66px;&quot;&gt;&lt;span style=&quot;background-color: #f9f9f9; color: #333333; text-align: start;&quot;&gt;Parameter&amp;nbsp;Passing&lt;/span&gt; &lt;br /&gt;(인자 전달)&lt;/td&gt;
&lt;td style=&quot;background-color: #f9f9f9; width: 37.0928%; height: 66px;&quot;&gt;첫&amp;nbsp;4개의&amp;nbsp;정수형&amp;nbsp;인자는&amp;nbsp;RCX,&amp;nbsp;RDX,&amp;nbsp;R8,&amp;nbsp;R9에,&amp;nbsp;부동소수점&amp;nbsp;인자는&amp;nbsp;XMM0&amp;ndash;3에&amp;nbsp;전달한다.&lt;/td&gt;
&lt;td style=&quot;background-color: #f9f9f9; width: 21.628%; height: 66px;&quot;&gt;5번째 이후의 인자는 스택에 저장된다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;3. 스택 정렬 규칙&lt;/h2&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정렬&lt;br /&gt;대부분의 구조체는 자연 정렬에 맞춰 정렬됩니다. 기본 예외는 스택 포인터와&amp;nbsp;malloc&amp;nbsp;또는&amp;nbsp;alloca&amp;nbsp;메모리로, 성능을 지원하기 위해 16바이트로 맞춥니다. 16바이트 이상의 맞춤은 수동으로 수행해야 합니다. 16바이트는 XMM 작업의 일반적인 맞춤 크기이므로 대부분의 코드에서 이 값이 유효합니다. 구조체 레이아웃 및 맞춤에 대한 자세한 내용은 x64 형식 및 스토리지 레이아웃을 참조&amp;nbsp;하세요. 스택 레이아웃에 대한 자세한 내용은&amp;nbsp;x64 스택 사용을 참조하세요.&lt;br /&gt;&lt;br /&gt;스택은 항상 16바이트 맞춤 상태로 유지되지만, 반환 주소가 푸시된 후와 같이 프롤로그 내부에서 지정된 경우와&amp;nbsp;&lt;br /&gt;함수 형식에 특정 프레임 함수 클래스용으로 표시된 경우는 예외입니다.&lt;/blockquote&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;스택 정렬은 스택 포인터가 가리키는 주소(RSP)가 특정 배수로 맞춰져 있어야 한다는 규칙이다. Windows x64 ABI에서는 함수 프롤로그, 에필로그를 벗어난 모든 지점에서 RSP &amp;equiv; 0 (mod 16)이 의무사항이고, 리프(Leaf) 함수만 예외적으로 이 요구를 다시 충족하지 않아도 된다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;XMM_registers.png&quot; data-origin-width=&quot;330&quot; data-origin-height=&quot;330&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b15gAN/btsPsUa96Kw/UhIHf1dYjG5JhrkLoGspc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b15gAN/btsPsUa96Kw/UhIHf1dYjG5JhrkLoGspc0/img.png&quot; data-alt=&quot;[이미지1] XMM (https://en.wikipedia.org/wiki/Streaming_SIMD_Extensions)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b15gAN/btsPsUa96Kw/UhIHf1dYjG5JhrkLoGspc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb15gAN%2FbtsPsUa96Kw%2FUhIHf1dYjG5JhrkLoGspc0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;330&quot; height=&quot;330&quot; data-filename=&quot;XMM_registers.png&quot; data-origin-width=&quot;330&quot; data-origin-height=&quot;330&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지1] XMM (https://en.wikipedia.org/wiki/Streaming_SIMD_Extensions)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;스택 정렬 규칙에 따르면 XMM 작업의 일반적인 맞춤 크기 때문에 128bit(16byte)에 해당하는 정렬을 사용한다고 명시되어 있다. 그런데 32bit 환경의 __vectorcall 역시 XMM 레지스터를 사용하지만, x86 ABI가 보장하는 스택 정렬은 최소 4byte에 불과하다. 반면 64bit ABI는 함수 바디 구간에서 RSP &amp;equiv; 0 (mod 16)을 강제해 16byte 정렬을 반드시 지키게 한다. 64비트도 32비트와 마찬가지로 한 번에 처리할 수 있는 크기를 생각해 본다면 64bit(8byte) 정렬을 따르는 것이 꽤나 일반적으로 보인다. 그런데 왜 64bit(8byte) 정렬이 아닌 128bit(16byte) 정렬을 따라야 하는 것일까? 이는 단순한 연산 단위 때문이 아니라, SIMD 명령어의 정렬 요구사항과 향후 AVX 확장까지 고려한 플랫폼 수준의 정렬 정책 때문이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 13.7209%;&quot;&gt;명령어&lt;/td&gt;
&lt;td style=&quot;width: 24.5349%;&quot;&gt;약어&amp;nbsp;의미&lt;/td&gt;
&lt;td style=&quot;width: 16.8605%;&quot;&gt;전송&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 24.8837%;&quot;&gt;정렬 제약&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;사용 이유&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 13.7209%;&quot;&gt;MOVAPS/&lt;br /&gt;MOVAPD&lt;/td&gt;
&lt;td style=&quot;width: 24.5349%;&quot;&gt;Aligned Packed Single/&lt;br /&gt;Aligned&amp;nbsp;Packed&amp;nbsp;Double&lt;/td&gt;
&lt;td style=&quot;width: 16.8605%;&quot;&gt;128bit(16byte)&lt;/td&gt;
&lt;td style=&quot;width: 24.8837%;&quot;&gt;128bit(16byte) 정렬 필수, 어기면 #GP 발생&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;정렬된&amp;nbsp;SIMD&amp;nbsp;데이터&amp;nbsp;고속&amp;nbsp;처리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 13.7209%;&quot;&gt;MOVUPS/&lt;br /&gt;MOVUPD&lt;/td&gt;
&lt;td style=&quot;width: 24.5349%;&quot;&gt;Unaligned Packed Single/&lt;br /&gt;Unaligned Packed Double&lt;/td&gt;
&lt;td style=&quot;width: 16.8605%;&quot;&gt;128bit(16byte)&lt;/td&gt;
&lt;td style=&quot;width: 24.8837%;&quot;&gt;정렬&amp;nbsp;불필요&amp;nbsp;(임의&amp;nbsp;주소&amp;nbsp;허용)&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;정렬&amp;nbsp;보장&amp;nbsp;없는&amp;nbsp;메모리&amp;nbsp;접근&amp;nbsp;시&amp;nbsp;사용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 13.7209%;&quot;&gt;MOVSS/&lt;br /&gt;MOVSD&lt;/td&gt;
&lt;td style=&quot;width: 24.5349%;&quot;&gt;Scalar Single/&lt;br /&gt;Scalar&amp;nbsp;Double&lt;/td&gt;
&lt;td style=&quot;width: 16.8605%;&quot;&gt;32bit(4byte)/&lt;br /&gt;64bit(8byte)&lt;/td&gt;
&lt;td style=&quot;width: 24.8837%;&quot;&gt;32bit(4byte) 정렬 권장/&lt;br /&gt;64bit(8byte)&amp;nbsp;정렬&amp;nbsp;권장&lt;/td&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;단일 float 값 로드, 저장/&lt;br /&gt;단일 double 값 로드, 저장&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;914&quot; data-origin-height=&quot;199&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bCOjgS/btsPr5ZfScY/YADOYeuwp906u6KfGjLRok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bCOjgS/btsPr5ZfScY/YADOYeuwp906u6KfGjLRok/img.png&quot; data-alt=&quot;[이미지2] Pentium III Instruction Table&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bCOjgS/btsPr5ZfScY/YADOYeuwp906u6KfGjLRok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbCOjgS%2FbtsPr5ZfScY%2FYADOYeuwp906u6KfGjLRok%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;914&quot; height=&quot;199&quot; data-origin-width=&quot;914&quot; data-origin-height=&quot;199&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지2] Pentium III Instruction Table&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;역사적으로 MOVUP 명령어는 정렬된 주소에서도 상대적으로 느린 동작을 보였으며, 이는 같은 128bit&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;(16byte)&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;크기의 데이터를 처리하는 MOVAP 명령어가 메모리와 XMM 레지스터 간의 데이터 전송을 한 번에 수행할 수 있었기 때문이다. MOVAP는 메모리 주소가 128bit(16byte) 경계에 정렬되어 있는 경우에만 빠르게 동작하며, 그렇지 않으면 #GP(General Protection) 예외를 발생시킨다. 이에 반해 MOVUP는 정렬을 보장할 수 없는 상황에서 안정성을 확보하기 위해 사용되었으나, 초기 x86 SSE 지원 CPU에서는 내부적으로 정렬 여부를 매번 확인해야 했고, 이로 인해 명령어 자체가 느릴 수밖에 없었다. 따라서 성능 측면에서 보면 조건 분기를 넣어 정렬 여부를 검사하느니, 애초에 데이터 구조를 16byte 단위로 정렬하여 MOVAPS 같은 정렬 기반 명령어를 사용하는 것이 더 효율적이고 단순한 방식으로 여겨졌다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;따라서 CPU가 예외 없이 빠르게 SIMD 명령어를 처리하도록 ABI 차원에서 성능을 이유로 16byte 정렬 규칙이 도입되었다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;907&quot; data-origin-height=&quot;387&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bx7mOG/btsPtopN7H4/zhzsp4UyOKMXCASrvybDA1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bx7mOG/btsPtopN7H4/zhzsp4UyOKMXCASrvybDA1/img.png&quot; data-alt=&quot;[이미지3] Haswell Instruction Table&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bx7mOG/btsPtopN7H4/zhzsp4UyOKMXCASrvybDA1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbx7mOG%2FbtsPtopN7H4%2Fzhzsp4UyOKMXCASrvybDA1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;907&quot; height=&quot;387&quot; data-origin-width=&quot;907&quot; data-origin-height=&quot;387&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지3] Haswell Instruction Table&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Haswell 이후 부터 최근 CPU 마이크로아키텍처에서는 MOVAP와 MOVUPS 성능 차이가 거의 사라졌다. 하지만 여전히 일부 SIMD 명령어는 비정렬 접근 시 #GP 예외를 일으킨다. 결국, 현대 하드웨어에서 성능상의 정렬 요구 조건이 완화되었음에도 불구하고 16byte 정렬 규칙을 폐지할 수 없는 것은, 이와 같은 예외 상황을 방지하여 시스템의 안정성을 유지하고, 기존 소프트웨어와의 ABI 차원에서의 호환성을 지속적으로 보장하기 위한 것이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;869&quot; data-origin-height=&quot;288&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ckJRCG/btsPs5degSf/4eg2ArjXyMhnU3Eo7GbSB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ckJRCG/btsPs5degSf/4eg2ArjXyMhnU3Eo7GbSB0/img.png&quot; data-alt=&quot;[이미지4] call main&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ckJRCG/btsPs5degSf/4eg2ArjXyMhnU3Eo7GbSB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FckJRCG%2FbtsPs5degSf%2F4eg2ArjXyMhnU3Eo7GbSB0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;869&quot; height=&quot;288&quot; data-origin-width=&quot;869&quot; data-origin-height=&quot;288&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지4] call main&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;실제로 x64 ABI의 스택 정렬 규칙을 확인해 보면, 프로그램의 진입점인 main 함수 호출 직전에 이미 RSP 레지스터는 16바이트(0x10) 정렬 상태임을 관찰할 수 있다. 이는 함수 body에서 RSP &amp;equiv; 0 (mod 16)을 보장하는 플랫폼의 기본 규칙 때문으로, Caller(호출자)가 미리 정렬 상태를 준비해 두고 Callee(피호출자)는 이를 신뢰하고 바로 SIMD 연산 등을 수행할 수 있도록 설계된 것이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;869&quot; data-origin-height=&quot;287&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sfhie/btsPtAcJjmO/NF5itoq2GtHlxbuEk3ejuk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sfhie/btsPtAcJjmO/NF5itoq2GtHlxbuEk3ejuk/img.png&quot; data-alt=&quot;[이미지5] main&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sfhie/btsPtAcJjmO/NF5itoq2GtHlxbuEk3ejuk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fsfhie%2FbtsPtAcJjmO%2FNF5itoq2GtHlxbuEk3ejuk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;869&quot; height=&quot;287&quot; data-origin-width=&quot;869&quot; data-origin-height=&quot;287&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지5] main&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;최적화 수준 /O2를 적용한 main 함수에서는 Opt-Mid 패턴이 나타나는 것을 확인할 수 있다. 이때 sub rsp, 0x28 명령어가 등장하는데, 이는 main 함수 진입 전에 호출자가 call main을 수행하면서 실행된 push rip에 의해 RSP가 8byte 증가한 것을 보정하기 위한 것이다. 따라서 body 구간에서 다시 16byte 정렬를 맞추기 위해 이를 포함한 추가적인 0x8 보정이 필요해지며, 결과적으로 0x20에 8byte를 더한 0x28 만큼 RSP를 감소시키는 명령이 수행되는 것이다. 이 보정으로 인해 main함수의 body에서는 16byte 정렬이 일관되게 유지된다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;test.jpg&quot; data-origin-width=&quot;2868&quot; data-origin-height=&quot;3304&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bb234g/btsPuNbStXK/ard47FEXFCJsPCQ2ouXfqK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bb234g/btsPuNbStXK/ard47FEXFCJsPCQ2ouXfqK/img.jpg&quot; data-alt=&quot;[이미지6] test function&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bb234g/btsPuNbStXK/ard47FEXFCJsPCQ2ouXfqK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbb234g%2FbtsPuNbStXK%2Fard47FEXFCJsPCQ2ouXfqK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2868&quot; height=&quot;3304&quot; data-filename=&quot;test.jpg&quot; data-origin-width=&quot;2868&quot; data-origin-height=&quot;3304&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지6] test function&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;push 및 pop 명령어는 스택 포인터를 변경하므로, 스택 정렬 규칙을 위반할 수 있다. 따라서 x64 에서는 이러한 명령의 사용을 각각 함수의 프롤로그와 에필로그 구간으로 제한하고 있다. 이로 인해 함수 프롤로그가 끝나고 본격적인 body 구간이 시작되면 에필로그가 나타나기 전까지 스택 포인터는 고정된 값을 유지한다. 실제로 컴파일된 x64 코드를 분석해 보면 함수의 body에서 push나 pop 명령어가 나타나지 않는것을 확인할 수 있으며, 이는 정렬을 일관되게 유지하기 위한 설계적 특징으로 볼 수 있다. 결과적으로 프롤로그와 에필로그 사이에서 RSP는 전혀 변경되지 않는 것이 x64 함수의 중요한 특징 중 하나이다. 다만, 함수를 호출할 때와 같이 프롤로그 단계에서 정렬이 보장되어 있는 경우는 body 내부에서도 제한적으로 push를 사용할 수 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;4. 섀도우 스페이스 규칙&lt;/h2&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 175px;&quot; border=&quot;1&quot; data-ke-style=&quot;style12&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 31.9767%; height: 22px;&quot;&gt;용어&lt;/td&gt;
&lt;td style=&quot;width: 68.0233%; height: 22px;&quot;&gt;출처&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 31.9767%; height: 17px;&quot;&gt;Shadow Space&lt;/td&gt;
&lt;td style=&quot;width: 68.0233%; height: 17px;&quot;&gt;MSDN, LLVM, Intel, Wikipedia, Community&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 31.9767%; height: 17px;&quot;&gt;Shadow Store&lt;/td&gt;
&lt;td style=&quot;width: 68.0233%; height: 17px;&quot;&gt;MSDN, System V AMD64 ABI, StackOverflow, Reddit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 31.9767%; height: 17px;&quot;&gt;Shadow Area&lt;/td&gt;
&lt;td style=&quot;width: 68.0233%; height: 17px;&quot;&gt;LLVM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 31.9767%; height: 17px;&quot;&gt;Argument Homing Space&lt;/td&gt;
&lt;td style=&quot;width: 68.0233%; height: 17px;&quot;&gt;AMD&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 31.9767%; height: 17px;&quot;&gt;Prameter Homing Space&lt;/td&gt;
&lt;td style=&quot;width: 68.0233%; height: 17px;&quot;&gt;CodeMachine&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 31.9767%; height: 17px;&quot;&gt;Homing Space&lt;/td&gt;
&lt;td style=&quot;width: 68.0233%; height: 17px;&quot;&gt;CodeMachine&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 31.9767%; height: 17px;&quot;&gt;Home Space&lt;/td&gt;
&lt;td style=&quot;width: 68.0233%; height: 17px;&quot;&gt;Github, StackOverflow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 31.9767%; height: 17px;&quot;&gt;Spill Space&lt;/td&gt;
&lt;td style=&quot;width: 68.0233%; height: 17px;&quot;&gt;StackOverflow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 31.9767%; height: 17px;&quot;&gt;Spill&amp;nbsp;Slot&lt;/td&gt;
&lt;td style=&quot;width: 68.0233%; height: 17px;&quot;&gt;Blog&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;x64 Architecture에서 Caller(호출자)가 함수 호출 시 스택에 미리 할당하는 레지스터 저장 영역에 관하여 여러 문서와 커뮤니티에서 서로 다른 명칭을 사용하고 있어 이를 정리할 필요가 있다. MSDN, LLVM, Intel의 공식 문서와 Wikipedia 등 여러 문헌에서는 이 영역을 &quot;Shadow Space&quot;라는 용어로 기술하고 있으나, 일부 공식 문서나 비공식적인 커뮤니티 및 블로그에서는 다른 용어들이 사용되기도 한다. 따라서 나타난 사용 빈도와 공식 문서의 채택 여부를 고려했을 때, &quot;Shadow Space&quot;가 해당 영역을 지칭하는 가장 공식적인 용어라고 판단할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;shadow1.jpg&quot; data-origin-width=&quot;4400&quot; data-origin-height=&quot;2475&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OEolO/btsPuEtaSCQ/ZsjJhqSeB0Km5DjKfKUAY0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OEolO/btsPuEtaSCQ/ZsjJhqSeB0Km5DjKfKUAY0/img.jpg&quot; data-alt=&quot;[이미지7] Shadow Space&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OEolO/btsPuEtaSCQ/ZsjJhqSeB0Km5DjKfKUAY0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOEolO%2FbtsPuEtaSCQ%2FZsjJhqSeB0Km5DjKfKUAY0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4400&quot; height=&quot;2475&quot; data-filename=&quot;shadow1.jpg&quot; data-origin-width=&quot;4400&quot; data-origin-height=&quot;2475&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지7] Shadow Space&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Shadow Space는 Caller(호출자)가 함수를 호출하기 전에 RCX, RDX, R8, R9(또는 XMM0~XMM3) 레지스터를 저장해둘 수 있도록 예약하는 스택 상의 32byte 공간을 의미한다. 이 공간은 함수 인자 4개에 대응하는 레지스터 값을 Callee(피호출자) 함수 내부에서 백업하거나 참조할 수 있도록 보장하는 역할을 한다. 이 영역은 레지스터 인자가 4개가 아닌 경우(0~3)에도 반드시 32Byte 전체의 공간이 필요하다. 따라서 함수 호출 시, 호출자는 Shadow Space 영역을 고려해 스택의 영역을 0x20(32byte) 이상만큼 확보해야 한다. 이때, 스택 정렬 규칙에 따라 16byte 정렬을 유지해야 한다. (그 밑의 lea rbp, [rsp+50h]는 로컬 변수영역의 경계 역할을 하는 코드다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;shadow2.jpg&quot; data-origin-width=&quot;4400&quot; data-origin-height=&quot;2475&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cnxiYC/btsPvCOGODU/Rty9boXHktEnC0W6XTa5Tk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cnxiYC/btsPvCOGODU/Rty9boXHktEnC0W6XTa5Tk/img.jpg&quot; data-alt=&quot;[이미지8] Shadow Space&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cnxiYC/btsPvCOGODU/Rty9boXHktEnC0W6XTa5Tk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcnxiYC%2FbtsPvCOGODU%2FRty9boXHktEnC0W6XTa5Tk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4400&quot; height=&quot;2475&quot; data-filename=&quot;shadow2.jpg&quot; data-origin-width=&quot;4400&quot; data-origin-height=&quot;2475&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지8] Shadow Space&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수 호출 규약에 따라 RCX, RDX, R8, R9순으로 인자를 넣고 있다. 5번째 부터는 인자값을 스택으로 전달하고 있는데, 그 위치를 자세히 보면 [rsp+0x0]이 아닌 [rsp+0x20]으로, Shadow Space 영역을 피해서 값을 저장하는 것을 확인할 수 있다. 이는 Callee(피호출자)에서 Shadow Space 영역의 사용을 보장하기 위함이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;The called function effectively owns this space and can use it for any purpose, so the calling function cannot rely on its contents on return. Register parameters occupy the least significant ends of registers and shadow space must be allocated for four register parameters even if the called function doesn&amp;rsquo;t have this many parameters.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 공간은 호출 시점에서 Caller(호출자)가 확보하지만, 해당 영역은 Callee(피호출자)가 완전히 소유하는 것으로 간주되며, Callee(피호출자)는 이를 자유롭게 덮어쓰거나 임시 용도로 사용할 수 있다. 따라서 Caller(호출자)는 이 공간의 내용을 복귀 시점에서 신뢰하거나 재사용할 수 없기 때문에 함수 호출 전, 이 공간에 값을 저장하는 것은 무의미하다. 또한 Callee(피호출자)의 매개변수가 많지 않더라도(4미만), Caller(호출자)는 항상 이 32바이트의 Shadow Space를 확보해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;shadow3.jpg&quot; data-origin-width=&quot;4400&quot; data-origin-height=&quot;2475&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5ps2g/btsPvXd8qex/TD3CDKUFcQ2XQQ6lb2QXCK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5ps2g/btsPvXd8qex/TD3CDKUFcQ2XQQ6lb2QXCK/img.jpg&quot; data-alt=&quot;[이미지9] Shadow Space&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5ps2g/btsPvXd8qex/TD3CDKUFcQ2XQQ6lb2QXCK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5ps2g%2FbtsPvXd8qex%2FTD3CDKUFcQ2XQQ6lb2QXCK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4400&quot; height=&quot;2475&quot; data-filename=&quot;shadow3.jpg&quot; data-origin-width=&quot;4400&quot; data-origin-height=&quot;2475&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지9] Shadow Space&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;Callee(&lt;/span&gt;피호출자)는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;함수 내부에서 Shadow Space가 존재한다는 사실을 암묵적으로 신뢰하고, 별도 확인 작업 없이 자유롭게 덮어쓸 수 있어야 한다. 다만, 해당 공간을 홈 슬롯(Home Slot) 용도로만 사용하는 것이 아니라, 임시 변수 저장이나 기타 목적에도 활용할 수 있다. 주로 이 공간은 첫 네 개의 레지스터 인자 값을 메모리로 저장할 필요가 있을 때 사용되지만, 반드시 사용해야 하는 것은 아니며, 함수 최적화 수준이나 구현 방식에 따라 생략되기도 한다. 또한 이 공간이 인자 값을 저장하는 것 외에도 목적에 따라 다양한 방식으로 활용될 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 161px;&quot; border=&quot;1&quot; data-ke-style=&quot;style12&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 22px;&quot;&gt;구분&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 22px;&quot;&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 44px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 44px;&quot;&gt;가변 인자 함수&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 44px;&quot;&gt;매크로가 레지스터가 아니라 메모리 배열을 순회하기 때문에 레지스터 파라미터를 스택으로 옮겨 한 덩어리로 다룰 수 있게 한다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 44px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 44px;&quot;&gt;디버그(/Od)&amp;nbsp;빌드&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 44px;&quot;&gt;디버거, 크래시덤프에서 파라미터 값을 메모리에서 복구할 때 사용할 수 있으며 디버깅을 좀 더 용이하게 하기 위해 사용하기도 한다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;파라미터의&amp;nbsp;주소가&amp;nbsp;필요할&amp;nbsp;때&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;레지스터 값은 주소가 없으므로 해당 파라미터를 스택에 저장해 주소를 참조할 수 있게 한다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;함수를 호출하기 전에 해당 인자 값을 보존해야 할 때&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;함수 호출 뒤에도 값이 필요하면 임시 보관 장소로 사용한다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;언와인딩 메타데이터가 레지스터 값을 스택에 있었다고 가정 할 때&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;일부 컴파일러에서 예외 처리 복구용으로 필요하다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Shadow Space는 단순히 인자의 백업 공간에 그치지 않고, 함수의 특성이나 빌드 설정, 디버깅 지원, 예외 처리 등 다양한 상황에 따라 유연하게 활용되는 구조적 여유 공간이다. 정해진 용도만을 위한 고정된 공간이 아니라, 함수 내부의 요구에 따라 다목적으로 활용 가능한 공간으로 기능한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;shadowspace.jpg&quot; data-origin-width=&quot;4400&quot; data-origin-height=&quot;2475&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LGLGr/btsPAyNzqhx/kr9m0Ru8j4xePtCKJLuOw0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LGLGr/btsPAyNzqhx/kr9m0Ru8j4xePtCKJLuOw0/img.jpg&quot; data-alt=&quot;[이미지10] Shadow Space&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LGLGr/btsPAyNzqhx/kr9m0Ru8j4xePtCKJLuOw0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLGLGr%2FbtsPAyNzqhx%2Fkr9m0Ru8j4xePtCKJLuOw0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4400&quot; height=&quot;2475&quot; data-filename=&quot;shadowspace.jpg&quot; data-origin-width=&quot;4400&quot; data-origin-height=&quot;2475&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지10] Shadow Space&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Windows x64 ABI에서 Shadow Space는 사용 여부와 무관하게 Caller(호출자)가 반드시 32바이트를 확보해야 하는 구조적 요구사항이며, 이는 함수의 인자 개수나 함수 내부 구현과는 전혀 관련이 없다. 다시 말해, 이 공간이 실제로 쓰이든 쓰이지 않든 관계없이 함수를 호출하기 전에는 반드시 32byte를 확보해야 하는 것이 ABI 차원에서의 규칙이다. 이 규칙을 어기는 경우는 매우 제한적인 상황에 국한된다. 따라서 Shadow Space 관련 명령이 명시적으로 보이지 않더라도, 규칙상 항상 확보되어 있다고 보는 것이 원칙이며, 이는 함수가 이를 실제로 사용할지를 떠나 호출 시점에서 반드시 지켜져야 하는 전제 조건이다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. 레지스터 보존 규칙&lt;/h2&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;x64 호출 규칙&lt;br /&gt;&lt;br /&gt;x64 ABI는 레지스터 RAX, RCX, RDX, R8, R9, R10, R11 및 XMM0-XMM5를 휘발성으로 간주합니다. 있는 경우 YMM0-YMM15 및 ZMM0-ZMM15의 상위 부분도 휘발성입니다. AVX512VL에서 ZMM, YMM 및 XMM 레지스터 16-31도 휘발성입니다. AMX 지원이 있는 경우 TMM 타일 레지스터는 휘발성입니다. 전체 프로그램 최적화와 같은 분석으로 안전성을 입증할 수 없는 경우 휘발성 레지스터는 함수 호출 시 소멸된 것으로 간주합니다.&lt;br /&gt;&lt;br /&gt;x64 ABI는 레지스터 RBX, RBP, RDI, RSI, RSP, R12, R13, R14, R15 및 XMM6-XMM15를 비휘발성으로 간주합니다. 이들 레지스터는 그것들을 사용하는 함수에 의해 저장되고 복원되어야 합니다.&lt;br /&gt;&lt;br /&gt;x64 ABI 규칙 개요&lt;br /&gt;&lt;br /&gt;x64 아키텍처는 범용 레지스터 16개(이하 '정수 레지스터')와 부동 소수점용으로 사용 가능한 XMM/YMM 레지스터 16개를 제공합니다. 휘발성 레지스터는 호출자가 호출 중에 내용이 손실될 수 있는 것으로 가정하는 임시 저장소입니다. 함수 호출 중에 값을 유지하려면 비휘발성 레지스터가 필요합니다. 호출 수신자는 비휘발성 레지스터(사용하는 경우)를 저장해야 합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Windows x64 호출 규약을 정의하는 Microsoft의 문서에 따르면, x64 ABI는 레지스터를 휘발성(volatile)과 비휘발성(non-volatile)으로 구분하며, 이 구분은 함수 호출 시 레지스터의 값 보존 책임을 명확히 하기 위한 목적에서 도입되었다. 문서에 따르면, 휘발성 레지스터는 호출자가 호출 중에 손실될 수 있을 것으로 가정하고 있다. 즉, 휘발성 레지스터는 필요시 Caller(호출자)에 의해 저장 및 복원 해야한다. 함수 호출 중에 값을 유지하려면 비휘발성 레지스터가 필요하다고 하는데, 이 말은 비휘발 레지스터는 호출자가 호출 중 값을 유지할 수 있다는 것을 의미한다. 즉, 비휘발성 레지스터는 Callee(피호출자)에 의해 저장 및 복원되는 레지스터이며, 공식문서에서도 호출 수신자는(Callee) 비휘발성 레지스터(사용하는 경우)를 저장해야 한다고 명시하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;volatile.jpg&quot; data-origin-width=&quot;5786&quot; data-origin-height=&quot;1884&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bF0cb0/btsPzHdrlMM/yyiTKEo8eSfLJ2eRw5poY0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bF0cb0/btsPzHdrlMM/yyiTKEo8eSfLJ2eRw5poY0/img.jpg&quot; data-alt=&quot;[이미지11] 휘발성 레지스터 &amp;amp;amp; 비휘발성 레지스터&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bF0cb0/btsPzHdrlMM/yyiTKEo8eSfLJ2eRw5poY0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbF0cb0%2FbtsPzHdrlMM%2FyyiTKEo8eSfLJ2eRw5poY0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;5786&quot; height=&quot;1884&quot; data-filename=&quot;volatile.jpg&quot; data-origin-width=&quot;5786&quot; data-origin-height=&quot;1884&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지11] 휘발성 레지스터 &amp;amp; 비휘발성 레지스터&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 110px;&quot; border=&quot;1&quot; data-ke-style=&quot;style12&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 31.2403%; height: 22px;&quot;&gt;분류&lt;/td&gt;
&lt;td style=&quot;width: 18.6821%; height: 22px;&quot;&gt;보존&amp;nbsp;책임&lt;/td&gt;
&lt;td style=&quot;width: 50.0775%; height: 22px;&quot;&gt;의미&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 44px;&quot;&gt;
&lt;td style=&quot;width: 31.2403%; height: 44px;&quot;&gt;휘발성 레지스터 (Volatile)&lt;/td&gt;
&lt;td style=&quot;width: 18.6821%; height: 44px;&quot;&gt;Caller-Saved&lt;/td&gt;
&lt;td style=&quot;width: 50.0775%; height: 44px;&quot;&gt;호출 직후 값이 보존된다고 기대할 수 없다. 필요하면 호출자가 따로 저장해야 한다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 44px;&quot;&gt;
&lt;td style=&quot;width: 31.2403%; height: 44px;&quot;&gt;비휘발성 레지스터 (non-Volatile)&lt;/td&gt;
&lt;td style=&quot;width: 18.6821%; height: 44px;&quot;&gt;Callee-Saved&lt;/td&gt;
&lt;td style=&quot;width: 50.0775%; height: 44px;&quot;&gt;호출&amp;nbsp;전,&amp;nbsp;후의&amp;nbsp;값이&amp;nbsp;같아야&amp;nbsp;한다.&amp;nbsp;피호출자가&amp;nbsp;해당&amp;nbsp;레지스터를&amp;nbsp;쓰면&amp;nbsp;반드시&amp;nbsp;원래&amp;nbsp;값으로&amp;nbsp;복구해야&amp;nbsp;한다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;휘발성(volatile), 비휘발성(non-volatile)는 레지스터 자체의 물리적인(하드웨어) 특성이 아닌, Caller(호출자)의 시점에서 바라본 레지스터의 특성이다. Caller(호출자) 입장에서는 휘발성 레지스터는 Callee(피호출자)가 보존해 주지 않기 때문에 호출 시점에서 값이 변경(휘발성) 될 수 있다고 보는것이다. 반대로 비휘발성 레지스터는 Callee(피호출자)가 함수 내부에서 직접 보존하기 때문에 호출 시점에 값이 변경되지 않는(비휘발성)것으로 판단할 수 있다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 66px;&quot; border=&quot;1&quot; data-ke-style=&quot;style12&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 19.7673%; height: 22px;&quot;&gt;구분&lt;/td&gt;
&lt;td style=&quot;width: 80.2327%; height: 22px;&quot;&gt;레지스터&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 19.7673%; height: 22px;&quot;&gt;휘발성 레지스터&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;width: 80.2327%; height: 22px;&quot;&gt;RAX, RCX, RDX, R8, R9, R10, R11, XMM0-XMM5, YMM0-YMM5, ZMM0-ZMM5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 19.7673%; height: 22px;&quot;&gt;비휘발성 레지스터&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;width: 80.2327%; height: 22px;&quot;&gt;RBX, RBP, RDI, RSI, RSP, R12, R13, R14, R15, XMM6-XMM15, YMM6-YMM15, ZMM6-ZMM15&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MS 공식 문서에서는 위와 같이 레지스터를 휘발성과 비휘발성으로 구분한다. 자주 덮어쓰는 값은 휘발성, 오래 보존할 값은 비휘발성으로 지정되며, 용량이 큰 레지스터는 저장 부담 때문에 일부만 비휘발성이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 90px;&quot; border=&quot;1&quot; data-ke-style=&quot;style12&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 22px;&quot;&gt;설계 목표&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 22px;&quot;&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;호출자, 피호출자 간 비용 부담 분배&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;모든 레지스터를 항상 callee-saved(피호출자 보존)로 지정하면 모든 함수의 prologue와 epilogue에 push와 pop이 반복되어 코드 크기와 스택 사용량이 증가하는 문제가 생긴다. 반면, 모든 레지스터가 caller-saved(호출자 보존)로 지정되면 호출이 발생할 때마다 호출자가 직접 레지스터 값을 보존해야 해서 호출 빈도가 높을수록 오버헤드가 커진다. 따라서 ABI는 호출자와 피호출자가 모두 보존하도록 비용을 나눠 균형있게 분담하도록 한다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;데이터&amp;nbsp;수명에&amp;nbsp;따른&amp;nbsp;역할&amp;nbsp;분담&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;데이터의 생명주기(lifetime)를 기준으로, 루프 인덱스나 베이스 포인터와 같은 장기간 살아 있는 값은 비휘발성 레지스터에, 반대로 임시적이고 짧은 계산에 사용되는 값은 휘발성 레지스터에 할당 하고 있다. 호출자는 장기 데이터를 안전하게 유지하면서도, 단기적인 계산에서는 부담 없이 레지스터를 자유롭게 사용할 수 있다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;컴파일러&amp;nbsp;최적화&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;컴파일러가 레지스터 할당할 때 함수 내 호출 빈도에 따라 휘발성 레지스터, 비휘발성 레지스터의 비용(weight)을 다르게 설정하는 휴리스틱을 적용해 최적화를 수행한다. 이 구분을 활용하여 불필요한 메모리 접근 횟수를 감소시킬 수 있다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;다양한&amp;nbsp;언어&amp;nbsp;및&amp;nbsp;모듈&amp;nbsp;간&amp;nbsp;호환성&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;저장 및 복원의 책임이 모듈마다 다르다면 링크는 가능할지 몰라도 실행 과정에서 상태가 훼손되어 제대로 동작하지 않을 위험이 있다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비휘발성 및 휘발성 레지스터 구분은 호출자와 피호출자간의 효율적인 역할 분담과 비용 최소화를 위해 필수적이다. 모든 레지스터를 동일하게 취급하여 보존 여부를 상황에 따라 결정하면 각 함수를 호출될 때마다 추가적인 분석과 판단이 요구되어 컴파일러 및 런타임 오버헤드가 발생할 수 있다. 또한, 이 경우 호출자와 피호출자 간의 보존 규약이 명확하지 않아 서로 다른 모듈이나 언어 간 상호작용 시 예기치 않은 상태 변경으로 인한 오류 위험이 증가한다. 반면, ABI에서 레지스터를 미리 휘발성과 비휘발성으로 명확히 구분하면 호출 시점마다 보존 여부를 판단할 필요가 없어지고, 각 함수는 이 규약을 신뢰하여 독립적으로 최적화된 코드를 생성할 수 있다. 결과적으로 이러한 명확한 구분은 코드의 안정성 및 유지보수성을 높이고, 다양한 언어나 모듈 간의 원활한 연동과 함께 컴파일러의 최적화 효율을 극대화하는 데 기여한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;6. 언와인드 데이터 규칙&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;언와인드 데이터(Unwind Data)란, Windows x64 환경에서 예외(Exception) 발생 시나 스택 추적(Stack Unwinding) 시에 스택 프레임을 정확히 복원할 수 있도록 돕는 추가적인 메타데이터(metadata)를 의미한다. 이는 함수가 실행될 때 어떻게 스택을 변경했는지를 기록한다. RUNTIME_FUNCTION, UNWIND_INFO,&lt;span&gt;&amp;nbsp;&lt;/span&gt;UNWIND_CODE 라는 구조체로 나타나며, x64 ABI 규약 중 하나다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1753586105332&quot; class=&quot;crystal&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;typedef struct _RUNTIME_FUNCTION {
  DWORD BeginAddress; // Function start address
  DWORD EndAddress; // Function end address
  union {
    DWORD UnwindInfoAddress; // Unwind info address
    DWORD UnwindData; // Alternative name for the same field
  } DUMMYUNIONNAME;
} RUNTIME_FUNCTION, *PRUNTIME_FUNCTION;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;_RUNTIME_FUNCTION 구조체는 PE 포맷의 예외 처리 테이블에서 각 함수에 대한 정보를 저장하기 위해 사용되며, 함수의 시작 주소와 끝 주소, 그리고 해당 함수에 연관된 언와인드 정보의 RVA를 포함한다. 언와인드 정보는 UnwindInfoAddress 또는 UnwindData로 명명된 필드를 통해 참조되며, 두 이름은 동일한 필드를 가리키는 대체 표현이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1753586105334&quot; class=&quot;angelscript&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;typedef struct _UNWIND_INFO {
    BYTE Version : 3;           // Version
    BYTE Flags : 5;             // Flags
    BYTE SizeOfProlog;          // Size of prolog
    BYTE CountOfCodes;          // Count of unwind codes
    BYTE FrameRegister : 4;     // Frame Register
    BYTE FrameOffset : 4;       // Frame Register offset (scaled)
    UNWIND_CODE UnwindCode[1];  // Unwind codes array
    /*  UNWIND_CODE MoreUnwindCode[((CountOfCodes + 1) &amp;amp; ~1) - 1];
*   union {
*       OPTIONAL ULONG ExceptionHandler;
*       OPTIONAL ULONG FunctionEntry;
*   };
*   OPTIONAL ULONG ExceptionData[]; */
} UNWIND_INFO, *PUNWIND_INFO;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;_UNWIND_INFO 구조체는 함수가 예외 상황에서 콜스택을 어떻게 복원할지를 정의한 메타데이터를 포함하며, 버전, 플래그, 함수 프롤로그의 크기, 언와인드 코드 수, 프레임 레지스터 및 그 오프셋, 그리고 복원 과정을 나타내는 UNWIND_CODE 배열로 구성된다. UNWIND_CODE 배열은 고정 길이가 아니며, CountOfCodes에 따라 추가적인 unwind 코드 및 선택적으로 예외 핸들러 주소를 포함할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1753586105336&quot; class=&quot;cpp&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;typedef union _UNWIND_CODE {
    struct {
        UBYTE CodeOffset; // Offset in prolog
        UBYTE UnwindOp : 4; // Unwind operation code
        UBYTE OpInfo   : 4; // Operation info
    };
    USHORT FrameOffset; // unsigned offset to a value in the local stack frame
} UNWIND_CODE, *PUNWIND_CODE;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;_UNWIND_CODE는 언와인드 동작을 정의하는 구조체로, 기본적으로 프롤로그 내 오프셋과 해당 위치에서 수행할 복원 동작의 종류 및 세부 정보로 이루어진다. 경우에 따라 이 구조체는 2바이트를 단일 FrameOffset으로 해석할 수 있으며, 특정 unwind 연산자에서 프레임 오프셋 정보를 필요로 할 때 사용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;unwind.jpg&quot; data-origin-width=&quot;5424&quot; data-origin-height=&quot;2112&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dAAbTy/btsPBJN6UOJ/u3EqtS9vuqz9e62aZqGkdK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dAAbTy/btsPBJN6UOJ/u3EqtS9vuqz9e62aZqGkdK/img.jpg&quot; data-alt=&quot;[이미지12] Unwind Data&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dAAbTy/btsPBJN6UOJ/u3EqtS9vuqz9e62aZqGkdK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdAAbTy%2FbtsPBJN6UOJ%2Fu3EqtS9vuqz9e62aZqGkdK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;5424&quot; height=&quot;2112&quot; data-filename=&quot;unwind.jpg&quot; data-origin-width=&quot;5424&quot; data-origin-height=&quot;2112&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지12] Unwind Data&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수가 스택 공간을 할당하거나 다른 함수를 호출하는 non-leaf 함수일 경우, 해당 코드 범위를 나타내는 RUNTIME_FUNCTION 엔트리를 .pdata 섹션에 기록하고, 그 엔트리가 참조하는 UNWIND_INFO(UNWIND_CODE) 구조체를 .xdata 섹션에 함께 정의해야 한다. 반면, 스택을 전혀 사용하지 않고 다른 함수도 호출하지 않는 leaf 함수의 경우에는 생략이 가능하다. 각각의 구조체는 .pdata와 .xdata 섹션에 기록되는 것이 기본이며, 이는 Microsoft의 링크 규칙과 운영체제 런타임에 의해 기대되는 표준 위치다. 하지만 이들 섹션은 절대적으로 고정된 것은 아니며, 다른 섹션에 배치될 수도 있다. 운영체제는 예외 처리 시 .pdata에 등록된 함수 범위를 기준으로 UNWIND_INFO의 위치를 RVA로 해석해 접근하기 때문에, .xdata가 아닌 다른 섹션에 존재하더라도 RVA 값만 정확하다면 기능적으로 문제는 발생하지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;1. 예외가 발생하면 운영체제는 RIP가 포함된 주소를 기준으로 .pdata 섹션에 저장된 RUNTIME_FUNCTION 테이블을 탐색하여 해당 함수의 예외 처리 정보를 조회한다.&lt;br /&gt;&lt;br /&gt;2. 조회된 RUNTIME_FUNCTION 항목에 포함된 UnwindInfoAddress를 통해 .xdata 섹션에 위치한 UNWIND_INFO 구조체를 로드한다.&lt;br /&gt;&lt;br /&gt;3. UNWIND_INFO는 프롤로그 길이, 프레임 레지스터 정보, 언와인드 코드 배열을 포함하며, OS는 이 코드를 역순으로 해석해 함수 진입 시점의 RSP 및 비휘발성 레지스터 값을 복원한다.&lt;br /&gt;&lt;br /&gt;4. 복원된 스택 포인터와 레지스터 상태를 바탕으로 Caller(호출자) 함수의 리턴 주소(RIP)로 스택을 되돌리며, 이전 함수에 대해 동일한 과정을 반복한다.&lt;br /&gt;&lt;br /&gt;5. 만약 UNWIND_INFO의 Flags 필드에 예외 핸들러의 존재가 명시되어 있으면, OS는 복원된 컨텍스트로 되돌아가지 않고 지정된 RVA에 위치한 핸들러로 제어를 전달하여 예외 처리를 수행한다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 절차는 예외 발생 시 콜스택을 정확히 복원하고, 필요한 경우 사용자 정의 핸들러로 제어를 안전하게 이전할 수 있도록 하기 위한 x64 예외 처리 메커니즘이다. 함수 단위로 기록된 Unwind Data는 스택 프레임을 역방향으로 추적하면서 Caller(호출자)의 컨텍스트를 재구성하는 데 필요한 최소한의 메타데이터를 제공하며, 이는 구조적으로 정렬된 데이터 기반의 예외 처리 흐름을 가능하게 함으로써 성능과 안정성 모두를 확보하는 데 기여한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;7. 함수 호출 규약&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;x64 함수 호출 규약에 대한 자세한 내용은 &lt;a href=&quot;https://kj0on.tistory.com/44&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://kj0on.tistory.com/44&lt;/a&gt; 참고&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;8. 참고 문헌&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[1] X64 Deep Dive,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://codemachine.com/articles/x64_deep_dive.html&quot;&gt;https://codemachine.com/articles/x64_deep_dive.html&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[2] x64 호출 규칙,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/cpp/build/x64-calling-convention?view=msvc-170&quot;&gt;https://learn.microsoft.com/ko-kr/cpp/build/x64-calling-convention?view=msvc-170&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[3] x64 스택 사용,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/cpp/build/stack-usage?view=msvc-170&quot;&gt;https://learn.microsoft.com/ko-kr/cpp/build/stack-usage?view=msvc-170&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[4] Why should data be aligned to 16 bytes for SSE instructions?,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://community.intel.com/t5/Software-Tuning-Performance/Why-should-data-be-aligned-to-16-bytes-for-SSE-instructions/td-p/1164004&quot;&gt;https://community.intel.com/t5/Software-Tuning-Performance/Why-should-data-be-aligned-to-16-bytes-for-SSE-instructions/td-p/1164004&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[5] Debugging Stories: Stack alignment matters,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://research.csiro.au/tsblog/debugging-stories-stack-alignment-matters/&quot;&gt;https://research.csiro.au/tsblog/debugging-stories-stack-alignment-matters/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[6] What is the point of MOVAPS in x86 if it does the same as MOVUPS in modern computers?,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://stackoverflow.com/questions/79067215/what-is-the-point-of-movaps-in-x86-if-it-does-the-same-as-movups-in-modern-compu&quot;&gt;https://stackoverflow.com/questions/79067215/what-is-the-point-of-movaps-in-x86-if-it-does-the-same-as-movups-in-modern-compu&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[7] Instruction tables,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://agner.org/optimize/instruction_tables.pdf&quot;&gt;https://agner.org/optimize/instruction_tables.pdf&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[8] win64&amp;nbsp;Structured&amp;nbsp;Exception&amp;nbsp;Handling,&amp;nbsp;&lt;a href=&quot;https://www.tortall.net/projects/yasm/manual/html/objfmt-win64-exception.html&quot;&gt;https://www.tortall.net/projects/yasm/manual/html/objfmt-win64-exception.html&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[9]&lt;span&gt;&amp;nbsp;&lt;/span&gt;Struct RUNTIME_FUNCTION,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://stackoverflow.com/questions/19808172/struct-runtime-function&quot;&gt;https://stackoverflow.com/questions/19808172/struct-runtime-function&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Reversing/Definition</category>
      <category>ABI</category>
      <category>x64</category>
      <author>kj0on</author>
      <guid isPermaLink="true">https://kj0on.tistory.com/47</guid>
      <comments>https://kj0on.tistory.com/47#entry47comment</comments>
      <pubDate>Tue, 22 Jul 2025 14:48:44 +0900</pubDate>
    </item>
    <item>
      <title>[Definition] x32 ABI</title>
      <link>https://kj0on.tistory.com/46</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;1. 정의&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;ABI (Application Binary Interface)는 어플리케이션과 운영체제 또는 컴파일된 코드 간의 상호작용 방식을 정의한 이진 수준의 규약이다. 쉽게 말해, 컴파일된 바이너리들이 서로 호환되도록 하는 규칙 모음을 뜻한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. x32 ABI&lt;/h2&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 96px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 25%; height: 22px;&quot;&gt;규칙&lt;/td&gt;
&lt;td style=&quot;width: 22.2093%; height: 22px;&quot;&gt;역할&lt;/td&gt;
&lt;td style=&quot;width: 27.7907%; height: 22px;&quot;&gt;필수 규칙(ABI)&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 22px;&quot;&gt;조건부 규칙&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 40px;&quot;&gt;
&lt;td style=&quot;width: 25%; height: 40px;&quot;&gt;스택 정렬 규칙&lt;/td&gt;
&lt;td style=&quot;width: 22.2093%; height: 40px;&quot;&gt;Alignment &lt;br /&gt;(정렬)&lt;/td&gt;
&lt;td style=&quot;width: 27.7907%; height: 40px;&quot;&gt;모든 구간에서 E&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;SP &amp;equiv; 0 (mod 4)를 유지해야 한다&lt;/span&gt;.&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 40px;&quot;&gt;16byte 정렬을 요구하는 SIMD 명령을 사용 할 경우, 함수 내부에서 추가 정렬을 보장해야 한다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 25%; height: 17px;&quot;&gt;레지스터 보존 규칙&lt;/td&gt;
&lt;td style=&quot;width: 22.2093%; height: 17px;&quot;&gt;Register&amp;nbsp;Save &lt;br /&gt;(레지스터&amp;nbsp;보존)&lt;/td&gt;
&lt;td style=&quot;width: 27.7907%; height: 17px;&quot;&gt;Callee(피호출자)에서&amp;nbsp;비휘발성&amp;nbsp;레지스터를&amp;nbsp;사용했다면&amp;nbsp;함수&amp;nbsp;내부에서&amp;nbsp;원래&amp;nbsp;값으로&amp;nbsp;복구해야&amp;nbsp;한다.&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px;&quot;&gt;비휘발성&amp;nbsp;레지스터를&amp;nbsp;사용하지&amp;nbsp;않았다면&amp;nbsp;저장,&amp;nbsp;복구&amp;nbsp;코드가&amp;nbsp;없어도&amp;nbsp;된다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 25%; height: 17px;&quot;&gt;함수 호출 규약&lt;/td&gt;
&lt;td style=&quot;width: 22.2093%; height: 17px;&quot;&gt;Parameter&amp;nbsp;Passing &lt;br /&gt;(인자&amp;nbsp;전달)&lt;/td&gt;
&lt;td style=&quot;width: 27.7907%; height: 17px;&quot;&gt;__stdcall, __cdecl, __fastcall, __vectorcall, ...&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px;&quot;&gt;...&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 스택 정렬 규칙&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-1. Hello World&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3-1-1. 예제 코드&lt;/h4&gt;
&lt;pre id=&quot;code_1754111071553&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

int main(void) {
	printf(&quot;Hello World!\n&quot;);
	getchar();
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당&amp;nbsp;프로그램은&amp;nbsp;실행&amp;nbsp;시&amp;nbsp;콘솔에&amp;nbsp;&quot;Hello&amp;nbsp;World!&quot;라는&amp;nbsp;문자열을&amp;nbsp;출력하도록&amp;nbsp;작성된&amp;nbsp;코드이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;397&quot; data-origin-height=&quot;197&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SmrGk/btsPGIgTXEE/sqyjTCZKe0ygYRF5vrnph1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SmrGk/btsPGIgTXEE/sqyjTCZKe0ygYRF5vrnph1/img.png&quot; data-alt=&quot;[이미지1] 실행 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SmrGk/btsPGIgTXEE/sqyjTCZKe0ygYRF5vrnph1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSmrGk%2FbtsPGIgTXEE%2FsqyjTCZKe0ygYRF5vrnph1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;397&quot; height=&quot;197&quot; data-origin-width=&quot;397&quot; data-origin-height=&quot;197&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지1] 실행 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3-1-2. ESP 분석&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1558&quot; data-origin-height=&quot;249&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bIuFxO/btsPDXzA4cM/K9yrRHFY0uGI1ws1oF6K51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bIuFxO/btsPDXzA4cM/K9yrRHFY0uGI1ws1oF6K51/img.png&quot; data-alt=&quot;[이미지2] Entry Point&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bIuFxO/btsPDXzA4cM/K9yrRHFY0uGI1ws1oF6K51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbIuFxO%2FbtsPDXzA4cM%2FK9yrRHFY0uGI1ws1oF6K51%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1558&quot; height=&quot;249&quot; data-origin-width=&quot;1558&quot; data-origin-height=&quot;249&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지2] Entry Point&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;32bit 환경에서는 기본 데이터 단위(word)가 4byte이므로 ESP는 항상 4의 배수로 정렬되어야 하며, 윈도우 로더와 링커는 프로그램 시작 시 ESP를 이미 4byte로 정렬된 상태로 설정한다. 이후 각 함수는 이 정렬을 유지한 채 인자 전달, 로컬 변수 할당, 함수 호출 등을 수행한다. 이렇게 정렬을 유지하면 메모리 접근 시 정렬 예외를 방지하고, 성능 이점을 얻을 수 있다. 결과적으로, x32에서는 스택 정렬이 구조적 안전성과 호환성을 보장하는 기본 규칙으로 기능한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;607&quot; data-origin-height=&quot;286&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bCRrzO/btsPDXfFQQa/kFzr6UKFyMdACeOhFhqufk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bCRrzO/btsPDXfFQQa/kFzr6UKFyMdACeOhFhqufk/img.png&quot; data-alt=&quot;[이미지3] Hello World&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bCRrzO/btsPDXfFQQa/kFzr6UKFyMdACeOhFhqufk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbCRrzO%2FbtsPDXfFQQa%2FkFzr6UKFyMdACeOhFhqufk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;607&quot; height=&quot;286&quot; data-origin-width=&quot;607&quot; data-origin-height=&quot;286&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지3] Hello World&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수 프롤로그에서 로컬 변수나 임시 데이터를 저장하기 위해 스택 공간을 확보할 때, 항상 4byte 정렬을 유지한 채 크기를 계산하고 할당하는 방식이 사용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;607&quot; data-origin-height=&quot;286&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mkJvk/btsPEssZGP7/KndFnfI2Vee2KJRFkQimok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mkJvk/btsPEssZGP7/KndFnfI2Vee2KJRFkQimok/img.png&quot; data-alt=&quot;[이미지4] Hello World&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mkJvk/btsPEssZGP7/KndFnfI2Vee2KJRFkQimok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmkJvk%2FbtsPEssZGP7%2FKndFnfI2Vee2KJRFkQimok%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;607&quot; height=&quot;286&quot; data-origin-width=&quot;607&quot; data-origin-height=&quot;286&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지4] Hello World&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 함수 내부에서 사용하는 push, pop 명령어 또한 4byte 단위로 ESP를 증감시키기 때문에, 전체적인 스택 정렬이 지속적으로 4byte 단위로 유지되도록 설계되어 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-2. SIMD&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3-2-1. 예제 코드&lt;/h4&gt;
&lt;pre id=&quot;code_1754111166003&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;emmintrin.h&amp;gt;

void simd_add(float out[4], const float a[4], const float b[4])
{
    __m128 va = _mm_load_ps(a);
    __m128 vb = _mm_load_ps(b);
    __m128 vc = _mm_add_ps(va, vb);
    _mm_store_ps(out, vc);
}

int main(void) {

    float out[4] = { 0, };
    float a[4] = { 0.1f, 0.2f, 0.3f, 0.4f };
    float b[4] = { 0.5f, 0.6f, 0.7f, 0.8f };

	printf(&quot;Hello World!\n&quot;);

    simd_add(out, a, b);
    for (int i = 0; i &amp;lt; sizeof(out) / sizeof(float); i++){
        printf(&quot;%.1f &quot;, out[i]);
    }
    printf(&quot;\n&quot;);

	getchar();
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 프로그램은 실행 시 콘솔에 &quot;Hello World!&quot;라는 문자열을 출력 한 뒤, SIMD를&amp;nbsp;활용해&amp;nbsp;float&amp;nbsp;배열&amp;nbsp;a와&amp;nbsp;b의&amp;nbsp;각&amp;nbsp;요소를&amp;nbsp;병렬로&amp;nbsp;더한&amp;nbsp;결과를&amp;nbsp;out&amp;nbsp;배열에&amp;nbsp;저장하고&amp;nbsp;출력하는&amp;nbsp;프로그램이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;397&quot; data-origin-height=&quot;197&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lujHD/btsPFjvpeMx/BvAn6BMH90xPizkkMAtDS1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lujHD/btsPFjvpeMx/BvAn6BMH90xPizkkMAtDS1/img.png&quot; data-alt=&quot;[이미지5] 실행 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lujHD/btsPFjvpeMx/BvAn6BMH90xPizkkMAtDS1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlujHD%2FbtsPFjvpeMx%2FBvAn6BMH90xPizkkMAtDS1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;397&quot; height=&quot;197&quot; data-origin-width=&quot;397&quot; data-origin-height=&quot;197&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지5] 실행 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3-2-2. movaps&lt;/h4&gt;
&lt;pre id=&quot;code_1754113059719&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;movaps reg, mem
movaps mem, reg
movaps reg, reg&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;movaps 명령어는 x86/x64 아키텍처에서 사용되는 SSE (Streaming SIMD Extensions) 명령어 중 하나로, 16byte(128bit) 단위의 정렬된 데이터를 복사하는 명령어다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;cache.jpg&quot; data-origin-width=&quot;4250&quot; data-origin-height=&quot;1991&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/H2vRP/btsPFaMjoz9/Y1GE7C1JA9pwe6dTM1qTe1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/H2vRP/btsPFaMjoz9/Y1GE7C1JA9pwe6dTM1qTe1/img.jpg&quot; data-alt=&quot;[이미지6] 캐시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/H2vRP/btsPFaMjoz9/Y1GE7C1JA9pwe6dTM1qTe1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FH2vRP%2FbtsPFaMjoz9%2FY1GE7C1JA9pwe6dTM1qTe1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4250&quot; height=&quot;1991&quot; data-filename=&quot;cache.jpg&quot; data-origin-width=&quot;4250&quot; data-origin-height=&quot;1991&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지6] 캐시&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메인 메모리에서 데이터를 읽을 때 16byte 정렬을 지키지 않으면 CPU의 캐시 서브시스템이 데이터를 효율적으로 로드하지 못하고 성능 저하가 발생할 수 있다. 이때 접근하려는 주소가 캐시 라인의 경계를 넘는 경우가 생기면 하나의 메모리 접근이 두 개의 캐시 라인에 걸쳐 처리된다. 이 과정에서 두 번의 메모리 접근과 바렐 시프터 또는 병합 로직을 통한 재조합 과정이 추가된다. 이러한 연산은 단순히 캐시 미스 발생 가능성을 높일 뿐 아니라 내부 마이크로아키텍처의 처리 경로까지 복잡하게 만들어 명령어 처리 속도를 감소시킨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;simd_and0.jpg&quot; data-origin-width=&quot;3170&quot; data-origin-height=&quot;2475&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNOOCo/btsPEtMI0Kl/z4f5WcX20e1T2jxKWI3jh1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNOOCo/btsPEtMI0Kl/z4f5WcX20e1T2jxKWI3jh1/img.jpg&quot; data-alt=&quot;[이미지7] EXCEPTION_ACCESS_VIOLATION&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNOOCo/btsPEtMI0Kl/z4f5WcX20e1T2jxKWI3jh1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNOOCo%2FbtsPEtMI0Kl%2Fz4f5WcX20e1T2jxKWI3jh1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3170&quot; height=&quot;2475&quot; data-filename=&quot;simd_and0.jpg&quot; data-origin-width=&quot;3170&quot; data-origin-height=&quot;2475&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지7] EXCEPTION_ACCESS_VIOLATION&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;movaps 명령은 16byte로 정렬된 메모리 주소에서만 동작하며, 정렬이 어긋난 상태에서 실행하면 EXCEPTION_ACCESS_VIOLATION 예외가 발생한다. 이는 CPU가 정렬 위반을 하드웨어 수준에서 막기 때문이며, 정렬되지 않은 주소에 안전하게 접근하려면 movups 명령을 사용해야 한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3-2-3. ESP 분석&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;684&quot; data-origin-height=&quot;457&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/clSYgX/btsPFhj3l0X/3sTRHTxF63FY6LPxjxBr1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/clSYgX/btsPFhj3l0X/3sTRHTxF63FY6LPxjxBr1k/img.png&quot; data-alt=&quot;[이미지8] SIMD add&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/clSYgX/btsPFhj3l0X/3sTRHTxF63FY6LPxjxBr1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FclSYgX%2FbtsPFhj3l0X%2F3sTRHTxF63FY6LPxjxBr1k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;684&quot; height=&quot;457&quot; data-origin-width=&quot;684&quot; data-origin-height=&quot;457&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지8] SIMD add&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;16byte정렬은 4byte정렬을 보장하지만, 반대로 4byte정렬만으로는 16byte 정렬이 보장되지 않는다. x32ABI의 스택 정렬 규칙은 4byte정렬만 요구하기 때문에 16byte 정렬을 요구하는 SIMD 명령을 사용할 때는 함수 내부에서 별도로 재정렬이 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;684&quot; data-origin-height=&quot;457&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Vduqn/btsPDD9Ciht/KwR2AOcQbq7LCWzXo1YXE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Vduqn/btsPDD9Ciht/KwR2AOcQbq7LCWzXo1YXE0/img.png&quot; data-alt=&quot;[이미지9] SIMD add&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Vduqn/btsPDD9Ciht/KwR2AOcQbq7LCWzXo1YXE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVduqn%2FbtsPDD9Ciht%2FKwR2AOcQbq7LCWzXo1YXE0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;684&quot; height=&quot;457&quot; data-origin-width=&quot;684&quot; data-origin-height=&quot;457&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지9] SIMD add&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 흔히 사용되는 방식 중 하나가 and esp, 0xFFFFFFF0 명령을 통해 하위 4bit를 0으로 마스킹하는 방식이다. 이 연산은 현재 ESP 값에서 16byte 정렬을 강제하며, 이후에 movaps를 사용할 때 정렬 위반 예외를 방지할 수 있다. 따라서 정렬을 요구하는 SSE 명령어를 사용하는 함수에서는 프롤로그에서 ESP 정렬을 보장하는 코드 패턴이 삽입되는 경우가 많다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1104&quot; data-origin-height=&quot;406&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lWFuW/btsPDNK2eqS/Zovrrevj9LfysIyMcTsw0K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lWFuW/btsPDNK2eqS/Zovrrevj9LfysIyMcTsw0K/img.png&quot; data-alt=&quot;[이미지10] and&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lWFuW/btsPDNK2eqS/Zovrrevj9LfysIyMcTsw0K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlWFuW%2FbtsPDNK2eqS%2FZovrrevj9LfysIyMcTsw0K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1104&quot; height=&quot;406&quot; data-origin-width=&quot;1104&quot; data-origin-height=&quot;406&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지10] and&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;0xFFFFFFF0과 and 연산을 수행하면 하위 4bit가 0으로 변경되어 해당 값은 16byte 정렬 상태가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1104&quot; data-origin-height=&quot;406&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nLjqP/btsPEChXy0x/YA6j6DKeKo6UyVFGtdLB0K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nLjqP/btsPEChXy0x/YA6j6DKeKo6UyVFGtdLB0K/img.png&quot; data-alt=&quot;[이미지11] and&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nLjqP/btsPEChXy0x/YA6j6DKeKo6UyVFGtdLB0K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnLjqP%2FbtsPEChXy0x%2FYA6j6DKeKo6UyVFGtdLB0K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1104&quot; height=&quot;406&quot; data-origin-width=&quot;1104&quot; data-origin-height=&quot;406&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지11] and&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 이진수로 0xFFFFFFF0이 1111 1111 1111 1111 1111 1111 1111 0000이기 때문에, 어떤 값과 AND 연산을 하더라도 마지막 4bit는 강제로 0000이 되어 전체 값이 16byte로 정렬된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;simd_and3.jpg&quot; data-origin-width=&quot;3864&quot; data-origin-height=&quot;1999&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MYdH1/btsPDFzF24h/UAxmF6OE4wADWjE7Wyg2ik/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MYdH1/btsPDFzF24h/UAxmF6OE4wADWjE7Wyg2ik/img.jpg&quot; data-alt=&quot;[이미지12] ESP&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MYdH1/btsPDFzF24h/UAxmF6OE4wADWjE7Wyg2ik/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMYdH1%2FbtsPDFzF24h%2FUAxmF6OE4wADWjE7Wyg2ik%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3864&quot; height=&quot;1999&quot; data-filename=&quot;simd_and3.jpg&quot; data-origin-width=&quot;3864&quot; data-origin-height=&quot;1999&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지12] ESP&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 정렬 연산은 SIMD 명령 직전이 아닌 함수 프롤로그에서 나타날 수 있다. 함수 진입 시 컴파일러는 이후의 push, sub, add 연산까지 고려해 전체 스택 프레임이 최종적으로 16byte 정렬을 유지하도록 설계하며, 이를 통해 정렬 상태를 반복적으로 확인하거나 수정하지 않고도 SIMD 명령을 안전하게 사용할 수 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. 레지스터 보존 규칙&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;컴파일러는 ESI, EDI, EBX 및 EBP 레지스터가 함수에서 사용되는 경우 이러한 레지스터를 저장하고 복원하는 프롤로그 및 에필로그 코드를 생성합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Microsoft의 문서에 따르면, ESI, EDI, EBX, EBP는 비휘발성(non-volatile) 레지스터로 간주하며, 함수 내에서 이들을 사용하는 경우 해당 함수는 이 레지스터들의 값을 호출 시점과 동일하게 유지해야 한다고 명시되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;reg.jpg&quot; data-origin-width=&quot;5786&quot; data-origin-height=&quot;1884&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFkD99/btsPHPf1zgD/21kncTt92iARS3oBwSIjO1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFkD99/btsPHPf1zgD/21kncTt92iARS3oBwSIjO1/img.jpg&quot; data-alt=&quot;[이미지13] 휘발성 레지스터 &amp;amp;amp; 비휘발성 레지스터&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFkD99/btsPHPf1zgD/21kncTt92iARS3oBwSIjO1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFkD99%2FbtsPHPf1zgD%2F21kncTt92iARS3oBwSIjO1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;5786&quot; height=&quot;1884&quot; data-filename=&quot;reg.jpg&quot; data-origin-width=&quot;5786&quot; data-origin-height=&quot;1884&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지13] 휘발성 레지스터 &amp;amp; 비휘발성 레지스터&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 110px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 31.2403%; height: 22px;&quot;&gt;분류&lt;/td&gt;
&lt;td style=&quot;width: 18.6821%; height: 22px;&quot;&gt;보존&amp;nbsp;책임&lt;/td&gt;
&lt;td style=&quot;width: 50.0775%; height: 22px;&quot;&gt;의미&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 44px;&quot;&gt;
&lt;td style=&quot;width: 31.2403%; height: 44px;&quot;&gt;휘발성 레지스터 (Volatile)&lt;/td&gt;
&lt;td style=&quot;width: 18.6821%; height: 44px;&quot;&gt;Caller-Saved&lt;/td&gt;
&lt;td style=&quot;width: 50.0775%; height: 44px;&quot;&gt;호출 직후 값이 보존된다고 기대할 수 없다. 필요하면 호출자가 따로 저장해야 한다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 44px;&quot;&gt;
&lt;td style=&quot;width: 31.2403%; height: 44px;&quot;&gt;비휘발성 레지스터 (non-Volatile)&lt;/td&gt;
&lt;td style=&quot;width: 18.6821%; height: 44px;&quot;&gt;Callee-Saved&lt;/td&gt;
&lt;td style=&quot;width: 50.0775%; height: 44px;&quot;&gt;호출&amp;nbsp;전,&amp;nbsp;후의&amp;nbsp;값이&amp;nbsp;같아야&amp;nbsp;한다.&amp;nbsp;피호출자가&amp;nbsp;해당&amp;nbsp;레지스터를&amp;nbsp;쓰면&amp;nbsp;반드시&amp;nbsp;원래&amp;nbsp;값으로&amp;nbsp;복구해야&amp;nbsp;한다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;휘발성(volatile), 비휘발성(non-volatile)는 레지스터 자체의 물리적인(하드웨어) 특성이 아닌, Caller(호출자)의 시점에서 바라본 레지스터의 특성이다. Caller(호출자) 입장에서는 휘발성 레지스터는 Callee(피호출자)가 보존해 주지 않기 때문에 호출 시점에서 값이 변경(휘발성) 될 수 있다고 보는것이다. 반대로 비휘발성 레지스터는 Callee(피호출자)가 함수 내부에서 직접 보존하기 때문에 호출 시점에 값이 변경되지 않는(비휘발성)것으로 판단할 수 있다는 것이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 66px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 19.7673%; height: 22px;&quot;&gt;구분&lt;/td&gt;
&lt;td style=&quot;width: 80.2327%; height: 22px;&quot;&gt;레지스터&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 19.7673%; height: 22px;&quot;&gt;휘발성 레지스터&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;width: 80.2327%; height: 22px;&quot;&gt;EAX, ECX, EDX&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 19.7673%; height: 22px;&quot;&gt;비휘발성 레지스터&lt;br /&gt;&lt;br /&gt;&lt;/td&gt;
&lt;td style=&quot;width: 80.2327%; height: 22px;&quot;&gt;ESI, EDI, EBX, EBP&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;MS 공식 문서에서는 위와 같이 레지스터를 휘발성과 비휘발성으로 구분한다. 자주 덮어쓰는 값은 휘발성, 오래 보존할 값은 비휘발성으로 지정된다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 90px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 22px;&quot;&gt;설계 목표&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 22px;&quot;&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;호출자, 피호출자 간 비용 부담 분배&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;모든 레지스터를 항상 callee-saved(피호출자 보존)로 지정하면 모든 함수의 prologue와 epilogue에 push와 pop이 반복되어 코드 크기와 스택 사용량이 증가하는 문제가 생긴다. 반면, 모든 레지스터가 caller-saved(호출자 보존)로 지정되면 호출이 발생할 때마다 호출자가 직접 레지스터 값을 보존해야 해서 호출 빈도가 높을수록 오버헤드가 커진다. 따라서 ABI는 호출자와 피호출자가 모두 보존하도록 비용을 나눠 균형있게 분담하도록 한다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;데이터&amp;nbsp;수명에&amp;nbsp;따른&amp;nbsp;역할&amp;nbsp;분담&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;데이터의 생명주기(lifetime)를 기준으로, 루프 인덱스나 베이스 포인터와 같은 장기간 살아 있는 값은 비휘발성 레지스터에, 반대로 임시적이고 짧은 계산에 사용되는 값은 휘발성 레지스터에 할당 하고 있다. 호출자는 장기 데이터를 안전하게 유지하면서도, 단기적인 계산에서는 부담 없이 레지스터를 자유롭게 사용할 수 있다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;컴파일러&amp;nbsp;최적화&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;컴파일러가 레지스터 할당할 때 함수 내 호출 빈도에 따라 휘발성 레지스터, 비휘발성 레지스터의 비용(weight)을 다르게 설정하는 휴리스틱을 적용해 최적화를 수행한다. 이 구분을 활용하여 불필요한 메모리 접근 횟수를 감소시킬 수 있다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;다양한&amp;nbsp;언어&amp;nbsp;및&amp;nbsp;모듈&amp;nbsp;간&amp;nbsp;호환성&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;저장 및 복원의 책임이 모듈마다 다르다면 링크는 가능할지 몰라도 실행 과정에서 상태가 훼손되어 제대로 동작하지 않을 위험이 있다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;비휘발성 및 휘발성 레지스터 구분은 호출자와 피호출자간의 효율적인 역할 분담과 비용 최소화를 위해 필수적이다. 모든 레지스터를 동일하게 취급하여 보존 여부를 상황에 따라 결정하면 각 함수를 호출될 때마다 추가적인 분석과 판단이 요구되어 컴파일러 및 런타임 오버헤드가 발생할 수 있다. 또한, 이 경우 호출자와 피호출자 간의 보존 규약이 명확하지 않아 서로 다른 모듈이나 언어 간 상호작용 시 예기치 않은 상태 변경으로 인한 오류 위험이 증가한다. 반면, ABI에서 레지스터를 미리 휘발성과 비휘발성으로 명확히 구분하면 호출 시점마다 보존 여부를 판단할 필요가 없어지고, 각 함수는 이 규약을 신뢰하여 독립적으로 최적화된 코드를 생성할 수 있다. 결과적으로 이러한 명확한 구분은 코드의 안정성 및 유지보수성을 높이고, 다양한 언어나 모듈 간의 원활한 연동과 함께 컴파일러의 최적화 효율을 극대화하는 데 기여한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. 함수 호출 규약&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;x32 함수 호출 규약에 대한 자세한 내용은 &lt;a href=&quot;https://kj0on.tistory.com/42&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://kj0on.tistory.com/42&lt;/a&gt;&amp;nbsp;참고&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. 참고 문헌&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[1] 인수 전달 및 명명 규칙, &lt;a href=&quot;https://learn.microsoft.com/ko-kr/cpp/cpp/argument-passing-and-naming-conventions?view=msvc-170&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://learn.microsoft.com/ko-kr/cpp/cpp/argument-passing-and-naming-conventions?view=msvc-170&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[2] x86 calling conventions, &lt;a href=&quot;https://en.wikipedia.org/wiki/X86_calling_conventions&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://en.wikipedia.org/wiki/X86_calling_conventions&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Reversing/Definition</category>
      <category>ABI</category>
      <category>x32</category>
      <author>kj0on</author>
      <guid isPermaLink="true">https://kj0on.tistory.com/46</guid>
      <comments>https://kj0on.tistory.com/46#entry46comment</comments>
      <pubDate>Tue, 22 Jul 2025 14:48:26 +0900</pubDate>
    </item>
    <item>
      <title>[Definition] 64비트 함수 호출 규약 (64bit Calling Convention)</title>
      <link>https://kj0on.tistory.com/44</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;0. 64비트 스택 프레임 (64bit Stack Frame)&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;64비트 스택프레임에 대한 자세한 설명은 &lt;a href=&quot;https://kj0on.tistory.com/43&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://kj0on.tistory.com/43&lt;/a&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;참고&lt;/p&gt;
&lt;hr data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;1. 정의&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;함수와&amp;nbsp;호출자&amp;nbsp;간에&amp;nbsp;인수를&amp;nbsp;전달하고&amp;nbsp;값을&amp;nbsp;반환하기&amp;nbsp;위한&amp;nbsp;규칙&lt;br /&gt;&amp;nbsp;&lt;br /&gt;프로시저(함수)&amp;nbsp;호출&amp;nbsp;시&amp;nbsp;인자를&amp;nbsp;어디에&amp;nbsp;어떤&amp;nbsp;순서로&amp;nbsp;전달하고,&amp;nbsp;누가&amp;nbsp;스택을&amp;nbsp;정리하며,&amp;nbsp;레지스터를&amp;nbsp;보존할지,&amp;nbsp;어느&amp;nbsp;레지스터로&amp;nbsp;값을&amp;nbsp;반환할지&amp;nbsp;등을&amp;nbsp;규정한&amp;nbsp;저수준&amp;nbsp;인터페이스&amp;nbsp;계약이다.&amp;nbsp;컴파일러,&amp;nbsp;언어,&amp;nbsp;OS,&amp;nbsp;CPU가&amp;nbsp;서로&amp;nbsp;다른&amp;nbsp;오브젝트&amp;nbsp;코드를&amp;nbsp;같은&amp;nbsp;ABI&amp;nbsp;안에서&amp;nbsp;링크&amp;nbsp;및&amp;nbsp;호출할&amp;nbsp;수&amp;nbsp;있게&amp;nbsp;해준다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;2. Caller(호출자)와 Callee(피호출자)&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2708&quot; data-origin-height=&quot;794&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beRA1E/btsPj2AttRo/FoauELqu4hijjDnBwEXcs1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beRA1E/btsPj2AttRo/FoauELqu4hijjDnBwEXcs1/img.jpg&quot; data-alt=&quot;[이미지1] caller callee&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beRA1E/btsPj2AttRo/FoauELqu4hijjDnBwEXcs1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbeRA1E%2FbtsPj2AttRo%2FFoauELqu4hijjDnBwEXcs1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2708&quot; height=&quot;794&quot; data-origin-width=&quot;2708&quot; data-origin-height=&quot;794&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지1] caller callee&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Caller는 함수를 호출하는 쪽이고, Callee는 호출된 함수이다. Caller는 인자를 준비하고 제어를 Callee에게 넘기며, Callee는 이를 받아 작업을 수행한 뒤 결과를 반환한다. 이 과정에서 책임이 명확하게 나뉘며, 어떤 쪽이 어떤 책임을 지는지는 사용된 호출 규약에 따라 사전에 정해진 방식으로 결정된다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;3. 함수 호출 규약 분류&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3700&quot; data-origin-height=&quot;2475&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBj6Ac/btsPkE0f3Dc/MWPKd9N7KNSuJMIQWlHJ20/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBj6Ac/btsPkE0f3Dc/MWPKd9N7KNSuJMIQWlHJ20/img.jpg&quot; data-alt=&quot;[이미지2] Calling Convention&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBj6Ac/btsPkE0f3Dc/MWPKd9N7KNSuJMIQWlHJ20/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBj6Ac%2FbtsPkE0f3Dc%2FMWPKd9N7KNSuJMIQWlHJ20%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3700&quot; height=&quot;2475&quot; data-origin-width=&quot;3700&quot; data-origin-height=&quot;2475&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지2] Calling Convention&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Win16 및 초기 컴파일러 환경에서는 각 프로그래밍 언어마다 고유한 호출 방식이 존재했고, 운영체제 내부용 전용 호출 규약도 함께 사용되었다. 그러나 이러한 다양성은 호환성 문제와 확장성의 한계를 드러냈고, 결국 Win32 시대에 들어 실무적으로 표준화된 호출 규약들이 등장하면서 언어나 환경을 넘어 보다 효율적이고 일관된 방식으로 정립되기 시작했다. 이후 Win64 환경에서는 아예 단일 호출 규약이 강제되어 모든 언어와 컴파일러가 통일된 방식으로 함수를 호출하게 되었으며, 사실상 호출 규약 간의 차이가 사라졌다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;callingconvention_all.jpg&quot; data-origin-width=&quot;3700&quot; data-origin-height=&quot;2475&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bB65F2/btsPBMLv394/5JEHkUkBnPqwkX6W7eH94k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bB65F2/btsPBMLv394/5JEHkUkBnPqwkX6W7eH94k/img.jpg&quot; data-alt=&quot;[이미지3] Calling Convention&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bB65F2/btsPBMLv394/5JEHkUkBnPqwkX6W7eH94k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbB65F2%2FbtsPBMLv394%2F5JEHkUkBnPqwkX6W7eH94k%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3700&quot; height=&quot;2475&quot; data-filename=&quot;callingconvention_all.jpg&quot; data-origin-width=&quot;3700&quot; data-origin-height=&quot;2475&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지3] Calling Convention&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이 글에서는 x64 ABI 만 집중적으로 다룬다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;4. Windows x64 함수 호출 규약&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Windows x32에는 __cdecl, __stdcall, __fastcall, __vectorcall 등 다수의 호출규약이 공존했으나, x64로의 전환 과정에서 플랫폼별로 하나의 표준 호출규약만 남도록 설계가 단순화되었다. Windows x64 calling convention이라는 단일 규격을 강제함으로써 모듈이 모두 동일한 규칙을 공유한다. 이러한 통일은 레지스터 전달로 인한 성능 이점과 시스템 수준 최적화를 가능케 하며, 하나의 규약만 알면 모든 바이너리가 호환된다는 이점을 얻게 되었다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;4-1. 예제 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753691666076&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

int int_add_fun(int a, int b, int c, int d, int e, int f) {
    int i1 = a;
    int i2 = b;
    int i3 = c;
    int i4 = d;
    int i5 = e;
    int i6 = f;
    int result = 0;
    result = i1 + i2 + i3 + i4 + i5 + i6;
    return result;
}

float float_add_fun(float a, float b, float c, float d, float e, float f) {
    float f1 = a;
    float f2 = b;
    float f3 = c;
    float f4 = d;
    float f5 = e;
    float f6 = f;
    float result = 0;
    result = f1 + f2 + f3 + f4 + f5 + f6;
    return result;
}

int main() {

    int int_result = int_add_fun(1, 2, 3, 4, 5, 6);
    printf(&quot;%d + %d + %d + %d + %d + %d = %d\n&quot;, 1, 2, 3, 4, 5, 6, int_result);

    float float_result = float_add_fun(0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f);
    printf(&quot;%.1f + %.1f + %.1f + %.1f + %.1f + %.1f = %.1f\n&quot;, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, float_result);

    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;이 코드는 6개의 정수를 더하는 함수 int_add_fun과 6개의 소수를 더하는 함수 float_add_fun을 정의하고, 이를 main 함수에서 호출하여 결과를 출력하는 간단한 예제이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1100&quot; data-origin-height=&quot;266&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwzIo0/btsPAwXap9M/Yf7mSDxNyELakg8ARZ95Z0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwzIo0/btsPAwXap9M/Yf7mSDxNyELakg8ARZ95Z0/img.png&quot; data-alt=&quot;[이미지4] 실행 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwzIo0/btsPAwXap9M/Yf7mSDxNyELakg8ARZ95Z0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwzIo0%2FbtsPAwXap9M%2FYf7mSDxNyELakg8ARZ95Z0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1100&quot; height=&quot;266&quot; data-origin-width=&quot;1100&quot; data-origin-height=&quot;266&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지4] 실행 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4-2. Windows x64 calling convention&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;callingconvention_all.jpg&quot; data-origin-width=&quot;5239&quot; data-origin-height=&quot;5221&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c30bnT/btsPC8mF3tl/SsFJt2ZRIAbXCWQewkReX1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c30bnT/btsPC8mF3tl/SsFJt2ZRIAbXCWQewkReX1/img.jpg&quot; data-alt=&quot;[이미지5] Windows x64 calling convention&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c30bnT/btsPC8mF3tl/SsFJt2ZRIAbXCWQewkReX1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc30bnT%2FbtsPC8mF3tl%2FSsFJt2ZRIAbXCWQewkReX1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;5239&quot; height=&quot;5221&quot; data-filename=&quot;callingconvention_all.jpg&quot; data-origin-width=&quot;5239&quot; data-origin-height=&quot;5221&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지5] Windows x64 calling convention&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 117px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;항목&lt;/td&gt;
&lt;td style=&quot;width: 66.6666%; height: 17px;&quot; colspan=&quot;2&quot;&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;레지스터 (Register)&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;스택 (Stack)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;인수&amp;nbsp;전달&amp;nbsp;순서&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;왼쪽&amp;nbsp;&amp;rarr;&amp;nbsp;오른쪽&amp;nbsp;(Left&amp;nbsp;to&amp;nbsp;right)&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;오른쪽&amp;nbsp;&amp;rarr;&amp;nbsp;왼쪽&amp;nbsp;(Right&amp;nbsp;to&amp;nbsp;left)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;인수&amp;nbsp;전달&amp;nbsp;매체&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;RAX, RDX, R8, R9&lt;br /&gt;XMM0 ~ XMM3&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;Stack&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;스택&amp;nbsp;유지&amp;nbsp;관리&amp;nbsp;책임&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;X&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;호출자 (Caller)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;함수&amp;nbsp;이름&amp;nbsp;데코레이션&lt;/td&gt;
&lt;td style=&quot;width: 66.6666%; height: 22px;&quot; colspan=&quot;2&quot;&gt;&amp;lt;function name&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4-2-1. 인수 전달 순서&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;callingconvention1.jpg&quot; data-origin-width=&quot;3126&quot; data-origin-height=&quot;3774&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5fuoP/btsPCnlwqEz/WM5y2UXLaBlnOAQN4DjjSK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5fuoP/btsPCnlwqEz/WM5y2UXLaBlnOAQN4DjjSK/img.jpg&quot; data-alt=&quot;[이미지6] (/Od) Parameter Passing Order&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5fuoP/btsPCnlwqEz/WM5y2UXLaBlnOAQN4DjjSK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5fuoP%2FbtsPCnlwqEz%2FWM5y2UXLaBlnOAQN4DjjSK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3126&quot; height=&quot;3774&quot; data-filename=&quot;callingconvention1.jpg&quot; data-origin-width=&quot;3126&quot; data-origin-height=&quot;3774&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지6] (/Od) Parameter Passing Order&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인수는 데이터 종류에 따라 정수용 및 포인터용 레지스터와 부동소수점용 레지스터로 분리되어 전달된다. 정수형 및 포인터형 인수는 왼쪽에서 오른쪽 순서로 RCX &amp;rarr; RDX &amp;rarr; R8 &amp;rarr; R9 레지스터에 순차적으로 할당되며, 다섯 번째 이후의 인수는 오른쪽에서 왼쪽 순서로 스택에 저장된다. 부동소수점 및 SIMD 인수는 왼쪽에서 오른쪽 순서로 XMM0 ~ XMM3까지 사용된다. 이 경우에도 초과 인수는 오른쪽에서 왼쪽으로 스택에 저장된다. 이때 스택에 저장되는 인수는 모두 Shadow Space를 피해서 저장해야 한다. 구조체, 64비트 이상 정수, 16바이트 이상의 벡터 타입 등은 종류에 따라 레지스터 분할 전달, 포인터 전달, 메모리 복사 후 포인터 전달 방식으로 전달되며, 대부분의 경우 RCX~R9 또는 스택에 포인터 형태로 전달된다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4-2-2. 인수 전달 매체&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;x64 ABI에 따르면 Caller(호출자)는 함수 호출 시 항상 32byte의 Shadow Space를 스택에 미리 확보해야 하며, Callee(피호출자)는 이 공간을 자유롭게 활용할 수 있다. 이 공간은 주로 원래의 인자 값을 보존하기 위해 사용한다. 또한 디버그 빌드에서는 모든 인자를 추적 가능하도록 하기 위해, Callee(피호출자)는 함수 프롤로그에서 Shadow Space 영역에 레지스터 값을 항상 스택에 저장하는 방식으로 코드를 생성한다. 위는 디버그 빌드에 의해 나타난 결과다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;callingconvention2.jpg&quot; data-origin-width=&quot;3748&quot; data-origin-height=&quot;2726&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NoeDa/btsPCRleri6/9TSHi71pyUXBNVYlGOemP1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NoeDa/btsPCRleri6/9TSHi71pyUXBNVYlGOemP1/img.jpg&quot; data-alt=&quot;[이미지8] (/Od) Parameter Passing Medium (int_add_fun)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NoeDa/btsPCRleri6/9TSHi71pyUXBNVYlGOemP1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNoeDa%2FbtsPCRleri6%2F9TSHi71pyUXBNVYlGOemP1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3748&quot; height=&quot;2726&quot; data-filename=&quot;callingconvention2.jpg&quot; data-origin-width=&quot;3748&quot; data-origin-height=&quot;2726&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지8] (/Od) Parameter Passing Medium (int_add_fun)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정수형 및 포인터형 인수는 RCX, RDX, R8, R9 레지스터를 사용하며, 이 네 개를 초과하는 인수는 스택을 통해 전달된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;callingconvention3.jpg&quot; data-origin-width=&quot;3752&quot; data-origin-height=&quot;2667&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kTWKn/btsPC4kigHf/7jUw5s74ErRcv63kKHTMXk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kTWKn/btsPC4kigHf/7jUw5s74ErRcv63kKHTMXk/img.jpg&quot; data-alt=&quot;[이미지9] (/Od) Parameter Passing Medium (float_add_fun)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kTWKn/btsPC4kigHf/7jUw5s74ErRcv63kKHTMXk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkTWKn%2FbtsPC4kigHf%2F7jUw5s74ErRcv63kKHTMXk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3752&quot; height=&quot;2667&quot; data-filename=&quot;callingconvention3.jpg&quot; data-origin-width=&quot;3752&quot; data-origin-height=&quot;2667&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지9] (/Od) Parameter Passing Medium (float_add_fun)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부동소수점 및 SIMD 인수는 XMM0, XMM1, XMM2, XMM3까지 최대 4개 레지스터를 사용하며, 이 네 개를 초과하는 인수는 스택을 통해 전달된다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4-2-3. 스택 유지 관리 책임&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;callingconvention4.jpg&quot; data-origin-width=&quot;4416&quot; data-origin-height=&quot;3774&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVjS8Q/btsPCMdcWYK/y6ibgpS67CgxwrJl2ePIm0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVjS8Q/btsPCMdcWYK/y6ibgpS67CgxwrJl2ePIm0/img.jpg&quot; data-alt=&quot;[이미지10] (/Od) Stack Cleanup Responsibility&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVjS8Q/btsPCMdcWYK/y6ibgpS67CgxwrJl2ePIm0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVjS8Q%2FbtsPCMdcWYK%2Fy6ibgpS67CgxwrJl2ePIm0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4416&quot; height=&quot;3774&quot; data-filename=&quot;callingconvention4.jpg&quot; data-origin-width=&quot;4416&quot; data-origin-height=&quot;3774&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지10] (/Od) Stack Cleanup Responsibility&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스택 유지 관리 책임은 Caller(호출자)에게 있으며, 함수 호출 전후에 RSP 값을 원래 상태로 되돌리는 작업은 호출자가 수행해야 한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4-2-4. 함수 이름 데코레이션&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;callingconvention5.jpg&quot; data-origin-width=&quot;3126&quot; data-origin-height=&quot;3774&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b0cCAX/btsPDCVg4sT/AhikzbvwtJX6lmXXi6mx2k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b0cCAX/btsPDCVg4sT/AhikzbvwtJX6lmXXi6mx2k/img.jpg&quot; data-alt=&quot;[이미지10] (/Od) Name Decoration Scheme&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b0cCAX/btsPDCVg4sT/AhikzbvwtJX6lmXXi6mx2k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb0cCAX%2FbtsPDCVg4sT%2FAhikzbvwtJX6lmXXi6mx2k%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3126&quot; height=&quot;3774&quot; data-filename=&quot;callingconvention5.jpg&quot; data-origin-width=&quot;3126&quot; data-origin-height=&quot;3774&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지10] (/Od) Name Decoration Scheme&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수 이름 데코레이션은 적용되지 않는다. 함수 이름은 소스 코드와 동일한 이름 그대로 기록되며, 접두사나 접미사가 붙지 않는다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. Caller cleans the stack (Caller-pop / Caller-cleans)&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;callerclean1.jpg&quot; data-origin-width=&quot;4416&quot; data-origin-height=&quot;2784&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cgdErG/btsPClAvYY2/ruPo4M0LghXmnYkxkyvXzk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cgdErG/btsPClAvYY2/ruPo4M0LghXmnYkxkyvXzk/img.jpg&quot; data-alt=&quot;[이미지11] x64 Stack Cleanup&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cgdErG/btsPClAvYY2/ruPo4M0LghXmnYkxkyvXzk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcgdErG%2FbtsPClAvYY2%2FruPo4M0LghXmnYkxkyvXzk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4416&quot; height=&quot;2784&quot; data-filename=&quot;callerclean1.jpg&quot; data-origin-width=&quot;4416&quot; data-origin-height=&quot;2784&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지11] x64 Stack Cleanup&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Callee(피호출자)의 에필로그에서 add 또는 leave 명령과 같이 스택 포인터를 복원하는 코드를 확인할 수 있는데, 이는 마치 Callee가 콜스택을 정리하는 것처럼 보일 수 있다. 그러나 이러한 동작은 전적으로 Callee 내부에서 사용한 스택 프레임에 대한 정리에 불과하다. 이는 해당 명령어가 어디까지 스택을 정리하는지를 확인해 보면 쉽게 알 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;callerclean2.jpg&quot; data-origin-width=&quot;6061&quot; data-origin-height=&quot;4185&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b0Q5H6/btsPB22eU44/hskyDBaWPlSmbFPZ17POWk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b0Q5H6/btsPB22eU44/hskyDBaWPlSmbFPZ17POWk/img.jpg&quot; data-alt=&quot;[이미지12] x64 Stack Cleanup&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b0Q5H6/btsPB22eU44/hskyDBaWPlSmbFPZ17POWk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb0Q5H6%2FbtsPB22eU44%2FhskyDBaWPlSmbFPZ17POWk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;6061&quot; height=&quot;4185&quot; data-filename=&quot;callerclean2.jpg&quot; data-origin-width=&quot;6061&quot; data-origin-height=&quot;4185&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지12] x64 Stack Cleanup&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인자가 총 6개이기 때문에 4개의 인자(1, 2, 3 , 4)는 레지스터(RCX, RDX, R8, R8)로 전달되고, 나머지 2개의 인자(5, 6)은 스택으로 전달된다. 이때, Shadow Space 또한 Caller에서 할당하기 때문에 이 공간을 피해서 스택에 저장된다. 값을 확인해 보면 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;int_add_fun 함수를 호출하기 전, 스택의 상태는 위와 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;callerclean3.jpg&quot; data-origin-width=&quot;6061&quot; data-origin-height=&quot;4185&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsnIbK/btsPB3GUDt6/rZCtLenpw0tzGJHAfv7rO1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsnIbK/btsPB3GUDt6/rZCtLenpw0tzGJHAfv7rO1/img.jpg&quot; data-alt=&quot;[이미지13] x64 Stack Cleanup&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsnIbK/btsPB3GUDt6/rZCtLenpw0tzGJHAfv7rO1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbsnIbK%2FbtsPB3GUDt6%2FrZCtLenpw0tzGJHAfv7rO1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;6061&quot; height=&quot;4185&quot; data-filename=&quot;callerclean3.jpg&quot; data-origin-width=&quot;6061&quot; data-origin-height=&quot;4185&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지13] x64 Stack Cleanup&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;int_add_fun의 에필로그에 나타나는 lea rsp, [rbp+60h] 또는 add rsp, imm 명령을 실행한 결과, 이는 int_add_fun 함수 내부에서 확보했던 Local 영역만 정리하고 호출자가 전달한 인자 영역은 그대로 남아 있다는 점을 통해, 해당 명령이 정리하는 범위가 피호출자 내부의 스택 프레임에 국한된다는 사실을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;callerclean1(x32).jpg&quot; data-origin-width=&quot;5324&quot; data-origin-height=&quot;6672&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhsZDY/btsPCTcMlv6/LYq9pdpkK70dvravdWcCXk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhsZDY/btsPCTcMlv6/LYq9pdpkK70dvravdWcCXk/img.jpg&quot; data-alt=&quot;[이미지14] x32 Stack Cleanup&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhsZDY/btsPCTcMlv6/LYq9pdpkK70dvravdWcCXk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbhsZDY%2FbtsPCTcMlv6%2FLYq9pdpkK70dvravdWcCXk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;5324&quot; height=&quot;6672&quot; data-filename=&quot;callerclean1(x32).jpg&quot; data-origin-width=&quot;5324&quot; data-origin-height=&quot;6672&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지14] x32 Stack Cleanup&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;x32와 비교하면 x64 환경의 Callee(피호출자)의 에필로그에서 나타나는 스택 정리 명령은 x32에서의 mov esp, ebp 명령과 기능적으로 동일한 역할을 수행한다. 두 명령 모두 함수 진입 시 생성한 스택 프레임을 반환 직전에 원래 상태로 복구하는 용도로 사용되며, 로컬 변수 등 피호출자 내부에서 사용한 스택 영역만을 정리한다는 공통점을 가진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure data-ke-type=&quot;image&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; data-ke-style=&quot;alignLeft&quot;&gt;&lt;span class=&quot;bar_progress&quot;&gt;&lt;/span&gt;
&lt;figcaption style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;callerclean2(x32).jpg&quot; data-origin-width=&quot;5300&quot; data-origin-height=&quot;6672&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7zyac/btsPCVasbBj/fpftt1iM2HhTJDlNVYe80k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7zyac/btsPCVasbBj/fpftt1iM2HhTJDlNVYe80k/img.jpg&quot; data-alt=&quot;[이미지15] x32 Stack Cleanup&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7zyac/btsPCVasbBj/fpftt1iM2HhTJDlNVYe80k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7zyac%2FbtsPCVasbBj%2Ffpftt1iM2HhTJDlNVYe80k%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;5300&quot; height=&quot;6672&quot; data-filename=&quot;callerclean2(x32).jpg&quot; data-origin-width=&quot;5300&quot; data-origin-height=&quot;6672&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지15] x32 Stack Cleanup&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;x32에서 실제로 스택이 정리되는 동작은 mov esp, ebp 이후에 나타난다. Callee에서 스택을 정리하는 경우(stdcall, fastcall, vectorcall) ret &amp;lt;n&amp;gt;으로 스택을 정리하고, Caller에서 스택을 정리하는 경우(cdecl) add esp, imm으로 스택을 정리한다. 따라서 스택을 정리한다는 것은 단순한 로컬 프레임 복원 뿐 아니라, 함수 호출에 사용된 인자 영역까지 포함한 전체 호출 컨텍스트의 정리를 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;callerclean4.jpg&quot; data-origin-width=&quot;6077&quot; data-origin-height=&quot;4185&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cziwhN/btsPCpCOfMj/aIiKgBoro9lLZATld4kvQ1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cziwhN/btsPCpCOfMj/aIiKgBoro9lLZATld4kvQ1/img.jpg&quot; data-alt=&quot;[이미지16] x64 Stack Cleanup&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cziwhN/btsPCpCOfMj/aIiKgBoro9lLZATld4kvQ1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcziwhN%2FbtsPCpCOfMj%2FaIiKgBoro9lLZATld4kvQ1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;6077&quot; height=&quot;4185&quot; data-filename=&quot;callerclean4.jpg&quot; data-origin-width=&quot;6077&quot; data-origin-height=&quot;4185&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지16] x64 Stack Cleanup&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;x64에서 함수를 호출할 때 사용했던 Shadow Space와 Argument의 영역의 정리는 로컬 영역과 인자 영역을 포함한 전체 호출 컨텍스트의 정리를 의미한다. x32에서는 보통 Callee(피호출자)의 에필로그, 함수 호출 이후 Caller(호출자)의 바디에서 이루어진다. 반면, x64에서는 x32와는 다르게 Caller(호출자)의 에필로그에서 스택을 정리한다. 여기서 한가지 이상한 점이 있는데 Caller(호출자)의 에필로그에서 스택을 정리하는 동작은 모든 Caller(호출자) 함수에 존재한다는 것이다. 이 동작은 x32에서 __stdcall, __fastcall, __vectorcall 함수 호출 규약 역시 포함하고 있다. 그렇다면 모든 함수의 스택 정리 책임은 무조건 Caller(호출자)에 있는 것일까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stackclean1.jpg&quot; data-origin-width=&quot;4521&quot; data-origin-height=&quot;6561&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDFoJN/btsPDIhj3oz/ymk1G5JsklRGkK5npbHDxk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDFoJN/btsPDIhj3oz/ymk1G5JsklRGkK5npbHDxk/img.jpg&quot; data-alt=&quot;[이미지17] Local Area Cleanup&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDFoJN/btsPDIhj3oz/ymk1G5JsklRGkK5npbHDxk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDFoJN%2FbtsPDIhj3oz%2Fymk1G5JsklRGkK5npbHDxk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4521&quot; height=&quot;6561&quot; data-filename=&quot;stackclean1.jpg&quot; data-origin-width=&quot;4521&quot; data-origin-height=&quot;6561&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지17] Local Area Cleanup&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스택 정리 책임을 구분할 때는 로컬 영역과 인자 영역이라는 두 가지 서로 다른 영역을 구분해야 한다. 로컬 영역은 함수 내부에서 생성된 임시 데이터나 지역 변수를 저장하기 위한 공간으로, 언제나 해당 함수인 Callee(피호출자)가 진입 시 확보하고 반환 시 정리한다. 따라서 실행 환경과 호출 규약에 관계없이 로컬 영역은 언제나 Callee의 프롤로그에서 할당되고 에필로그에서 정리되는 것이 정해진 규칙이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stackclean2.jpg&quot; data-origin-width=&quot;4521&quot; data-origin-height=&quot;6561&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oikmw/btsPC8HBdxq/KCTmnhSHknQIxZBhu52Gy0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oikmw/btsPC8HBdxq/KCTmnhSHknQIxZBhu52Gy0/img.jpg&quot; data-alt=&quot;[이미지18] Argument Area Cleanup&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oikmw/btsPC8HBdxq/KCTmnhSHknQIxZBhu52Gy0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Foikmw%2FbtsPC8HBdxq%2FKCTmnhSHknQIxZBhu52Gy0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4521&quot; height=&quot;6561&quot; data-filename=&quot;stackclean2.jpg&quot; data-origin-width=&quot;4521&quot; data-origin-height=&quot;6561&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지18] Argument Area Cleanup&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스택 정리 책임이 어디에 있는지를 구분 할 때, 그 대상은 로컬 영역이 아니라 인자 영역에 한정된다. 함수 내부에서 사용되는 로컬 영역은 항상 Callee(피호출자)가 진입 시 할당하고 반환 시 정리하는 것으로 규약상 고정되어 있다. 여기에서는 스택 정리 책임을 구분 할 필요가 없다. 반면, 인자 영역에서는 가변 인자를 고려해 Caller(호출자)와 Callee(피호출자) 중 어디서 스택을 정리하는지를 구분해야 한다. 이 영역은 호출 규약에 따라 어느 쪽이 정리할지가 결정된다. 따라서 스택 정리 책임이라는 표현은 오직 인자 영역을 대상으로 한 개념이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 107px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 29.1473%; height: 22px;&quot;&gt;함수 호출 규약&lt;/td&gt;
&lt;td style=&quot;width: 20.6589%; height: 22px;&quot;&gt;로컬 영역&lt;/td&gt;
&lt;td style=&quot;width: 27.8294%; height: 22px;&quot;&gt;스택 정리 책임 (인자 영역)&lt;/td&gt;
&lt;td style=&quot;width: 22.3644%; height: 22px;&quot;&gt;위치&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 29.1473%; height: 17px;&quot;&gt;__stdcall (x32)&lt;/td&gt;
&lt;td style=&quot;width: 20.6589%; height: 17px;&quot;&gt;Callee(피호출자)&lt;/td&gt;
&lt;td style=&quot;width: 27.8294%; height: 17px;&quot;&gt;Callee&amp;nbsp;(피호출자)&lt;/td&gt;
&lt;td style=&quot;width: 22.3644%; height: 17px;&quot;&gt;Callee Epilogue&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 29.1473%; height: 17px;&quot;&gt;__cdecl (x32)&lt;/td&gt;
&lt;td style=&quot;width: 20.6589%; height: 17px;&quot;&gt;Callee(피호출자)&lt;/td&gt;
&lt;td style=&quot;width: 27.8294%; height: 17px;&quot;&gt;Caller&amp;nbsp;(호출자)&lt;/td&gt;
&lt;td style=&quot;width: 22.3644%; height: 17px;&quot;&gt;Caller&amp;nbsp;Body&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 29.1473%; height: 17px;&quot;&gt;__fastcall (x32)&lt;/td&gt;
&lt;td style=&quot;width: 20.6589%; height: 17px;&quot;&gt;Callee(피호출자)&lt;/td&gt;
&lt;td style=&quot;width: 27.8294%; height: 17px;&quot;&gt;Callee&amp;nbsp;(피호출자)&lt;/td&gt;
&lt;td style=&quot;width: 22.3644%; height: 17px;&quot;&gt;Callee&amp;nbsp;Epilogue&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 29.1473%; height: 17px;&quot;&gt;__vectorcall (x32)&lt;/td&gt;
&lt;td style=&quot;width: 20.6589%; height: 17px;&quot;&gt;Callee(피호출자)&lt;/td&gt;
&lt;td style=&quot;width: 27.8294%; height: 17px;&quot;&gt;Callee&amp;nbsp;(피호출자)&lt;/td&gt;
&lt;td style=&quot;width: 22.3644%; height: 17px;&quot;&gt;Callee&amp;nbsp;Epilogue&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 29.1473%; height: 17px;&quot;&gt;x64&amp;nbsp;calling&amp;nbsp;convention&amp;nbsp;(x64)&lt;/td&gt;
&lt;td style=&quot;width: 20.6589%; height: 17px;&quot;&gt;Callee(피호출자)&lt;/td&gt;
&lt;td style=&quot;width: 27.8294%; height: 17px;&quot;&gt;Caller&amp;nbsp;(호출자)&lt;/td&gt;
&lt;td style=&quot;width: 22.3644%; height: 17px;&quot;&gt;Caller&amp;nbsp;Epilogue&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 &quot;모든 함수의 스택 정리 책임은 무조건 Caller(호출자)에 있는 것일까?&quot;라는 질문에 대한 답은 &quot;x32에서 그렇지 않다.&quot;는 것이다. x32의 __stdcall, __fastcall, __vectorcall에서는 인자 영역이 Callee(피호출자)에 의해 정리되므로 스택 정리 책임은 Callee(피호출자)에게 있다(__cdecl은 호출자). 그렇기 때문에 스택 정리 책임이 무조건 Caller(호출자)에게 있다고 할 수 없다. 반면 x64에서는 호출 규약이 하나로 통일되었기 때문에 인자 영역 정리는 항상 Caller(호출자)의 책임으로 고정되어 있다. 그렇기 때문에 스택 정리 책임이 일관되게 Caller(호출자)에 있다고 할 수 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;6. 가변인자 (Variadic&amp;nbsp;Arguments)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6-1. 예제 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753858170989&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdarg.h&amp;gt;

int main(void)
{
    int total1 = var_add_fun(10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
    int total2 = var_add_fun(3, 1, 2, 3);
    int total3 = var_add_fun(3, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20);
    int total4 = var_add_fun(1000);

    printf(&quot;total1 = %d\ntotal2 = %d\ntotal3 = %d\ntotal4 = %d\n&quot;, total1, total2, total3, total4);
    return 0;
}

int var_add_fun(int count, ...)
{
    int result = 0;
    va_list args;
    va_start(args, count);
    for (int i = 0; i &amp;lt; count; ++i) {
        result += va_arg(args, int);
    }
    va_end(args);
    return result;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;위 코드는 가변 인자 n개를 모두 더한 뒤 그 합계를  printf로 출력하고 종료하는 프로그램이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;580&quot; data-origin-height=&quot;273&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c2t7mH/btsPDGqxkkz/lhBaXmdpomcU7vcg3BkNg0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c2t7mH/btsPDGqxkkz/lhBaXmdpomcU7vcg3BkNg0/img.png&quot; data-alt=&quot;[이미지19] 실행 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c2t7mH/btsPDGqxkkz/lhBaXmdpomcU7vcg3BkNg0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc2t7mH%2FbtsPDGqxkkz%2FlhBaXmdpomcU7vcg3BkNg0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;580&quot; height=&quot;273&quot; data-origin-width=&quot;580&quot; data-origin-height=&quot;273&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지19] 실행 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 90px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 15.5427%; height: 22px;&quot;&gt;변수&lt;/td&gt;
&lt;td style=&quot;width: 26.4727%; height: 22px;&quot;&gt;count (덧셈 인자의 수)&lt;/td&gt;
&lt;td style=&quot;width: 37.3062%; height: 22px;&quot;&gt;덧셈&lt;/td&gt;
&lt;td style=&quot;width: 20.6784%;&quot;&gt;결과&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 15.5427%; height: 17px;&quot;&gt;total1&lt;/td&gt;
&lt;td style=&quot;width: 26.4727%; height: 17px;&quot;&gt;10&lt;/td&gt;
&lt;td style=&quot;width: 37.3062%; height: 17px;&quot;&gt;1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10&lt;/td&gt;
&lt;td style=&quot;width: 20.6784%;&quot;&gt;55&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 15.5427%; height: 17px;&quot;&gt;total2&lt;/td&gt;
&lt;td style=&quot;width: 26.4727%; height: 17px;&quot;&gt;3&lt;/td&gt;
&lt;td style=&quot;width: 37.3062%; height: 17px;&quot;&gt;1 + 2 + 3&lt;/td&gt;
&lt;td style=&quot;width: 20.6784%;&quot;&gt;6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 15.5427%; height: 17px;&quot;&gt;total3&lt;/td&gt;
&lt;td style=&quot;width: 26.4727%; height: 17px;&quot;&gt;3&lt;/td&gt;
&lt;td style=&quot;width: 37.3062%; height: 17px;&quot;&gt;1 + 2 + 3&lt;/td&gt;
&lt;td style=&quot;width: 20.6784%;&quot;&gt;6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 15.5427%; height: 17px;&quot;&gt;total4&lt;/td&gt;
&lt;td style=&quot;width: 26.4727%; height: 17px;&quot;&gt;1000&lt;/td&gt;
&lt;td style=&quot;width: 37.3062%; height: 17px;&quot;&gt;&lt;span style=&quot;background-color: #f9f9f9; color: #333333; text-align: start;&quot;&gt;trash_value +&lt;/span&gt;&lt;span style=&quot;background-color: #f9f9f9; color: #333333; text-align: start;&quot;&gt; ... &lt;span style=&quot;background-color: #f9f9f9; color: #333333; text-align: start;&quot;&gt;+&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #f9f9f9; color: #333333; text-align: start;&quot;&gt;trash_value&lt;/span&gt; &lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20.6784%;&quot;&gt;&lt;span style=&quot;background-color: #f9f9f9; color: #333333; text-align: start;&quot;&gt;-1641958797&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6-2. 어셈블리 코드&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;6-2-1. main&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;main (1).png&quot; data-origin-width=&quot;950&quot; data-origin-height=&quot;1351&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wV1oA/btsPEuQGXFE/jxZTjtKYEH1mDf2pyGqMSk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wV1oA/btsPEuQGXFE/jxZTjtKYEH1mDf2pyGqMSk/img.png&quot; data-alt=&quot;[이미지20] main&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wV1oA/btsPEuQGXFE/jxZTjtKYEH1mDf2pyGqMSk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwV1oA%2FbtsPEuQGXFE%2FjxZTjtKYEH1mDf2pyGqMSk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;950&quot; height=&quot;1351&quot; data-filename=&quot;main (1).png&quot; data-origin-width=&quot;950&quot; data-origin-height=&quot;1351&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지20] main&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;6-2-2. var_add_fun&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;var_add_fun (1).png&quot; data-origin-width=&quot;950&quot; data-origin-height=&quot;867&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/A5DA7/btsPCjC8NMl/Ywk6gaIWTaKNeFbwO8GcwK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/A5DA7/btsPCjC8NMl/Ywk6gaIWTaKNeFbwO8GcwK/img.png&quot; data-alt=&quot;[이미지21] var_add_fun&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/A5DA7/btsPCjC8NMl/Ywk6gaIWTaKNeFbwO8GcwK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FA5DA7%2FbtsPCjC8NMl%2FYwk6gaIWTaKNeFbwO8GcwK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;950&quot; height=&quot;867&quot; data-filename=&quot;var_add_fun (1).png&quot; data-origin-width=&quot;950&quot; data-origin-height=&quot;867&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지21] var_add_fun&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6-3. x64의 가변인자 처리&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;var_add1.jpg&quot; data-origin-width=&quot;3962&quot; data-origin-height=&quot;3615&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bREg8J/btsPHgFdBDl/0XGsCPllJ0bfz9qSERgH7k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bREg8J/btsPHgFdBDl/0XGsCPllJ0bfz9qSERgH7k/img.jpg&quot; data-alt=&quot;[이미지22] var_add_fun&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bREg8J/btsPHgFdBDl/0XGsCPllJ0bfz9qSERgH7k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbREg8J%2FbtsPHgFdBDl%2F0XGsCPllJ0bfz9qSERgH7k%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3962&quot; height=&quot;3615&quot; data-filename=&quot;var_add1.jpg&quot; data-origin-width=&quot;3962&quot; data-origin-height=&quot;3615&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지22] var_add_fun&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;var_add_fun 함수가 동작하는 방식은 매우 단순하다. va_start를 통해 가변인자의 시작 주소(count 다음 인자)를 지정한다. 이후 count 만큼 인자를 result에 누산한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;var_add2.jpg&quot; data-origin-width=&quot;9000&quot; data-origin-height=&quot;3101&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bYK9ox/btsPClnl1FH/VTdiTuJQhuL79W5V5iWx4k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bYK9ox/btsPClnl1FH/VTdiTuJQhuL79W5V5iWx4k/img.jpg&quot; data-alt=&quot;[이미지23] var_add_fun&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bYK9ox/btsPClnl1FH/VTdiTuJQhuL79W5V5iWx4k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbYK9ox%2FbtsPClnl1FH%2FVTdiTuJQhuL79W5V5iWx4k%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;9000&quot; height=&quot;3101&quot; data-filename=&quot;var_add2.jpg&quot; data-origin-width=&quot;9000&quot; data-origin-height=&quot;3101&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지23] var_add_fun&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인자의 수가 가변적이라 하더라도 인자는 Caller(호출자)에 의해 호출 시점에 스택에 적재되므로 Callee(피호출자)의 로컬 영역 크기에는 영향을 미치지 않는다. 즉, var_add_fun(int count, ...)과 같은 가변 인자 함수에서 count 이후의 가변 인자들은 단순히 기존 스택 프레임 상의 인자 영역을 순회하는 방식으로 동작한다. 따라서 가변 인자의 존재 여부나 개수는 함수 내부에서 별도의 로컬 변수를 추가로 선언하거나, 스택 공간을 새로 확보해야 하는 요소가 아니므로 Callee(피호출자)의 로컬 영역 크기는 일정하게 유지된다. x32도 같은 방식으로 동작한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;var_add3.jpg&quot; data-origin-width=&quot;3962&quot; data-origin-height=&quot;3615&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dnqeJn/btsPDN4fD7V/vIe7Nef6VugZYBkg4YIqr0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dnqeJn/btsPDN4fD7V/vIe7Nef6VugZYBkg4YIqr0/img.jpg&quot; data-alt=&quot;[이미지24] var_add_fun&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dnqeJn/btsPDN4fD7V/vIe7Nef6VugZYBkg4YIqr0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdnqeJn%2FbtsPDN4fD7V%2FvIe7Nef6VugZYBkg4YIqr0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3962&quot; height=&quot;3615&quot; data-filename=&quot;var_add3.jpg&quot; data-origin-width=&quot;3962&quot; data-origin-height=&quot;3615&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지24] var_add_fun&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 인자의 수가 가변적 이더라도 Callee(피호출자)는 자신이 확보한 로컬 영역을 명확히 알고 있기 때문에 에필로그에서 정확하게 정리할 수 있다. 하지만 x64에서도 마찬가지로 Callee(피호출자)는 가변 인자의 수를 알 수 없기 때문에, 인자 영역 전체의 정리는 Caller(호출자)가 책임진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;var_add4.jpg&quot; data-origin-width=&quot;3962&quot; data-origin-height=&quot;5630&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dpYO5J/btsPDsTAmuD/0oijBCf9cyZ4CARiCmkm5k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dpYO5J/btsPDsTAmuD/0oijBCf9cyZ4CARiCmkm5k/img.jpg&quot; data-alt=&quot;[이미지25] main&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dpYO5J/btsPDsTAmuD/0oijBCf9cyZ4CARiCmkm5k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdpYO5J%2FbtsPDsTAmuD%2F0oijBCf9cyZ4CARiCmkm5k%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3962&quot; height=&quot;5630&quot; data-filename=&quot;var_add4.jpg&quot; data-origin-width=&quot;3962&quot; data-origin-height=&quot;5630&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지25] main&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;x64 함수 호출 규약에서는 인자 전달을 위한 스택 영역(Shadow Space 포함)을 Caller(호출자)가 함수 호출 직전에 한 번에 확보하고, 한 번에 정리한다. Caller(호출자)는 호출 당시 가변 인자의 개수와 전체 크기를 알고 있으므로 스택을 정리할 수 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;7. x32와 x64의 인자 영역 비교&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;7-1. Push Model (x32 Calling Convention)&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;pushmov.jpg&quot; data-origin-width=&quot;6060&quot; data-origin-height=&quot;4661&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/czmeMc/btsPEsek1BA/L4wsvYDwHhi4WaXJwCETH1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/czmeMc/btsPEsek1BA/L4wsvYDwHhi4WaXJwCETH1/img.jpg&quot; data-alt=&quot;[이미지26] push model&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/czmeMc/btsPEsek1BA/L4wsvYDwHhi4WaXJwCETH1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FczmeMc%2FbtsPEsek1BA%2FL4wsvYDwHhi4WaXJwCETH1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;6060&quot; height=&quot;4661&quot; data-filename=&quot;pushmov.jpg&quot; data-origin-width=&quot;6060&quot; data-origin-height=&quot;4661&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지26] push model&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;x32에서 인자를 스택으로 전달할 때는 주로 push 명령어를 통해 인자를 하나씩 역순으로 적재하는 방식이 사용된다. 따라서 호출되는 함수마다 인자의 개수에 따라 스택에 쌓이는 Argument 영역의 크기가 달라진다는 특징을 갖는다. 이러한 구조에서는 각 호출 지점마다 Argument 영역의 형태가 일정하게 유지되지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;pushmov1.jpg&quot; data-origin-width=&quot;5010&quot; data-origin-height=&quot;4622&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dzd32A/btsPDbq1kAW/EKUaC6rURh1wKBreNaLLzk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dzd32A/btsPDbq1kAW/EKUaC6rURh1wKBreNaLLzk/img.jpg&quot; data-alt=&quot;[이미지27] Push Model&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dzd32A/btsPDbq1kAW/EKUaC6rURh1wKBreNaLLzk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdzd32A%2FbtsPDbq1kAW%2FEKUaC6rURh1wKBreNaLLzk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;5010&quot; height=&quot;4622&quot; data-filename=&quot;pushmov1.jpg&quot; data-origin-width=&quot;5010&quot; data-origin-height=&quot;4622&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지27] Push Model&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;x32에서는 주로 push 명령을 사용해 인자를 스택에 적재하므로, 함수를 호출할 때마다 인자의 수만큼 스택에 쌓이게 되며, 이러한 호출이 반복될수록 인자 영역이 누적되어 전체 스택 사용량이 점점 증가한다. 같은 함수가 반복적으로 호출되는 경우, 컴파일 시점에는 최종적으로 얼마나 많은 인자들이 스택에 쌓일지 예측할 수 없기 때문에, 누적된 인자들로 인해 Stack Overflow 예외가 발생할 수 있다. 이러한 위험을 방지하기 위해, __cdecl에서는 함수 호출 직후 add esp, imm의 명령을 통해 곧바로 인자 영역을 정리하며, __stdcall, __fastcall, __vectorcall에서는 함수 동작이 완료된 직후, Callee(피호출자)에서 해당 인자 영역을 곧바로 정리한다. 이를 통해 인자 누적으로 인한 스택 오버플로우를 사전에 차단할 수 있도록 설계되어 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;7-2. Mov Model (x64 Calling Convention)&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;pushmov2.jpg&quot; data-origin-width=&quot;6060&quot; data-origin-height=&quot;4185&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nMoJZ/btsPDoDMxlf/q4ESMCbd8gE0Pkp6TETqS1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nMoJZ/btsPDoDMxlf/q4ESMCbd8gE0Pkp6TETqS1/img.jpg&quot; data-alt=&quot;[이미지28] Mov Model&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nMoJZ/btsPDoDMxlf/q4ESMCbd8gE0Pkp6TETqS1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnMoJZ%2FbtsPDoDMxlf%2Fq4ESMCbd8gE0Pkp6TETqS1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;6060&quot; height=&quot;4185&quot; data-filename=&quot;pushmov2.jpg&quot; data-origin-width=&quot;6060&quot; data-origin-height=&quot;4185&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지28] Mov Model&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;x64에서 인자를 스택으로 전달할 때는 주로 한번에 스택을 확보한 뒤, mov 명령어를 통해 인자를 적재하는 방식이 사용된다. 따라서 호출되는 함수의 인자의 개수에 상관없이 Argument 영역의 크기가 고정적이라는 특징을 갖는다. 이러한 구조에서는 각 호출 지점마다 Argument 영역의 형태가 일정하게 유지된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;pushmov3.jpg&quot; data-origin-width=&quot;6060&quot; data-origin-height=&quot;4185&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/B0R2A/btsPB2VVmxC/BkvYO5j2Tm3zDuusJkT4R1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/B0R2A/btsPB2VVmxC/BkvYO5j2Tm3zDuusJkT4R1/img.jpg&quot; data-alt=&quot;[이미지29] Mov Model&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/B0R2A/btsPB2VVmxC/BkvYO5j2Tm3zDuusJkT4R1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FB0R2A%2FbtsPB2VVmxC%2FBkvYO5j2Tm3zDuusJkT4R1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;6060&quot; height=&quot;4185&quot; data-filename=&quot;pushmov3.jpg&quot; data-origin-width=&quot;6060&quot; data-origin-height=&quot;4185&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지29] Mov Model&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;호출되는 함수들은 Argument 영역을 공유하는 방식으로 동작하며, mov 명령어를 통해 각 함수는 이전 호출에서 사용된 인자 위에 자신의 인자를 덮어쓰는 방식으로 이 영역을 재사용한다. 이때, 인자 값을 별도로 지우는 동작은 존재하지 않으며, 새로운 호출이 기존 값을 무시하고 자신의 값으로 덮기 때문에 정리가 불필요하다. 이와 같은 구조를 고려해 컴파일러는 모든 함수 호출에서 필요한 최대 인자 공간을 분석한 뒤, 함수 프롤로그에서 sub rsp, imm 명령을 통해 확보할 전체 스택 공간에 해당 Argument 영역까지 포함시킨다. 고정된 크기의 공유 영역을 반복적으로 덮어쓰며 사용하는 방식으로 효율성과 정렬 요건을 동시에 만족할 수 있게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;pushmov4.jpg&quot; data-origin-width=&quot;3240&quot; data-origin-height=&quot;3865&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ouX0q/btsPGENdJSm/8DWgwTkga1vT4OYKSISHW1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ouX0q/btsPGENdJSm/8DWgwTkga1vT4OYKSISHW1/img.jpg&quot; data-alt=&quot;[이미지30] Mov Model&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ouX0q/btsPGENdJSm/8DWgwTkga1vT4OYKSISHW1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FouX0q%2FbtsPGENdJSm%2F8DWgwTkga1vT4OYKSISHW1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3240&quot; height=&quot;3865&quot; data-filename=&quot;pushmov4.jpg&quot; data-origin-width=&quot;3240&quot; data-origin-height=&quot;3865&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지30] Mov Model&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;x64에서는 주로 mov 명령을 사용해 인자를 스택에 적재하므로, 같은 함수를 여러 번 호출하더라도 Argument 영역의 크기는 고정적으로 유지된다. 이는 인자 전달을 위한 메모리 공간이 호출 시마다 새로 쌓이는 것이 아니라, 미리 확보된 일정한 영역에 값을 덮어쓰는 방식으로 구성되기 때문이다. 반면 x32의 push Model은 호출할 때마다 인자 수만큼 스택이 확장되기 때문에 호출이 반복될수록 인자들이 누적되는 구조이며, 이를 정리하지 않으면 Stack Overflow 예외가 발생할 수 있다. x64에서는 이러한 Argument 영역의 누적이 발생하지 않기 때문에, 함수 호출 이후 곧바로 인자를 정리하는 명령이 필요하지 않게 된다. 따라서 Caller(호출자)의 에필로그에서 한번에 전체 스택을 정리할 수 있는것이다. 다만, 함수의 호출이 깊어지는 경우에는 Stack Overflow 예외가 발생할 수 있다. 이러한 상황은 인자 영역의 누적이 아닌, 반복된 호출로 인한 전체 프레임의 중첩으로 인해 발생한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;7-3. x32와 x64의 인자 전달 구조 차이의 설계 배경&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;32bit 환경은 4byte 정렬만 지키면 되었기 때문에, push 명령을 연속적으로 사용해 인자를 스택에 쌓아도 정렬 문제가 발생하지 않았다. push는 값 저장과 스택 포인터 조정을 1byte 명령으로 처리할 수 있어 코드 밀도와 실행 효율 면에서도 매우 유리했으며, 제한된 레지스터 수와 함께 레지스터를 아끼기 위한 현실적인 대안이었다. 반면 64bit 환경은 ABI 수준에서 스택 포인터(RSP)가 16바이트 정렬을 유지해야 하며, 함수 바디에서는 push 명령 사용이 사실상 금지된다. 이는 push가 8byte 단위로 RSP를 변경하기 때문에 사용 시 정렬을 깨뜨리기 때문이다. 이러한 제약 속에서 x64는 프롤로그에서 미리 스택 공간을 한 번에 확보한 뒤, 그 안에서 각 인자를 mov 명령으로 고정된 오프셋에 저장하는 모델로 전환되었다. 이 방식을 통해 스택 정렬을 유지할 수 있었으며, 고정된 주소 오프셋에 접근하므로 실행이나 메모리 접근 최적화에도 유리했다. 결국 x32와 x64의 인자 전달 방식 차이는 아키텍처별 정렬 요건과 ABI에서 요구하는 제약 조건 등 구조적인 설계 원칙에 따라 결정된 결과이다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;8. 참고 문헌&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;[1] x64 호출 규칙,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/cpp/build/x64-calling-convention?view=msvc-170&quot;&gt;https://learn.microsoft.com/ko-kr/cpp/build/x64-calling-convention?view=msvc-170&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Reversing/Definition</category>
      <category>Calling Convention</category>
      <category>x64</category>
      <category>함수 호출 규약</category>
      <author>kj0on</author>
      <guid isPermaLink="true">https://kj0on.tistory.com/44</guid>
      <comments>https://kj0on.tistory.com/44#entry44comment</comments>
      <pubDate>Sat, 19 Jul 2025 21:13:40 +0900</pubDate>
    </item>
    <item>
      <title>[Definition] 64비트 스택 프레임 (64bit Stack Frame)</title>
      <link>https://kj0on.tistory.com/43</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;0. x64 ABI&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;x64 ABI는 &lt;a href=&quot;https://kj0on.tistory.com/47&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://kj0on.tistory.com/47&lt;/a&gt; 참고&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 정의&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스택 프레임(Stack Frame)은 함수가 호출될 때 스택에 형성되는 하나의 논리적 메모리 블록으로, 해당 함수 실행에 필요한 정보를 일시적으로 보관해 주는 단위이다. 32비트 때와 유사한 목적을 가지지만, 64비트 함수 호출 규약과 CPU 설계 변화에 맞추어 구조와 규칙이 달라졌다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 함수 프레임 (Function Frame)&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3185&quot; data-origin-height=&quot;2518&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cq0evL/btsPfiyaKoa/19c0dK0fsxShp8uCOM56pK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cq0evL/btsPfiyaKoa/19c0dK0fsxShp8uCOM56pK/img.jpg&quot; data-alt=&quot;[이미지1] 실행 흐름&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cq0evL/btsPfiyaKoa/19c0dK0fsxShp8uCOM56pK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcq0evL%2FbtsPfiyaKoa%2F19c0dK0fsxShp8uCOM56pK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3185&quot; height=&quot;2518&quot; data-origin-width=&quot;3185&quot; data-origin-height=&quot;2518&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지1] 실행 흐름&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;함수의 시작에 붙는 패턴은 프롤로그(prologue), 끝 부분에 붙는 패턴은 에필로그(epilogue)로 구분할 수 있으며, 직접 작성한 코드의 로직은 두 패턴 사이의 바디(body)에 위치하게 된다. 이러한 공통된 틀은 컴파일 단계에서 컴파일러가 자동으로 삽입한다. 덕분에 모든 함수가 일관된 스택 프레임을 유지할 수 있게 되며 중첩 호출 상황에서도 데이터와 복귀 주소가 안전하게 보호된다. x86에서는 함수의 프롤로그와 에필로그가 상대적으로 정형화된 형태로 나타난다. 그러나 x64에서는 프롤로그와 에필로그의 형태가 하나로 고정되지 않으며, 함수의 특성이나 컴파일 옵션, 최적화 여부 등에 따라 여러 가지 방식으로 다양하게 구성될 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;Frame Pointer Omission&lt;br /&gt;Unlike the X86 CPU where the EBP register is used to access parameters and local variables on the stack, X64 functions do not make use of the RBP register for this purpose i.e. do not use the EBP register as a frame pointer. Instead, it uses the RSP register both as a stack pointer and a frame pointer, more on how this works in the next topic. So, on X64 the RBP register is now freed up from its stack duties and can be used as a general purpose register. An exception to this rule are functions that use alloca() to dynamically allocate space on the stack. Such functions will use the RBP register as a frame pointer, as they did with EBP on the X86.&lt;br /&gt;&lt;br /&gt;Stack Pointer based local variable access&lt;br /&gt;On the X86 CPU, the most important function of the frame pointer (EBP) register is to provide access to stack based parameters and local variables. As discussed earlier, on the X64 CPU, the RBP register does not point to the stack frame of the current function. So on X64, it is the RSP register that has to serve both as a stack pointer as well as a frame pointer. So all stack references on X64 are performed based on RSP. Due to this, functions on X64 depend on the RSP register being static throughout the function body, serving as a frame of reference for accessing locals and parameters. Since push and pop instructions alter the stack pointer, X64 functions restrict push and pop instructions to the function prolog and epilog respectively. The fact that the stack pointer does not change at all between the prolog and the epilog is a characteristic feature of X64 functions, as shown in Figure 3.&lt;/blockquote&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;x86에서는 EBP가 스택의 기준점이 되어 매개변수와 지역 변수를 안정적으로 참조하지만, x64에서 RBP는 더 이상 프레임 포인터로 사용되지 않는다(다른 레지스터와 마찬가지로 범용 레지스터로 사용될 수 있음). RBP가 더 이상 현재 프레임을 가리키지 않으므로 RSP가 스택 포인터와 프레임 포인터 두 역할을 동시에 맡아야 한다. 이 때문에 모든 스택 접근은 RSP를 기준으로 이루어지고, push, pop 명령어는 스택 포인터를 변경하므로 x64 함수는 해당 명령어를 함수 프롤로그와 에필로그로 제한된다. 단, alloca()를 사용하여 스택 공간을 동적으로 할당하는 함수는 예외로 x86의 EBP와 마찬가지로 RBP 레지스터를 프레임 포인터로 사용한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;prolog.jpg&quot; data-origin-width=&quot;3411&quot; data-origin-height=&quot;1654&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biJiwm/btsPrq2R91w/MNZq58L8P6MzZknOgfoBj0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biJiwm/btsPrq2R91w/MNZq58L8P6MzZknOgfoBj0/img.jpg&quot; data-alt=&quot;[이미지2] x64 prologue &amp;amp;amp; epilogue&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biJiwm/btsPrq2R91w/MNZq58L8P6MzZknOgfoBj0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbiJiwm%2FbtsPrq2R91w%2FMNZq58L8P6MzZknOgfoBj0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3411&quot; height=&quot;1654&quot; data-filename=&quot;prolog.jpg&quot; data-origin-width=&quot;3411&quot; data-origin-height=&quot;1654&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지2] x64 prologue &amp;amp; epilogue&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;추가적으로 알아야 할 점은 특정 조건에서는 다시 RBP가 프레임 포인터 역할을 수행할 수 있다는 것이다. 즉, 모든 스택 접근이 반드시 RSP를 기준으로 이루어지는 것은 아니며, 상황에 따라 RBP를 기준점으로 사용하는 x86 방식이 다시 등장할 수 있다. 이는 디버깅을 용이하게 하고 RSP가 함수 바디에서 변동될 가능성이 있는 상황에서 안정적인 기준점 역할을 하기 위함이다. 따라서 x64에서 RBP는 항상 생략되는 것도, 항상 사용되는 것도 아닌 선택적인 옵션에 해당한다는 사실을 이해해야 한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 238px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;패턴&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;프롤로그 시퀀스&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;에필로그 시퀀스&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;Opt-Full&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;(없음)&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;(없음)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;Opt-Mid&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;sub rsp, imm&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;add rsp, imm&lt;br /&gt;ret&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 53px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 53px;&quot;&gt;Leaf&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 53px;&quot;&gt;push&amp;nbsp;rbp&lt;br /&gt;sub&amp;nbsp;rsp,&amp;nbsp;imm &lt;br /&gt;mov rbp, rsp&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 53px;&quot;&gt;lea rsp, [rbp+imm]&lt;br /&gt;pop rbp&lt;br /&gt;ret&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 53px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 53px;&quot;&gt;Non-Leaf&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 53px;&quot;&gt;push&amp;nbsp;rbp &lt;br /&gt;sub&amp;nbsp;rsp,&amp;nbsp;imm+20h &lt;br /&gt;lea&amp;nbsp;rbp,&amp;nbsp;[rsp+20h]&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 53px;&quot;&gt;lea rsp, [rbp+imm]&lt;br /&gt;pop rbp&lt;br /&gt;ret&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;x64 함수 프롤로그, 에필로그는 최적화 수준 및 함수 호출 여부에 따라 대표적으로 네 가지 패턴으로 분류할 수 있다. 최적화가 활성화된 경우에는 Opt-Full 또는 Opt-Mid 패턴이 나타난다. 반면, 최적화가 꺼져 있거나 디버깅을 위한 정보가 필요한 경우에는 Leaf 또는 Non-Leaf 패턴이 등장하며, RBP를 프레임 포인터로 복원한다. 다만 이러한 네 가지 분류 외에도 함수의 구조나 요구사항에 따라 다양한 형태의 프롤로그, 에필로그가 존재할 수 있으며, 이는 내부적 조건에 따라 달라진다. 따라서 실제 컴파일 결과에서는 대표적인 패턴을 벗어난 변형된 구조가 나타날 수 있다. 특히 위의 분류는 주관적 판단에 의한 것이므로, 전반적인 컴파일러 구현이나 ABI 사양을 완전히 대변한다고 보기에는 한계가 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;함수, 최적화&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;패턴&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;Leaf function, /Od&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;Leaf&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;non-Leaf function, /Od&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;Non-Leaf&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;Leaf alloca function, /Od&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;Leaf&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;non-Leaf alloca function, /Od&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;Non-Leaf&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;Leaf function, /O1&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;Opt-Full&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;non-Leaf function, /O1&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;Opt-Full&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;Leaf alloca function, /O1&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;Leaf&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;non-Leaf alloca function, /O1&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;Non-Leaf&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최적화 수준과 함수 형태에 따라 프롤로그 패턴은 다르게 나타난다. /Od처럼 최적화가 꺼진 경우 Leaf, Non-Leaf 패턴을 따른다. /O1과 같이 최적화가 적용된 경우에는 Opt-Full 패턴으로 축소되며 이는 작성 코드에 따라 달라진다. main의 경우 Opt-Mid 패턴이 나타났다. 하지만 alloca()를 사용하여&amp;nbsp;스택 공간을 동적으로 할당하는 함수는 예외로 x86의 EBP와 마찬가지로 RBP 레지스터를 프레임 포인터로 사용한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 스택 프레임 (Stack Frame)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-1. 코드 및 스택 구조 개요&lt;/h3&gt;
&lt;pre id=&quot;code_1752994276301&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

int to_seconds(int hour, int minute, int second) {
	int result_hour = 0;
	int result_minute = 0;
	int result_second = 0;
	int result_total = 0;

	result_hour = hour * 3600;
	result_minute = minute * 60;
	result_second = second;

	result_total = result_hour + result_minute + result_second;

	return result_total;

}

int main() {
	int h = 1;
	int m = 30;
	int s = 15;
	int total = to_seconds(h, m, s);

	printf(&quot;Total seconds: %d\n&quot;, total);

	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 코드는 시, 분, 초를 각각 초 단위로 환산한 뒤 합산하는 단순한 흐름으로 되어 있다. 해당 코드를 토대로 스택 프레임이 어떻게 생성되고 소멸하는지를 단계별로 살펴본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stack.jpg&quot; data-origin-width=&quot;3482&quot; data-origin-height=&quot;1097&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhTV27/btsPpuLYBXm/Vtm61e61umNhvWPKY7ojbK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhTV27/btsPpuLYBXm/Vtm61e61umNhvWPKY7ojbK/img.jpg&quot; data-alt=&quot;[이미지3] 스택&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhTV27/btsPpuLYBXm/Vtm61e61umNhvWPKY7ojbK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbhTV27%2FbtsPpuLYBXm%2FVtm61e61umNhvWPKY7ojbK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3482&quot; height=&quot;1097&quot; data-filename=&quot;stack.jpg&quot; data-origin-width=&quot;3482&quot; data-origin-height=&quot;1097&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지3] 스택&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;x64&amp;nbsp;환경을&amp;nbsp;고려해&amp;nbsp;스택은&amp;nbsp;Full&amp;nbsp;Descending&amp;nbsp;방식으로&amp;nbsp;동작하므로,&amp;nbsp;ESP&amp;nbsp;레지스터는&amp;nbsp;데이터를&amp;nbsp;저장할&amp;nbsp;때마다&amp;nbsp;더&amp;nbsp;낮은&amp;nbsp;주소로&amp;nbsp;이동한&amp;nbsp;뒤&amp;nbsp;해당&amp;nbsp;위치에&amp;nbsp;값을&amp;nbsp;기록한다.&amp;nbsp;낮은주소와&amp;nbsp;높은&amp;nbsp;주소의&amp;nbsp;위치는&amp;nbsp;위와&amp;nbsp;같으며&amp;nbsp;주소의&amp;nbsp;간격은&amp;nbsp;8byte다.&amp;nbsp;데이터를&amp;nbsp;기록할&amp;nbsp;때는&amp;nbsp;가독성을&amp;nbsp;고려해&amp;nbsp;빅엔디언&amp;nbsp;방식을&amp;nbsp;적용한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-2. 스택 프레임 분석 (Leaf &amp;amp; Non-Leaf)&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stack1.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2208&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ceEFil/btsPqku14xR/ugn1vS22IkJ2MdKvn0haKK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ceEFil/btsPqku14xR/ugn1vS22IkJ2MdKvn0haKK/img.jpg&quot; data-alt=&quot;[이미지4] main&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ceEFil/btsPqku14xR/ugn1vS22IkJ2MdKvn0haKK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FceEFil%2FbtsPqku14xR%2Fugn1vS22IkJ2MdKvn0haKK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4552&quot; height=&quot;2208&quot; data-filename=&quot;stack1.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2208&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지4] main&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;main함수 진입 후, 스택의 초기 상태는 위와 같다. 함수 진입 전, call main의 push rip 명령어로 인해 스택에는 main함수 종료 후 되돌아 갈 주소가 저장되어 있다. 32비트와의 차이점은 64비트 주소 지정 기능, 일반 용도로 사용하는 16개의 64비트 레지스터를 사용한다는 점이다(&lt;a href=&quot;https://learn.microsoft.com/ko-kr/cpp/build/x64-software-conventions?view=msvc-170&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://learn.microsoft.com/ko-kr/cpp/build/x64-software-conventions?view=msvc-170&lt;/a&gt;).&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stack2.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2199&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bux1ri/btsPpvjBrvu/59c7XZa0Ejd8h8PO3IMKkK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bux1ri/btsPpvjBrvu/59c7XZa0Ejd8h8PO3IMKkK/img.jpg&quot; data-alt=&quot;[이미지5] main prologue&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bux1ri/btsPpvjBrvu/59c7XZa0Ejd8h8PO3IMKkK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbux1ri%2FbtsPpvjBrvu%2F59c7XZa0Ejd8h8PO3IMKkK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4552&quot; height=&quot;2199&quot; data-filename=&quot;stack2.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2199&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지5] main prologue&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최적화를 적용하지 않은 Debug 빌드에서 main 함수는 to_seconds 함수를 호출하므로 Leaf 함수가 아니며, 이에 따라 Non-Leaf 패턴이 나타난다. 이 패턴의 대표적인 특징은 함수 진입 시 push rbp 명령어를 사용해 현재 RBP를 스택에 저장하고, 이후 lea를 통해 기준점을 설정하는 것이다. 다만 x64 환경에서 push rbp는 ABI의 필수 사항이 아니며, 디버깅의 편의성을 위해 컴파일러가 삽입하는 경우가 많다. 실제로 최적화가 활성화된 Release 빌드에서는 이러한 프레임 포인터 설정이 생략되는 경우가 일반적이며, 이때는 RSP 기반으로만 지역 변수 접근이 이뤄지고 prologue 자체가 간결화되는 경향이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stack3.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2199&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PCzkp/btsPp4MwxO9/eEpg4i9glakFMqxSeiekgK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PCzkp/btsPp4MwxO9/eEpg4i9glakFMqxSeiekgK/img.jpg&quot; data-alt=&quot;[이미지6] main prologue&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PCzkp/btsPp4MwxO9/eEpg4i9glakFMqxSeiekgK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPCzkp%2FbtsPp4MwxO9%2FeEpg4i9glakFMqxSeiekgK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4552&quot; height=&quot;2199&quot; data-filename=&quot;stack3.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2199&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지6] main prologue&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sub rsp, imm 명령은 함수가 실행되는 동안 사용할 영역을 한꺼번에 확보하는 명령이다. 이 영역엔 로컬 변수, 인자, 홈 파라미터 등이 포함된다. x32와 마찬가지로 이 명령어는 단순히 영역 확보 이상의 의미를 갖는다. &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;x32에서는 함수 본체에서 push 명령이 자주 사용되어 로컬 영역과 충돌 가능성이 있었지만, x64는 본체에서 push를 사용하지 않기 때문에 정적 공간 확보만으로 모든 지역 데이터를 처리할 수 있게 한다.&lt;span&gt; 따라서 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;x32에서와는 조금 다른 의미를 갖는다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;호출 직전의 call 명령어로 인해 발생한 push rip, 그리고 선택적으로 존재하는 push rbp로 인해 RSP가 어긋난 상황을 보정해 16byte로 재정렬하는 역할을 수행한다. 또한 이러한 정렬과 구조는 언와인드 데이터(unwind data)를 위한 고정된 프롤로그 패턴을 형성하며, 예외 발생 시 호출 스택 복구에 사용된다. &lt;/span&gt;그리고 함수를 호출할 때, Caller(호출자)의 로컬 영역과 그 다음의 함수에서 사용하는 로컬 영역, 그리고 리턴 주소를 겹치지 않도록 하는 역할 또한 수행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stack4.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2199&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HL4JS/btsPr6PQ2o6/nKtnB1AoHny35rKDMz67QK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HL4JS/btsPr6PQ2o6/nKtnB1AoHny35rKDMz67QK/img.jpg&quot; data-alt=&quot;[이미지7] main prologue&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HL4JS/btsPr6PQ2o6/nKtnB1AoHny35rKDMz67QK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHL4JS%2FbtsPr6PQ2o6%2FnKtnB1AoHny35rKDMz67QK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4552&quot; height=&quot;2199&quot; data-filename=&quot;stack4.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2199&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지7] main prologue&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;lea rbp, imm 명령은 인자와 로컬 영역을 구분하는 기준점을 설정하는 역할을 한다. 다만, x64에서는 RBP를 프레임 포인터로 사용하는 것이 필수적이지 않으며, RBP를 범용 레지스터로 활용해 연산 성능을 높이기도 한다. 이 때문에 RBP를 명시적으로 설정하지 않고 RSP 기준으로 스택 참조를 수행하는 함수들도 존재한다. 그럼에도 이 명령이 포함되는 이유는 디버깅을 고려해 명확한 프레임 경계를 제공하거나 스택 구조를 추적할 수 있도록 일관된 기준을 제공할 수 있기 때문이다. 또한 예외 처리 시 언와인드 정보를 쉽게 구성하려는 목적에서 이 명령이 삽입되는 경우도 많다. 결국 이 명령은 컴파일러의 정책 또는 디버깅 친화성을 위한 선택적 구성 요소로 해석해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stack5.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2199&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UAtq8/btsPqQf9J3d/am31iTbR29r3ymJto64lKk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UAtq8/btsPqQf9J3d/am31iTbR29r3ymJto64lKk/img.jpg&quot; data-alt=&quot;[이미지8] main body&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UAtq8/btsPqQf9J3d/am31iTbR29r3ymJto64lKk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUAtq8%2FbtsPqQf9J3d%2Fam31iTbR29r3ymJto64lKk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4552&quot; height=&quot;2199&quot; data-filename=&quot;stack5.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2199&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지8] main body&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 body부분의 코드에서는 RBP를 기준으로 시간(h), 분(m), 초(s) 값을 로컬 변수 영역에 저장하며, 이때 push 명령 대신 mov 명령을 사용하여 직접 스택에 값을 할당한다. 이는 함수 진입 시 고정된 크기의 프레임을 미리 확보한 상태에서 RSP를 변경하지 않음으로써, 스택의 16byte 정렬을 유지하려는 목적에 기반한다. 그리고 RBP는 섀도우 스페이스를 피해 설정되어 있기 때문에 해당 프레임에서 인자 전달용 공간과 로컬 변수 공간이 명확히 분리되며 값들의 충돌 없이 안전하게 저장된다. 그러나 이러한 구조는 이전에도 설명했듯이 선택적으로 활용되는 것으로, 필수적인 요소는 아니다. RSP를 기준으로 해도&amp;nbsp; &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;동일한 동작을 &lt;/span&gt;구현할 수 있으며, 최적화 적용 시 실제로 RSP 상대 주소만으로 스택을 운용하는 방식이 보다 일반적으로 채택된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stack6.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2199&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cDBJ1C/btsPs03D36G/alJs4m8XkcmWssbURsKfk0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cDBJ1C/btsPs03D36G/alJs4m8XkcmWssbURsKfk0/img.jpg&quot; data-alt=&quot;[이미지9] main body&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cDBJ1C/btsPs03D36G/alJs4m8XkcmWssbURsKfk0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcDBJ1C%2FbtsPs03D36G%2FalJs4m8XkcmWssbURsKfk0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4552&quot; height=&quot;2199&quot; data-filename=&quot;stack6.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2199&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지9] main body&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;to_seconds 함수를 호출하기 전, 각각의 로컬 변수(h, m ,s)를 레지스터에 담고 있다. x64 함수 호출 규약에 따라 정수형 인자는 순서대로 ECX, EDX, R8, R9 레지스터를 통해 전달되며, 이 예제에서는 인자가 3개이므로 ECX, EDX, R8이 사용된다. x32환경과 달리, x64에서는 하나의 고정된 호출 규약이 적용되어 함수마다 호출 방식이 달라지지 않는다. 이때, 인자의 자료형에 따라 레지스터 그룹이 구분되는데, 정수형은 위와 같은 범용 레지스터, 부동소수점형은 XMM0~XMM3 등의 레지스터를 통해 전달된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stack7.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2199&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Esrc5/btsPtjoYcBR/ZP6OEbBsdfYOQNskTBWw60/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Esrc5/btsPtjoYcBR/ZP6OEbBsdfYOQNskTBWw60/img.jpg&quot; data-alt=&quot;[이미지10] main body&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Esrc5/btsPtjoYcBR/ZP6OEbBsdfYOQNskTBWw60/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEsrc5%2FbtsPtjoYcBR%2FZP6OEbBsdfYOQNskTBWw60%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4552&quot; height=&quot;2199&quot; data-filename=&quot;stack7.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2199&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지10] main body&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;call to_seconds 명령을 통해 함수 호출 직전, 제어 흐름이 되돌아올 위치인 다음 명령어의 주소 0x0000000140011ADF를 스택에 push하여 저장한다. 이는 호출된 함수가 작업을 마친 후 ret 명령을 통해 복귀할 수 있도록 하기 위한 동작으로 x32와 동일한 메커니즘을 사용한다. 이후 호출되는 함수(to_seconds)의 프롤로그 부분에서 16byte 정렬을 맞추는 동작(sub rsp, imm)이 포함되어 있기 때문에 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;body에서 push가 가능하다. 이처럼 함수를 호출하는 동작은 프롤로그 단계에서 정렬이 보장되어 있기 때문에 body 내부에서도 제한적으로 push를 사용할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stack8.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2224&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/R3moA/btsPtB33pDB/sMIOHBJP8fog28chKzGqK1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/R3moA/btsPtB33pDB/sMIOHBJP8fog28chKzGqK1/img.jpg&quot; data-alt=&quot;[이미지11] to_seconds prologue&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/R3moA/btsPtB33pDB/sMIOHBJP8fog28chKzGqK1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FR3moA%2FbtsPtB33pDB%2FsMIOHBJP8fog28chKzGqK1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4552&quot; height=&quot;2224&quot; data-filename=&quot;stack8.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2224&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지11] to_seconds prologue&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;to_seconds 함수의 프롤로그 부분에서 인자로 전달받은 레지스터 ECX, EDX, E8을 다시 스택에 저장하는 동작을 한다. 이 동작은 &lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;인자의 백업을 위해 사용될 수도 있지만, 해당 예제 코드에서는 최적화를 적용하지 않았기 때문에 디버깅 용이성을 위해 나타난 코드이다. 이 영역은 main에서 미리 확보한 Shadow Space 영역이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;shadowspace_stackframe.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2224&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/voyNF/btsPC7HGcE9/7Su88RVsDERG4mS7kRpGT1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/voyNF/btsPC7HGcE9/7Su88RVsDERG4mS7kRpGT1/img.jpg&quot; data-alt=&quot;[이미지12] Shadow Space&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/voyNF/btsPC7HGcE9/7Su88RVsDERG4mS7kRpGT1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvoyNF%2FbtsPC7HGcE9%2F7Su88RVsDERG4mS7kRpGT1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4552&quot; height=&quot;2224&quot; data-filename=&quot;shadowspace_stackframe.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2224&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지12] Shadow Space&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;x64 ABI에 따르면 Shadow Space는 함수를 호출하기 전, Caller(호출자)가 필수적으로 확보해야 하는 공간이다. 이 동작은 main의 프롤로그 부분에서 sub rsp, imm을 할 때 확보된다. 따라서 imm의 최소값은 Shadow Space 영역의 크기인 32byte로 제한된다. Callee(피호출자)는 이 공간을 &lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;상황에 따라 유연하게 활용할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stack9.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2224&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqkRgV/btsPtlggwmQ/jHWDfXUprtFOf0Bek6ACpK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqkRgV/btsPtlggwmQ/jHWDfXUprtFOf0Bek6ACpK/img.jpg&quot; data-alt=&quot;[이미지13] to_seconds prologue&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqkRgV/btsPtlggwmQ/jHWDfXUprtFOf0Bek6ACpK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqkRgV%2FbtsPtlggwmQ%2FjHWDfXUprtFOf0Bek6ACpK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4552&quot; height=&quot;2224&quot; data-filename=&quot;stack9.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2224&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지13] to_seconds prologue&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;to_seconds 함수는 Leaf 함수이기 때문에 Leaf 패턴이 나타나는 것을 확인할 수 있다. 이때 사용되는 push rbp는 프레임 포인터를 보존하려는 관례 혹은 디버깅에 따른 것으로, 앞서 설명한 것처럼 반드시 필요한 절차는 아니며 RSP 기준으로도 동일한 동작을 구현할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stack10.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2242&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0MVPc/btsPtnZq1rk/9yHunS1k5MUQPw3cz79jR1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0MVPc/btsPtnZq1rk/9yHunS1k5MUQPw3cz79jR1/img.jpg&quot; data-alt=&quot;[이미지14] to_seconds prologue&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0MVPc/btsPtnZq1rk/9yHunS1k5MUQPw3cz79jR1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0MVPc%2FbtsPtnZq1rk%2F9yHunS1k5MUQPw3cz79jR1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4552&quot; height=&quot;2242&quot; data-filename=&quot;stack10.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2242&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지14] to_seconds prologue&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 to_seconds 함수의 프롤로그에서는 sub rsp, imm 명령을 통해 함수 내부에서 사용할 로컬 변수 공간을 확보하고 있다. 이는 단순한 데이터 저장 목적을 넘어, main 함수와 마찬가지로 스택의 16byte 정렬을 유지하고 예외 처리 시 언와인드(unwind) 정보를 정형화하기 위한 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stack11.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2242&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b714Zt/btsPsUwHEDH/K99qBzOSC7ksQ7CppIuYOK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b714Zt/btsPsUwHEDH/K99qBzOSC7ksQ7CppIuYOK/img.jpg&quot; data-alt=&quot;[이미지15] to_seconds prologue&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b714Zt/btsPsUwHEDH/K99qBzOSC7ksQ7CppIuYOK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb714Zt%2FbtsPsUwHEDH%2FK99qBzOSC7ksQ7CppIuYOK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4552&quot; height=&quot;2242&quot; data-filename=&quot;stack11.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2242&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지15] to_seconds prologue&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 main 함수와의 차이점은 to_seconds가 Leaf 함수라는 점에 있다. Leaf 함수는 내부에서 다른 함수를 호출하지 않기 때문에, Shadow Space를 추가로 확보할 필요가 없으며, 호출 인자와 로컬 변수 영역을 분리할 필요도 없다. 이로 인해 프레임 구성에서도 차이가 발생하며, 그 결과 서로 다른 패턴(Leaf, Non-Leaf)이 등장하는 것이다. to_seconds에서는 함수 진입 직후 설정된 RSP와 RBP가 동일한 위치를 가리키고 있는 것을 확인할 수 있는데, 이는 to_seconds가 Leaf 함수이기 때문이다. 또한 x32에서 EBP가 SFP를 가리키고 있는 구조와 전혀 다른 모습이 나타난다는 것을 확인할 수 있다(이 동작이 가능한 이유는 이후 에필로그에서 설명).&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stack12.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2242&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qTZ4X/btsPuEy5ujN/URt2ffEz0U5vjIatzY9rn0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qTZ4X/btsPuEy5ujN/URt2ffEz0U5vjIatzY9rn0/img.jpg&quot; data-alt=&quot;[이미지16] to_seconds body&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qTZ4X/btsPuEy5ujN/URt2ffEz0U5vjIatzY9rn0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqTZ4X%2FbtsPuEy5ujN%2FURt2ffEz0U5vjIatzY9rn0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4552&quot; height=&quot;2242&quot; data-filename=&quot;stack12.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2242&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지16] to_seconds body&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 EBP를 기준으로 로컬 변수를 초기화 하는 동작을 수행한다. to_seconds 함수에서 사용하는 로컬 변수인 result_hour, result_minute, result_second, result_total의 값을 0으로 초기화 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stack13.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2307&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMxBZo/btsPtU3CL7r/ouxntk2ai869EnvhPtXRU0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMxBZo/btsPtU3CL7r/ouxntk2ai869EnvhPtXRU0/img.jpg&quot; data-alt=&quot;[이미지17] to_seconds body&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMxBZo/btsPtU3CL7r/ouxntk2ai869EnvhPtXRU0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMxBZo%2FbtsPtU3CL7r%2Fouxntk2ai869EnvhPtXRU0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4552&quot; height=&quot;2307&quot; data-filename=&quot;stack13.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2307&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지17] to_seconds body&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시간(h)를 초(s)로 변환하는 코드로, imul을 통해 그 연산 결과를 EAX에 담는다. 이때 사용하는 인자는 Shadow Space에 백업한 스택을 참조한다. 이는 x64 함수 호출 규약에서 레지스터를 활용한다는 이점이 없어지는 것 처럼 보인다(레지스터로 전달한 인자를 다시 스택에 담고 그 스택에 저장된 값을 참조하기 때문). 하지만 이는 최적화를 사용하지 않고 Debug /Od로 빌드했기 때문이다. 컴파일 옵션에 따라 인자를 활용하는 방식에는 차이가 발생한다. 따라서 인자를 백업할 필요가 없는 상황이라면 레지스터 값을 바로 참조해서 연산을 진행하기도 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stack14.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2307&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dJKtsj/btsPsFfygnp/bKWlLfyMBs4cgE4RwAgzfk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dJKtsj/btsPsFfygnp/bKWlLfyMBs4cgE4RwAgzfk/img.jpg&quot; data-alt=&quot;[이미지18] to_seconds body&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dJKtsj/btsPsFfygnp/bKWlLfyMBs4cgE4RwAgzfk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdJKtsj%2FbtsPsFfygnp%2FbKWlLfyMBs4cgE4RwAgzfk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4552&quot; height=&quot;2307&quot; data-filename=&quot;stack14.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2307&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지18] to_seconds body&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;분(m)을 초(s)로 변환하는 코드로, 이전과 같이 스택에 백업한 값을 사용한다. 연산 결과를 to_seconds의 로컬 변수 영역에 저장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stack15.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2242&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sLKZG/btsPsWg7lnG/WrYZ2CeIr1sVkET0aD2Tbk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sLKZG/btsPsWg7lnG/WrYZ2CeIr1sVkET0aD2Tbk/img.jpg&quot; data-alt=&quot;[이미지19] to_seconds body&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sLKZG/btsPsWg7lnG/WrYZ2CeIr1sVkET0aD2Tbk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsLKZG%2FbtsPsWg7lnG%2FWrYZ2CeIr1sVkET0aD2Tbk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4552&quot; height=&quot;2242&quot; data-filename=&quot;stack15.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2242&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지19] to_seconds body&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;초(s)를 읽어서 기록하는 코드로, 이전과 같이 스택에 백업한 값을 사용한다. 연산 결과를 to_seconds의 로컬 변수 영역에 저장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stack16.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2307&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cRBUYi/btsPsEnqEZA/D5BgKvnPjAL7mRQHvswKk0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cRBUYi/btsPsEnqEZA/D5BgKvnPjAL7mRQHvswKk0/img.jpg&quot; data-alt=&quot;[이미지20] to_seconds body&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cRBUYi/btsPsEnqEZA/D5BgKvnPjAL7mRQHvswKk0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcRBUYi%2FbtsPsEnqEZA%2FD5BgKvnPjAL7mRQHvswKk0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4552&quot; height=&quot;2307&quot; data-filename=&quot;stack16.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2307&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지20] to_seconds body&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞선 연산 결과를 모두 더해주는 코드로, 시간(h), 분(m), 초(s)를 모두 합산한 결과를 to_seconds의 로컬 변수 영역에 저장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stack17.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2242&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UUYuM/btsPsF7LXP6/MQhBPlPaNZkPZcj3x2TOU1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UUYuM/btsPsF7LXP6/MQhBPlPaNZkPZcj3x2TOU1/img.jpg&quot; data-alt=&quot;[이미지21] to_seconds body&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UUYuM/btsPsF7LXP6/MQhBPlPaNZkPZcj3x2TOU1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUUYuM%2FbtsPsF7LXP6%2FMQhBPlPaNZkPZcj3x2TOU1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4552&quot; height=&quot;2242&quot; data-filename=&quot;stack17.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2242&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지21] to_seconds body&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;return을 통해 함수의 연산 결과 값이 호출자(main)에게 전달 될 수 있도록 한다. 이는 주로 EAX 레지스터에 결과를 저장하는 방식으로 이루어진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stack18.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2242&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AZLKc/btsPul03mOY/yKcKhmmJJw7zK4ekToTlW1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AZLKc/btsPul03mOY/yKcKhmmJJw7zK4ekToTlW1/img.jpg&quot; data-alt=&quot;[이미지22] to_seconds epilogue&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AZLKc/btsPul03mOY/yKcKhmmJJw7zK4ekToTlW1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAZLKc%2FbtsPul03mOY%2FyKcKhmmJJw7zK4ekToTlW1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4552&quot; height=&quot;2242&quot; data-filename=&quot;stack18.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2242&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지22] to_seconds epilogue&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[이미지15]에서 확인할 수 있듯, RBP가 SFP를 가리키지 않아도 복구가 가능한 이유는 에필로그에 위치한 lea rsp, imm 명령을 통해 스택 포인터를 정확히 원래 위치로 되돌릴 수 있기 때문이다. 이는 RBP를 프레임 포인터로 사용하지 않고 범용 레지스터로 활용하는 함수에서 자주 나타나는 방식으로, 프롤로그에서 sub rsp, 0x50과 같이 확보한 스택 크기만큼을 에필로그에서 정확히 더해주는 구조를 통해 RSP를 복구한다. 다시 말해, 복귀 지점의 RSP는 최초 확보한 스택 공간 크기만큼만 조정하면 되기 때문에, 굳이 SFP를 유지하거나 저장할 필요 없이 프레임 복구가 가능해지는 것이다. 이러한 구조는 x64 ABI의 특성에 기반한다. x64에서는 함수 body 구간에서 RSP가 항상 16byte 정렬을 유지해야 하며, 이로 인해 push나 pop과 같이 RSP를 변경하는 명령은 프롤로그 또는 에필로그에서만 제한적으로 사용된다. 즉, 함수가 실행되는 동안에는 RSP가 고정된 구조로 유지되며, 컴파일러는 이를 전제로 안전한 스택 복구 코드를 생성할 수 있다. 반면 x32에서는 함수 body에서도 자유롭게 push와 pop이 사용되므로, ESP의 값이 body 구간에서 지속적으로 변동될 수 있다. 이로 인해 프롤로그에서 sub esp, imm로 확보한 크기가 에필로그 시점에서는 유효하지 않을 수 있으며, 정확한 복구를 위해 항상 고정된 기준점인 EBP가 필요하게 된다. 따라서 x64에서는 RSP를 기반으로 프레임 복구가 가능하지만, x32에서는 ESP의 변동 가능성 때문에 반드시 EBP를 저장하고 이를 통해 복구하는 방식이 채택되는 것이다. 이 차이는 함수 호출 규약과 ABI 정렬 조건에서 기인하며, 컴파일러는 이러한 규칙을 바탕으로 스택 복구용 상수 값을 컴파일 타임에 고정된 값으로 삽입하게 된다. 이 외에 가장 핵심적인 부분은 x64에서 언와인드 테이블(.pdata/.xdata)에 기록된 프롤로그 메타데이터와 RSP만으로도 예외 처리 및 디버깅 단계에서 완전한 스택 복원이 가능하다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stack19.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2224&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Hgzfu/btsPsR1nqV8/ntkDmiOhj4qDdgXRBRkUM0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Hgzfu/btsPsR1nqV8/ntkDmiOhj4qDdgXRBRkUM0/img.jpg&quot; data-alt=&quot;[이미지23] to_seconds epilogue&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Hgzfu/btsPsR1nqV8/ntkDmiOhj4qDdgXRBRkUM0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHgzfu%2FbtsPsR1nqV8%2FntkDmiOhj4qDdgXRBRkUM0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4552&quot; height=&quot;2224&quot; data-filename=&quot;stack19.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2224&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지23] to_seconds epilogue&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;pop rbp 명령은 함수 종료 시점에서 스택 상단에 저장된 이전 RBP 값을 꺼내어 현재 RBP에 복원함으로써 호출자의 프레임 포인터를 재설정하는 역할을 한다. 동시에 이 동작으로 RSP는 리턴 주소(RIP)를 가리키는 위치로 이동하게 되며, 이전의 상태로 돌아갈 준비를 마치게 된다. 이는 RBP를 프레임 포인터로 사용할 때 일반적으로 나타나는 전형적인 에필로그 패턴이다. 반면 RBP를 프레임 포인터로 사용하지 않고 범용 레지스터로 활용하는 경우에는 push rbp나 pop rbp 같은 동작이 생략된다. 대신 에필로그에서는 lea rsp, imm 명령을 통해 RSP를 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;리턴 &lt;/span&gt;주소(RIP)가 저장된 위치로 이동하는 동작을 한다. 따라서 곧바로 ret 명령 동작이 가능해진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stack20.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2224&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/YuuHe/btsPs6c0PT0/UIDfFzya8ZAvDFQk8bmuO1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/YuuHe/btsPs6c0PT0/UIDfFzya8ZAvDFQk8bmuO1/img.jpg&quot; data-alt=&quot;[이미지24] to_seconds epilogue&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/YuuHe/btsPs6c0PT0/UIDfFzya8ZAvDFQk8bmuO1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYuuHe%2FbtsPs6c0PT0%2FUIDfFzya8ZAvDFQk8bmuO1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4552&quot; height=&quot;2224&quot; data-filename=&quot;stack20.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2224&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지24] to_seconds epilogue&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ret 내부 동작으로 pop rip를 수행하기 때문에 함수 호출 전, 스택에 저장한 값(to_seconds 호출 이후 주소)을 RIP에 저장해서&amp;nbsp;제어&amp;nbsp;흐름을&amp;nbsp;정확히&amp;nbsp;원래&amp;nbsp;위치로&amp;nbsp;되돌린다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stack21.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2199&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NcpxI/btsPtkh1bPu/Kpv3PeTbJfRJKkCAlckNvk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NcpxI/btsPtkh1bPu/Kpv3PeTbJfRJKkCAlckNvk/img.jpg&quot; data-alt=&quot;[이미지25] main body&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NcpxI/btsPtkh1bPu/Kpv3PeTbJfRJKkCAlckNvk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNcpxI%2FbtsPtkh1bPu%2FKpv3PeTbJfRJKkCAlckNvk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4552&quot; height=&quot;2199&quot; data-filename=&quot;stack21.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2199&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지25] main body&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;to_seconds 함수의 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;연산 결과를 &lt;/span&gt;return 명령어를 통해 EAX 레지스터에 저장해 놨기 때문에, EAX를 참조해서 main의 로컬 변수인 total에 저장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stack22.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2199&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/chJokk/btsPtyUIUnG/WyMdWjLJdNkKXLUNH8lvtk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/chJokk/btsPtyUIUnG/WyMdWjLJdNkKXLUNH8lvtk/img.jpg&quot; data-alt=&quot;[이미지26] main body&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/chJokk/btsPtyUIUnG/WyMdWjLJdNkKXLUNH8lvtk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FchJokk%2FbtsPtyUIUnG%2FWyMdWjLJdNkKXLUNH8lvtk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4552&quot; height=&quot;2199&quot; data-filename=&quot;stack22.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2199&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지26] main body&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;printf 호출 시에도 마찬가지로, 먼저 포맷 문자열과 인자들이 스택에 적재되고, RIP와 SFP(선택적)가 차례로 스택에 저장된다. 이어서 printf 내부의 프롤로그가 새로운 스택프레임을 설정하고, 바디에서 포맷 문자열을 해석해 콘솔(cmd) 창에 지정된 문자열을 출력한다. 에필로그 단계에서 RSP와 RBP(선택적)를 원래 상태로 복원한다. 마지막으로 ret이 실행되면 printf를 호출 할 때 저장된 RIP가 복원되어 호출 지점으로 되돌아가면서 제어가 다시 main 함수로 넘어온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stack23.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2199&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bf4ztt/btsPuZ4xDO0/y8MCQEo65J1pIf2noqsvO1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bf4ztt/btsPuZ4xDO0/y8MCQEo65J1pIf2noqsvO1/img.jpg&quot; data-alt=&quot;[이미지27] main body&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bf4ztt/btsPuZ4xDO0/y8MCQEo65J1pIf2noqsvO1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbf4ztt%2FbtsPuZ4xDO0%2Fy8MCQEo65J1pIf2noqsvO1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4552&quot; height=&quot;2199&quot; data-filename=&quot;stack23.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2199&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지27] main body&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;xor eax, eax 명령은 레지스터 EAX의 값을 0으로 초기화하는 역할을 한다. 주로 return 0; 구문을 컴파일할 때 생성되며, 프로그램이 정상적으로 종료되었음을 Caller(호출자)에 알리는 용도로 쓰인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stack24.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2199&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/w0iMD/btsPvBoAr4Z/iq9H6SPKWZh5vp8j6KWoKk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/w0iMD/btsPvBoAr4Z/iq9H6SPKWZh5vp8j6KWoKk/img.jpg&quot; data-alt=&quot;[이미지28] main epilogue&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/w0iMD/btsPvBoAr4Z/iq9H6SPKWZh5vp8j6KWoKk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fw0iMD%2FbtsPvBoAr4Z%2Fiq9H6SPKWZh5vp8j6KWoKk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4552&quot; height=&quot;2199&quot; data-filename=&quot;stack24.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2199&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지28] main epilogue&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;main의 에필로그 동작을 살펴보면 to_seconds 함수의 에필로그에서는 프롤로그에서 사용한 sub rsp, imm 명령과는 다른 방식으로 스택을 정리하고 있다. 이는 단순히 확보한 크기가 다르기 때문이 아니라 RBP를 기준으로 스택을 복구하기 때문에 나타나는 현상이다. 예제에서 main 함수는 Non-Leaf 함수로, 다른 함수를 호출하기 때문에 Shadow Space를 포함해 스택 공간을 확보한다(이 자체가 스택 정리 방식에 영향을 준 것은 아님). 중요한 점은 해당 예제에서 RBP를 프레임 포인터로 사용하고 있으며, 이로 인해 인자와 로컬 변수의 경계를 설정 하기 위해 RBP가 RSP보다 0x20 높은 위치, 즉 rsp + 0x20에 설정된다는 것이다. 이후 함수 종료 시에는 RBP를 기준으로 RSP를 복원하기 때문에, lea rsp, [rbp + 0x50]과 같은 형태로 정리하게 되고, 결과적으로 이는 처음 프롤로그에서 확보한 공간인 0x70과 동일한 크기를 복구하게 된다. 반면 RBP를 사용하지 않고 RSP를 기준으로 스택을 운용하는 함수에서는, 프롤로그에서 sub rsp, 0x70으로 확보한 만큼 에필로그에서 add rsp, 0x70으로 정확히 복구하는 방식이 사용된다. 따라서 x64에서 Non-Leaf 함수가 RBP를 활용할 경우, 스택 정리는 RBP + offset을 통해 간접적으로 수행되며, 그 차이는 RBP가 설정되는 위치를 기준으로 발생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stack25.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2205&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b5RzYt/btsPtCXhOEF/EYeQOHhS4iZU295bVJ8f1K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b5RzYt/btsPtCXhOEF/EYeQOHhS4iZU295bVJ8f1K/img.jpg&quot; data-alt=&quot;[이미지29] main epilogue&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b5RzYt/btsPtCXhOEF/EYeQOHhS4iZU295bVJ8f1K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb5RzYt%2FbtsPtCXhOEF%2FEYeQOHhS4iZU295bVJ8f1K%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4552&quot; height=&quot;2205&quot; data-filename=&quot;stack25.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2205&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지29] main epilogue&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;pop rbp로 SFP를 다시 RBP에 복원한다. RBP를&amp;nbsp;프레임&amp;nbsp;포인터로&amp;nbsp;사용하는&amp;nbsp;경우에&amp;nbsp;포함되는&amp;nbsp;패턴이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stack26.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2205&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NY0uo/btsPvqguyUk/iKyx6kabgsYCLKrlzjpkYk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NY0uo/btsPvqguyUk/iKyx6kabgsYCLKrlzjpkYk/img.jpg&quot; data-alt=&quot;[이미지30] main epilogue&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NY0uo/btsPvqguyUk/iKyx6kabgsYCLKrlzjpkYk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNY0uo%2FbtsPvqguyUk%2FiKyx6kabgsYCLKrlzjpkYk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4552&quot; height=&quot;2205&quot; data-filename=&quot;stack26.jpg&quot; data-origin-width=&quot;4552&quot; data-origin-height=&quot;2205&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지30] main epilogue&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;ret의 pop rip의 동작을 통해 제어 흐름을 main 함수 호출 직후 위치로 변경한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stack27.jpg&quot; data-origin-width=&quot;4423&quot; data-origin-height=&quot;2205&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cJcDq5/btsPvoiCV0j/4uKqJv0a4p6UkZNkMLjnTk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cJcDq5/btsPvoiCV0j/4uKqJv0a4p6UkZNkMLjnTk/img.jpg&quot; data-alt=&quot;[이미지31] main epilogue&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cJcDq5/btsPvoiCV0j/4uKqJv0a4p6UkZNkMLjnTk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcJcDq5%2FbtsPvoiCV0j%2F4uKqJv0a4p6UkZNkMLjnTk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4423&quot; height=&quot;2205&quot; data-filename=&quot;stack27.jpg&quot; data-origin-width=&quot;4423&quot; data-origin-height=&quot;2205&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지31] main epilogue&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;main 함수가 호출된 위치는 위와 같으며 main 함수 종료 후, 에필로그의 ret에서 pop eip를 통해 0x0000000140011B89의 코드가 실행된다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-3. 스택 프레임 분석 (Opt-Mid)&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;nonleaf_midopt1.jpg&quot; data-origin-width=&quot;4479&quot; data-origin-height=&quot;2922&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDRsWE/btsPB3e56iX/aRMctS7E4asKUWz0Y9R5k1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDRsWE/btsPB3e56iX/aRMctS7E4asKUWz0Y9R5k1/img.jpg&quot; data-alt=&quot;[이미지32] Opt-Mid prologue &amp;amp;amp; epilogue&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDRsWE/btsPB3e56iX/aRMctS7E4asKUWz0Y9R5k1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDRsWE%2FbtsPB3e56iX%2FaRMctS7E4asKUWz0Y9R5k1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4479&quot; height=&quot;2922&quot; data-filename=&quot;nonleaf_midopt1.jpg&quot; data-origin-width=&quot;4479&quot; data-origin-height=&quot;2922&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지32] Opt-Mid prologue &amp;amp; epilogue&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Opt-Mid로 나타나는 패턴을 확인해 보면 함수의 프롤로그에서 확보한 크기만큼 에필로그에서 스택을 정리하는 것을 확인할 수 있다. 또한 RBP를 사용하지 않기 때문에 SFP를 스택에 저장하는 동작을 하지 않는 것도 살펴볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;nonleaf_midopt2.jpg&quot; data-origin-width=&quot;4479&quot; data-origin-height=&quot;2922&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cg9Wy5/btsPB8gov9p/OrAkIR4z41e1YHxqNDKJPK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cg9Wy5/btsPB8gov9p/OrAkIR4z41e1YHxqNDKJPK/img.jpg&quot; data-alt=&quot;[이미지33] Opt-Mid RSP&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cg9Wy5/btsPB8gov9p/OrAkIR4z41e1YHxqNDKJPK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcg9Wy5%2FbtsPB8gov9p%2FOrAkIR4z41e1YHxqNDKJPK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4479&quot; height=&quot;2922&quot; data-filename=&quot;nonleaf_midopt2.jpg&quot; data-origin-width=&quot;4479&quot; data-origin-height=&quot;2922&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지33] Opt-Mid RSP&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RBP를 사용하지 않기 때문에 함수의 body, prologue에서 인자, 로컬 변수를 참조할 때 RSP가 기준이 된다는 사실을 확인할 수 있다. 이때, RSP는 스택 포인터와 프레임 포인터 역할을 동시에 수행하게 된다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. &lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;스택 프레임의 경계&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stackframe_struct1.jpg&quot; data-origin-width=&quot;3931&quot; data-origin-height=&quot;2276&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b9pyDM/btsPB3zqLqc/WufQZ9mkfVb9KnjraJ0uEk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b9pyDM/btsPB3zqLqc/WufQZ9mkfVb9KnjraJ0uEk/img.jpg&quot; data-alt=&quot;[이미지34] 스택 프레임 경계 (RSP)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b9pyDM/btsPB3zqLqc/WufQZ9mkfVb9KnjraJ0uEk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb9pyDM%2FbtsPB3zqLqc%2FWufQZ9mkfVb9KnjraJ0uEk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3931&quot; height=&quot;2276&quot; data-filename=&quot;stackframe_struct1.jpg&quot; data-origin-width=&quot;3931&quot; data-origin-height=&quot;2276&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지34] 스택 프레임 경계 (RSP)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;x64는 기능적, 구조적 배치가 어느정도 일치하는 스택 프레임을 형성하기 때문에, x32와 비교해 스택 프레임의 경계를 구분하기가 상대적으로 용이하다. 프레임 간 경계를 RIP(리턴 주소)를 기준으로 명확히 식별할 수 있는 구조적 장점을 갖는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stackframe_struct2.jpg&quot; data-origin-width=&quot;4011&quot; data-origin-height=&quot;2276&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c33APc/btsPCI2Ej7A/oK8hkFYPNa3l7PoyUyOqOk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c33APc/btsPCI2Ej7A/oK8hkFYPNa3l7PoyUyOqOk/img.jpg&quot; data-alt=&quot;[이미지35] 스택 프레임 경계 (RBP)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c33APc/btsPCI2Ej7A/oK8hkFYPNa3l7PoyUyOqOk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc33APc%2FbtsPCI2Ej7A%2FoK8hkFYPNa3l7PoyUyOqOk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4011&quot; height=&quot;2276&quot; data-filename=&quot;stackframe_struct2.jpg&quot; data-origin-width=&quot;4011&quot; data-origin-height=&quot;2276&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지35] 스택 프레임 경계 (RBP)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RBP를 활용하는 스택 프레임에서도 x64는 RIP(리턴 주소)를 기준으로 각 함수의 스택 프레임을 명확히 구분할 수 있다. 반면 x32에서는 EIP(리턴 주소)와 SFP(프레임 포인터)가 인자 영역과 로컬 데이터 영역 사이에 위치하고 있어, 단순한 구조 구분이 어려워 기능적, 구조적 기준을 따로 고려해야 했다. 하지만 x64에서는 push, pop 명령이 프롤로그와 에필로그에 한정되어 사용되고, 함수 body에서는 RSP의 16byte 정렬이 유지되도록 강제되기 때문에, 프롤로그에서 sub rsp, imm 명령으로 한 번에 전체 스택 프레임 영역을 확보하는 구조가 일반적이다. 이로 인해 각 함수는 이전 RIP부터 자신의 RIP에 이르기까지 하나의 독립된 스택 프레임으로 구분할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stackframe_struct3.jpg&quot; data-origin-width=&quot;2281&quot; data-origin-height=&quot;2295&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ywcFw/btsPCLZoFuA/tOZKWiYoRJ4PnIiADlSGkk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ywcFw/btsPCLZoFuA/tOZKWiYoRJ4PnIiADlSGkk/img.jpg&quot; data-alt=&quot;[이미지36] 스택 프레임 경계&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ywcFw/btsPCLZoFuA/tOZKWiYoRJ4PnIiADlSGkk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FywcFw%2FbtsPCLZoFuA%2FtOZKWiYoRJ4PnIiADlSGkk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2281&quot; height=&quot;2295&quot; data-filename=&quot;stackframe_struct3.jpg&quot; data-origin-width=&quot;2281&quot; data-origin-height=&quot;2295&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지36] 스택 프레임 경계&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. 참고 문헌&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[1] x64 호출 규칙, &lt;a href=&quot;https://learn.microsoft.com/ko-kr/cpp/build/x64-calling-convention?view=msvc-170&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://learn.microsoft.com/ko-kr/cpp/build/x64-calling-convention?view=msvc-170&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;[2] x64 스택 사용,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/cpp/build/stack-usage?view=msvc-170&quot;&gt;https://learn.microsoft.com/ko-kr/cpp/build/stack-usage?view=msvc-170&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Reversing/Definition</category>
      <category>stack frame</category>
      <category>x64</category>
      <category>스택 프레임</category>
      <author>kj0on</author>
      <guid isPermaLink="true">https://kj0on.tistory.com/43</guid>
      <comments>https://kj0on.tistory.com/43#entry43comment</comments>
      <pubDate>Tue, 15 Jul 2025 17:18:46 +0900</pubDate>
    </item>
    <item>
      <title>[Definition] 32비트 함수 호출 규약 (32bit Calling Convention)</title>
      <link>https://kj0on.tistory.com/42</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;0. 32비트 스택 프레임 (32bit Stack Frame)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color: #333333;&quot;&gt;32비트 스택프레임에 대한 자세한 설명은&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://kj0on.tistory.com/41&quot; target=&quot;_self&quot;&gt;&lt;span&gt;https://kj0on.tistory.com/41&lt;/span&gt;&lt;/a&gt; 참고&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 정의&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;함수와&amp;nbsp;호출자&amp;nbsp;간에&amp;nbsp;인수를&amp;nbsp;전달하고&amp;nbsp;값을&amp;nbsp;반환하기&amp;nbsp;위한&amp;nbsp;규칙&lt;br /&gt;&amp;nbsp;&lt;br /&gt;프로시저(함수)&amp;nbsp;호출&amp;nbsp;시&amp;nbsp;인자를&amp;nbsp;어디에&amp;nbsp;어떤&amp;nbsp;순서로&amp;nbsp;전달하고,&amp;nbsp;누가&amp;nbsp;스택을&amp;nbsp;정리하며,&amp;nbsp;레지스터를&amp;nbsp;보존할지,&amp;nbsp;어느&amp;nbsp;레지스터로&amp;nbsp;값을&amp;nbsp;반환할지&amp;nbsp;등을&amp;nbsp;규정한&amp;nbsp;저수준&amp;nbsp;인터페이스&amp;nbsp;계약이다.&amp;nbsp;컴파일러,&amp;nbsp;언어,&amp;nbsp;OS,&amp;nbsp;CPU가&amp;nbsp;서로&amp;nbsp;다른&amp;nbsp;오브젝트&amp;nbsp;코드를&amp;nbsp;같은&amp;nbsp;ABI&amp;nbsp;안에서&amp;nbsp;링크&amp;nbsp;및&amp;nbsp;호출할&amp;nbsp;수&amp;nbsp;있게&amp;nbsp;해준다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/cpp/cpp/calling-conventions?view=msvc-170&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;https://learn.microsoft.com/ko-kr/cpp/cpp/calling-conventions?view=msvc-170&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. Caller(호출자)와 Callee(피호출자)&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2708&quot; data-origin-height=&quot;794&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beRA1E/btsPj2AttRo/FoauELqu4hijjDnBwEXcs1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beRA1E/btsPj2AttRo/FoauELqu4hijjDnBwEXcs1/img.jpg&quot; data-alt=&quot;[이미지1] caller callee&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beRA1E/btsPj2AttRo/FoauELqu4hijjDnBwEXcs1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbeRA1E%2FbtsPj2AttRo%2FFoauELqu4hijjDnBwEXcs1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2708&quot; height=&quot;794&quot; data-origin-width=&quot;2708&quot; data-origin-height=&quot;794&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지1] caller callee&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Caller는 함수를 호출하는 쪽이고, Callee는 호출된 함수이다. Caller는 인자를 준비하고 제어를 Callee에게 넘기며, Callee는 이를 받아 작업을 수행한 뒤 결과를 반환한다. 이 과정에서 책임이 명확하게 나뉘며, 어떤 쪽이 어떤 책임을 지는지는 사용된 호출 규약에 따라 사전에 정해진 방식으로 결정된다.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 호출 규약 비교 요약 (C/C++)&lt;/h2&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style12&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 17.6356%; text-align: justify;&quot;&gt;키워드&lt;/td&gt;
&lt;td style=&quot;width: 17.7519%; text-align: justify;&quot;&gt;스택&amp;nbsp;정리&lt;/td&gt;
&lt;td style=&quot;width: 64.6124%; text-align: justify;&quot;&gt;매개&amp;nbsp;변수&amp;nbsp;전달&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 17.6356%; text-align: justify;&quot;&gt;__cdecl&lt;/td&gt;
&lt;td style=&quot;width: 17.7519%; text-align: justify;&quot;&gt;호출자&lt;/td&gt;
&lt;td style=&quot;width: 64.6124%; text-align: justify;&quot;&gt;매개&amp;nbsp;변수를&amp;nbsp;스택에&amp;nbsp;역순으로(오른쪽에서&amp;nbsp;왼쪽으로)&amp;nbsp;푸시합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 17.6356%; text-align: justify;&quot;&gt;__clrcall&lt;/td&gt;
&lt;td style=&quot;width: 17.7519%; text-align: justify;&quot;&gt;해당&amp;nbsp;없음&lt;/td&gt;
&lt;td style=&quot;width: 64.6124%; text-align: justify;&quot;&gt;CLR&amp;nbsp;식&amp;nbsp;스택에&amp;nbsp;매개&amp;nbsp;변수를&amp;nbsp;순서대로(왼쪽에서&amp;nbsp;오른쪽으로)&amp;nbsp;로드합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 17.6356%; text-align: justify;&quot;&gt;__stdcall&lt;/td&gt;
&lt;td style=&quot;width: 17.7519%; text-align: justify;&quot;&gt;호출&amp;nbsp;수신자&lt;/td&gt;
&lt;td style=&quot;width: 64.6124%; text-align: justify;&quot;&gt;매개&amp;nbsp;변수를&amp;nbsp;스택에&amp;nbsp;역순으로(오른쪽에서&amp;nbsp;왼쪽으로)&amp;nbsp;푸시합니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 17.6356%; text-align: justify;&quot;&gt;__fastcall&lt;/td&gt;
&lt;td style=&quot;width: 17.7519%; text-align: justify;&quot;&gt;호출&amp;nbsp;수신자&lt;/td&gt;
&lt;td style=&quot;width: 64.6124%; text-align: justify;&quot;&gt;레지스터에&amp;nbsp;저장된&amp;nbsp;다음&amp;nbsp;스택에&amp;nbsp;푸시됩니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 17.6356%; text-align: justify;&quot;&gt;__thiscall&lt;/td&gt;
&lt;td style=&quot;width: 17.7519%; text-align: justify;&quot;&gt;호출&amp;nbsp;수신자&lt;/td&gt;
&lt;td style=&quot;width: 64.6124%; text-align: justify;&quot;&gt;스택에&amp;nbsp;푸시됨;&amp;nbsp;this&amp;nbsp;ECX에&amp;nbsp;저장된&amp;nbsp;포인터&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 17.6356%; text-align: justify;&quot;&gt;__vectorcall&lt;/td&gt;
&lt;td style=&quot;width: 17.7519%; text-align: justify;&quot;&gt;호출&amp;nbsp;수신자&lt;/td&gt;
&lt;td style=&quot;width: 64.6124%; text-align: justify;&quot;&gt;레지스터에&amp;nbsp;저장된&amp;nbsp;다음&amp;nbsp;스택에&amp;nbsp;역순으로(오른쪽에서&amp;nbsp;왼쪽으로)&amp;nbsp;푸시됩니다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/cpp/cpp/argument-passing-and-naming-conventions?view=msvc-170&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;https://learn.microsoft.com/ko-kr/cpp/cpp/argument-passing-and-naming-conventions?view=msvc-170&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4.&amp;nbsp;함수&amp;nbsp;호출&amp;nbsp;규약&amp;nbsp;분류&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Win16 및 초기 컴파일러 환경에서는 각 프로그래밍 언어마다 고유한 호출 방식이 존재했고, 운영체제 내부용 전용 호출 규약도 함께 사용되었다. 그러나 이러한 다양성은 호환성 문제와 확장성의 한계를 드러냈고, 결국 Win32 시대에 들어 실무적으로 표준화된 호출 규약들이 등장하면서 언어나 환경을 넘어 보다 효율적이고 일관된 방식으로 정립되기 시작했다. 이후 Win64 환경에서는 아예 단일 호출 규약이 강제되어 모든 언어와 컴파일러가 통일된 방식으로 함수를 호출하게 되었으며, 사실상 호출 규약 간의 차이가 사라졌다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;convention_all2.jpg&quot; data-origin-width=&quot;3700&quot; data-origin-height=&quot;2475&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pdW1H/btsPB0vXWu3/nu2AsqIfxR1CjDRvhcfNI1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pdW1H/btsPB0vXWu3/nu2AsqIfxR1CjDRvhcfNI1/img.jpg&quot; data-alt=&quot;[이미지3] Calling Convention&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pdW1H/btsPB0vXWu3/nu2AsqIfxR1CjDRvhcfNI1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpdW1H%2FbtsPB0vXWu3%2Fnu2AsqIfxR1CjDRvhcfNI1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3700&quot; height=&quot;2475&quot; data-filename=&quot;convention_all2.jpg&quot; data-origin-width=&quot;3700&quot; data-origin-height=&quot;2475&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지3] Calling Convention&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글에서는 다양한 호출 규약 중에서도 현재 32비트 환경에서 가장 빈번히 사용되는 __cdecl, __stdcall, __fastcall, __vectorcall 만 집중적으로 다룬다.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. Windows x32 함수 호출 규약 비교&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;함수 호출 규약 각각의 인수 전달 방식, 인수 전달 매체, 스택 유지 관리 책임 ,함수 이름 데코레이션을 설명한다. 또한 이해를 돕기 위해 실제 예제 코드와 함께 호출 규약에 따른 함수 호출 과정의 차이를 비교한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;br /&gt;5-1. 예제 코드&lt;/h3&gt;
&lt;pre class=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

int int_add_fun(int a, int b, int c, int d) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int i1 = a;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int i2 = b;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int i3 = c;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int i4 = d;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int result = 0;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result = i1 + i2 + i3 + i4;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return result;
}

float float_add_fun(float a, float b, float c, float d) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float f1 = a;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float f2 = b;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float f3 = c;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float f4 = d;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float result = 0;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result = f1 + f2 + f3 + f4;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return result;
}

int main() {

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int int_result = int_add_fun(1, 2, 3, 4);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;printf(&quot;%d + %d + %d + %d = %d\n&quot;, 1, 2, 3, 4, int_result);

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;float float_result = float_add_fun(0.1f, 0.2f, 0.3f, 0.4f);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;printf(&quot;%.1f + %.1f + %.1f + %.1f = %.1f\n&quot;, 0.1f, 0.2f, 0.3f, 0.4f, float_result);

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 코드는 네 정수를 더하는 함수 int_add_fun과 네 소수를 더하는 함수 float_add_fun을 정의하고, 이를 main 함수에서 호출하여 결과를 출력하는 간단한 예제이다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;850&quot; data-origin-height=&quot;188&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2MacD/btsPlAp1ydz/OkzgjXke4RYN2xmKJwspE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2MacD/btsPlAp1ydz/OkzgjXke4RYN2xmKJwspE0/img.png&quot; data-alt=&quot;[이미지4] 실행 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2MacD/btsPlAp1ydz/OkzgjXke4RYN2xmKJwspE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2MacD%2FbtsPlAp1ydz%2FOkzgjXke4RYN2xmKJwspE0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;850&quot; height=&quot;188&quot; data-origin-width=&quot;850&quot; data-origin-height=&quot;188&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지4] 실행 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;5-2.&amp;nbsp;&lt;/span&gt;__stdcall&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4718&quot; data-origin-height=&quot;4270&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQLGBQ/btsPlMKUARw/kQyiVPwevD3Ut9D6P7VI81/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQLGBQ/btsPlMKUARw/kQyiVPwevD3Ut9D6P7VI81/img.jpg&quot; data-alt=&quot;[이미지5] __stdcall (/Od)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQLGBQ/btsPlMKUARw/kQyiVPwevD3Ut9D6P7VI81/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbQLGBQ%2FbtsPlMKUARw%2FkQyiVPwevD3Ut9D6P7VI81%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4718&quot; height=&quot;4270&quot; data-origin-width=&quot;4718&quot; data-origin-height=&quot;4270&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지5] __stdcall (/Od)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 113px;&quot; border=&quot;1&quot; data-ke-style=&quot;style12&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 50.0%; height: 22px; text-align: justify;&quot;&gt;항목&lt;/td&gt;
&lt;td style=&quot;width: 50.0%; height: 22px; text-align: justify;&quot;&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 50.0%; height: 22px; text-align: justify;&quot;&gt;인수 전달 순서&lt;/td&gt;
&lt;td style=&quot;width: 50.0%; height: 22px; text-align: justify;&quot;&gt;오른쪽 &amp;rarr; 왼쪽 (Right to Left)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 25px;&quot;&gt;
&lt;td style=&quot;width: 50.0%; height: 25px; text-align: justify;&quot;&gt;인수 전달 매체&lt;/td&gt;
&lt;td style=&quot;width: 50.0%; height: 25px; text-align: justify;&quot;&gt;스택 (All on stack)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 50.0%; height: 22px; text-align: justify;&quot;&gt;스택 유지 관리 책임&lt;/td&gt;
&lt;td style=&quot;width: 50.0%; height: 22px; text-align: justify;&quot;&gt;피호출자 (Callee)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 50.0%; height: 22px; text-align: justify;&quot;&gt;함수 이름 데코레이션&lt;/td&gt;
&lt;td style=&quot;width: 50.0%; height: 22px; text-align: justify;&quot;&gt;_&amp;lt;function&amp;nbsp;name&amp;gt;@&amp;lt;bytes&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;5-2-1. 인수 전달 순서&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4718&quot; data-origin-height=&quot;4270&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cDPCKf/btsPlReJ6Ka/sowxOEf4m2I0CrRqql3VU1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cDPCKf/btsPlReJ6Ka/sowxOEf4m2I0CrRqql3VU1/img.jpg&quot; data-alt=&quot;[이미지5] __stdcall (/Od) Parameter Passing Order&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cDPCKf/btsPlReJ6Ka/sowxOEf4m2I0CrRqql3VU1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcDPCKf%2FbtsPlReJ6Ka%2FsowxOEf4m2I0CrRqql3VU1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4718&quot; height=&quot;4270&quot; data-origin-width=&quot;4718&quot; data-origin-height=&quot;4270&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지5] __stdcall (/Od) Parameter Passing Order&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 인수(정수, 포인터, 부동소수점, 구조체 등)를 오른쪽에서 왼쪽 순으로 스택에 push한다.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5-2-2. 인수 전달 매체&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4718&quot; data-origin-height=&quot;4270&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cSWgHT/btsPmeG6QNR/U825MAMxHd6OvybTTdJ6cK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cSWgHT/btsPmeG6QNR/U825MAMxHd6OvybTTdJ6cK/img.jpg&quot; data-alt=&quot;[이미지6] __stdcall (/Od) Parameter Passing Medium&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cSWgHT/btsPmeG6QNR/U825MAMxHd6OvybTTdJ6cK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcSWgHT%2FbtsPmeG6QNR%2FU825MAMxHd6OvybTTdJ6cK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4718&quot; height=&quot;4270&quot; data-origin-width=&quot;4718&quot; data-origin-height=&quot;4270&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지6] __stdcall (/Od) Parameter Passing Medium&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 인수(정수, 포인터, 부동소수점, 구조체 등)를 스택으로 전달한다.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5-2-3. 스택 유지 관리 책임&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4718&quot; data-origin-height=&quot;4270&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bYvYDp/btsPleaoisK/tRHSIJsFPgAuKH476O9CoK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bYvYDp/btsPleaoisK/tRHSIJsFPgAuKH476O9CoK/img.jpg&quot; data-alt=&quot;[이미지7] __stdcall (/Od) Stack Cleanup Responsibility&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bYvYDp/btsPleaoisK/tRHSIJsFPgAuKH476O9CoK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbYvYDp%2FbtsPleaoisK%2FtRHSIJsFPgAuKH476O9CoK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4718&quot; height=&quot;4270&quot; data-origin-width=&quot;4718&quot; data-origin-height=&quot;4270&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지7] __stdcall (/Od) Stack Cleanup Responsibility&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Callee(피호출자)가 ret &amp;lt;n&amp;gt;으로 스택을 정리한다.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5-2-4. 함수 이름 데코레이션&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4718&quot; data-origin-height=&quot;4270&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lzg1E/btsPlcYc3yu/t9Z0b4frVrarV6khfF56u1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lzg1E/btsPlcYc3yu/t9Z0b4frVrarV6khfF56u1/img.jpg&quot; data-alt=&quot;[이미지8] __stdcall (/Od) Name Decoration Scheme&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lzg1E/btsPlcYc3yu/t9Z0b4frVrarV6khfF56u1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Flzg1E%2FbtsPlcYc3yu%2Ft9Z0b4frVrarV6khfF56u1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4718&quot; height=&quot;4270&quot; data-origin-width=&quot;4718&quot; data-origin-height=&quot;4270&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지8] __stdcall (/Od) Name Decoration Scheme&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;언더바(_)가 함수 이름 앞에 붙는다. 함수 이름 뒤에는 앳기호(@)가 오고 그 뒤에 인수 목록의 바이트 수(10진수)가 접미사로 지정된다.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5-3. __cdecl&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4718&quot; data-origin-height=&quot;4284&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b2ZAiY/btsPj138l2z/Pkz1DwklZ4wwlGHAA066bK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b2ZAiY/btsPj138l2z/Pkz1DwklZ4wwlGHAA066bK/img.jpg&quot; data-alt=&quot;[이미지9] __cdecl (/Od)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b2ZAiY/btsPj138l2z/Pkz1DwklZ4wwlGHAA066bK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb2ZAiY%2FbtsPj138l2z%2FPkz1DwklZ4wwlGHAA066bK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4718&quot; height=&quot;4284&quot; data-origin-width=&quot;4718&quot; data-origin-height=&quot;4284&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지9] __cdecl (/Od)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 113px;&quot; border=&quot;1&quot; data-ke-style=&quot;style12&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;항목&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;인수 전달 순서&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;오른쪽 &amp;rarr; 왼쪽 (Right to Left)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;인수 전달 매체&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;스택 (All on stack)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;스택 유지 관리 책임&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;호출자 (Caller)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;함수 이름 데코레이션&lt;/td&gt;
&lt;td style=&quot;text-align: justify;&quot;&gt;_&amp;lt;function name&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;br /&gt;5-3-1. 인수 전달 순서&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4718&quot; data-origin-height=&quot;4284&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xDIZ8/btsPlgzozzw/kEk2uA0VAq2ce4TstPeUj1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xDIZ8/btsPlgzozzw/kEk2uA0VAq2ce4TstPeUj1/img.jpg&quot; data-alt=&quot;[이미지10] __cdecl (/Od) Parameter Passing Order&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xDIZ8/btsPlgzozzw/kEk2uA0VAq2ce4TstPeUj1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxDIZ8%2FbtsPlgzozzw%2FkEk2uA0VAq2ce4TstPeUj1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4718&quot; height=&quot;4284&quot; data-origin-width=&quot;4718&quot; data-origin-height=&quot;4284&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지10] __cdecl (/Od) Parameter Passing Order&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 인수(정수, 포인터, 부동소수점, 구조체 등)를 오른쪽에서 왼쪽 순으로 스택에 push한다.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5-3-2. 인수 전달 매체&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4718&quot; data-origin-height=&quot;4284&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmXfHk/btsPk3GQQIO/yWLkRMiYqYLKBMvM6rcv7K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmXfHk/btsPk3GQQIO/yWLkRMiYqYLKBMvM6rcv7K/img.jpg&quot; data-alt=&quot;[이미지11] __cdecl (/Od) Parameter Passing Medium&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmXfHk/btsPk3GQQIO/yWLkRMiYqYLKBMvM6rcv7K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbmXfHk%2FbtsPk3GQQIO%2FyWLkRMiYqYLKBMvM6rcv7K%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4718&quot; height=&quot;4284&quot; data-origin-width=&quot;4718&quot; data-origin-height=&quot;4284&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지11] __cdecl (/Od) Parameter Passing Medium&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 인수(정수, 포인터, 부동소수점, 구조체 등)를 스택으로 전달한다.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5-3-3. 스택 유지 관리 책임&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4718&quot; data-origin-height=&quot;4284&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bL8rwZ/btsPma5UEgn/UmrYwobBKgpXEEPYCfKkHK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bL8rwZ/btsPma5UEgn/UmrYwobBKgpXEEPYCfKkHK/img.jpg&quot; data-alt=&quot;[이미지12] __cdecl (/Od) Stack Cleanup Responsibility&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bL8rwZ/btsPma5UEgn/UmrYwobBKgpXEEPYCfKkHK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbL8rwZ%2FbtsPma5UEgn%2FUmrYwobBKgpXEEPYCfKkHK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4718&quot; height=&quot;4284&quot; data-origin-width=&quot;4718&quot; data-origin-height=&quot;4284&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지12] __cdecl (/Od) Stack Cleanup Responsibility&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Caller(호출자)가 add esp, &amp;lt;n&amp;gt;으로 스택을 정리한다.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5-3-4. 함수 이름 데코레이션&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4718&quot; data-origin-height=&quot;4284&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVVheK/btsPj9Bf9Rs/o1YyKJkVM5fGKOUG4YArN0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVVheK/btsPj9Bf9Rs/o1YyKJkVM5fGKOUG4YArN0/img.jpg&quot; data-alt=&quot;[이미지13] __cdecl (/Od) Name Decoration Scheme&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVVheK/btsPj9Bf9Rs/o1YyKJkVM5fGKOUG4YArN0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVVheK%2FbtsPj9Bf9Rs%2Fo1YyKJkVM5fGKOUG4YArN0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4718&quot; height=&quot;4284&quot; data-origin-width=&quot;4718&quot; data-origin-height=&quot;4284&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지13] __cdecl (/Od) Name Decoration Scheme&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C&amp;nbsp;링크를&amp;nbsp;사용하는&amp;nbsp;__cdecl&amp;nbsp;함수를&amp;nbsp;내보낼&amp;nbsp;경우를&amp;nbsp;제외하고&amp;nbsp;언더바(_)는&amp;nbsp;함수&amp;nbsp;이름&amp;nbsp;앞에&amp;nbsp;접두사로&amp;nbsp;지정된다.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5-4. __fastcall&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4718&quot; data-origin-height=&quot;4382&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFNywK/btsPkaNuWN9/ivMZD8LOxS2zcGxp7N4JK0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFNywK/btsPkaNuWN9/ivMZD8LOxS2zcGxp7N4JK0/img.jpg&quot; data-alt=&quot;[이미지14] __fastcall (/Od)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFNywK/btsPkaNuWN9/ivMZD8LOxS2zcGxp7N4JK0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFNywK%2FbtsPkaNuWN9%2FivMZD8LOxS2zcGxp7N4JK0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4718&quot; height=&quot;4382&quot; data-origin-width=&quot;4718&quot; data-origin-height=&quot;4382&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지14] __fastcall (/Od)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 122px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;항목&lt;/td&gt;
&lt;td style=&quot;width: 66.6666%; height: 22px;&quot; colspan=&quot;2&quot;&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;레지스터 (Register)&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;스택 (Stack)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;인수 전달 순서&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;왼쪽 &amp;rarr; 오른쪽 (Left to right)&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;오른쪽&amp;nbsp;&amp;rarr;&amp;nbsp;왼쪽&amp;nbsp;(Right&amp;nbsp;to&amp;nbsp;left)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;인수 전달 매체&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;ECX, EDX&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;Stack&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;스택 유지 관리 책임&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;X&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;피호출자 (Callee)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px;&quot;&gt;함수 이름 데코레이션&lt;/td&gt;
&lt;td style=&quot;width: 66.6666%; height: 17px;&quot; colspan=&quot;2&quot;&gt;@&amp;lt;function&amp;nbsp;name&amp;gt;@&amp;lt;bytes&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5-4-1. 인수 전달 순서&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4718&quot; data-origin-height=&quot;4382&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cdV8P0/btsPlNKeLUk/RMDHyjFej1FgyiNCrHXn90/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cdV8P0/btsPlNKeLUk/RMDHyjFej1FgyiNCrHXn90/img.jpg&quot; data-alt=&quot;[이미지15] __fastcall (/Od) Parameter Passing Order&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cdV8P0/btsPlNKeLUk/RMDHyjFej1FgyiNCrHXn90/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcdV8P0%2FbtsPlNKeLUk%2FRMDHyjFej1FgyiNCrHXn90%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4718&quot; height=&quot;4382&quot; data-origin-width=&quot;4718&quot; data-origin-height=&quot;4382&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지15] __fastcall (/Od) Parameter Passing Order&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정수, 포인터 인수의 경우 첫 번째와 두 번째 인수를 각각 ECX, EDX 레지스터에 로드하고, 세 번째 이후 인수는 오른쪽에서 왼쪽 순으로 스택에 push한다. 부동소수점 및 레지스터 크기를 벗어나는 인수(64비트 자료형, 구조체 등)는 모두 오른쪽에서 왼쪽 순으로 스택에 push하며, ECX, EDX를 사용하지 않는다.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5-4-2. 인수 전달 매체&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4718&quot; data-origin-height=&quot;4382&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nJK9S/btsPlReF73G/ektSfKkocRb8CeT3qBfifK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nJK9S/btsPlReF73G/ektSfKkocRb8CeT3qBfifK/img.jpg&quot; data-alt=&quot;[이미지16] __fastcall (/Od) Parameter Passing Medium&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nJK9S/btsPlReF73G/ektSfKkocRb8CeT3qBfifK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnJK9S%2FbtsPlReF73G%2FektSfKkocRb8CeT3qBfifK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4718&quot; height=&quot;4382&quot; data-origin-width=&quot;4718&quot; data-origin-height=&quot;4382&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지16] __fastcall (/Od) Parameter Passing Medium&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정수 및 포인터 두 인수는 레지스터(ECX, EDX)로, 나머지 인수는 스택으로 전달한다.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5-4-3. 스택 유지 관리 책임&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4718&quot; data-origin-height=&quot;4382&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xfmcr/btsPkQOrFWp/vtQVBZahP5q35Qnb5alBP0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xfmcr/btsPkQOrFWp/vtQVBZahP5q35Qnb5alBP0/img.jpg&quot; data-alt=&quot;[이미지17] __fastcall (/Od) Stack Cleanup Responsibility&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xfmcr/btsPkQOrFWp/vtQVBZahP5q35Qnb5alBP0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fxfmcr%2FbtsPkQOrFWp%2FvtQVBZahP5q35Qnb5alBP0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4718&quot; height=&quot;4382&quot; data-origin-width=&quot;4718&quot; data-origin-height=&quot;4382&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지17] __fastcall (/Od) Stack Cleanup Responsibility&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Callee(피호출자)가 ret &amp;lt;n&amp;gt;으로 스택을 정리한다.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5-4-4. 함수 이름 데코레이션&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4718&quot; data-origin-height=&quot;4382&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZnep8/btsPmfTSx6M/L9pCM7puIhKYJM7YN7kMhK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZnep8/btsPmfTSx6M/L9pCM7puIhKYJM7YN7kMhK/img.jpg&quot; data-alt=&quot;[이미지18] __fastcall (/Od) Name Decoration Scheme&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZnep8/btsPmfTSx6M/L9pCM7puIhKYJM7YN7kMhK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZnep8%2FbtsPmfTSx6M%2FL9pCM7puIhKYJM7YN7kMhK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4718&quot; height=&quot;4382&quot; data-origin-width=&quot;4718&quot; data-origin-height=&quot;4382&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지18] __fastcall (/Od) Name Decoration Scheme&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수 이름 앞, 뒤에 앳기호(@)가 붙는다. 매개 변수 목록의 바이트 수(10진수)가 접미사로 지정된다.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;5-5. __vectorcall&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4718&quot; data-origin-height=&quot;4604&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cvVNXx/btsPlhrpTHZ/FGz1mPoZNY5tUyasKtbj40/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cvVNXx/btsPlhrpTHZ/FGz1mPoZNY5tUyasKtbj40/img.jpg&quot; data-alt=&quot;[이미지19] __vectorcall (/Od)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cvVNXx/btsPlhrpTHZ/FGz1mPoZNY5tUyasKtbj40/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcvVNXx%2FbtsPlhrpTHZ%2FFGz1mPoZNY5tUyasKtbj40%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4718&quot; height=&quot;4604&quot; data-origin-width=&quot;4718&quot; data-origin-height=&quot;4604&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지19] __vectorcall (/Od)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style12&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #9b9b9b; color: #ffffff;&quot;&gt;항목&lt;/td&gt;
&lt;td style=&quot;background-color: #9b9b9b; color: #ffffff;&quot; colspan=&quot;2&quot;&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #efefef;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;레지스터 (Register)&lt;/td&gt;
&lt;td&gt;스택 (Stack)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #efefef;&quot;&gt;인수 전달 순서&lt;/td&gt;
&lt;td style=&quot;background-color: #f9f9f9;&quot;&gt;왼쪽 &amp;rarr; 오른쪽 (Left to right)&lt;/td&gt;
&lt;td style=&quot;background-color: #f9f9f9;&quot;&gt;오른쪽&amp;nbsp;&amp;rarr;&amp;nbsp;왼쪽&amp;nbsp;(Right&amp;nbsp;to&amp;nbsp;left)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #efefef;&quot;&gt;인수 전달 매체&lt;/td&gt;
&lt;td&gt;ECX, EDX, XMM0 ~ XMM5&lt;/td&gt;
&lt;td&gt;Stack&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #efefef;&quot;&gt;스택 유지 관리 책임&lt;/td&gt;
&lt;td style=&quot;background-color: #f9f9f9;&quot;&gt;X&lt;/td&gt;
&lt;td style=&quot;background-color: #f9f9f9;&quot;&gt;피호출자 (Callee)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #efefef;&quot;&gt;함수 이름 데코레이션&lt;/td&gt;
&lt;td colspan=&quot;2&quot;&gt;&amp;lt;function&amp;nbsp;name&amp;gt;@@&amp;lt;bytes&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5-5-1. 인수 전달 순서&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4718&quot; data-origin-height=&quot;4604&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brdpOm/btsPle9rKLV/StxqkRc8mgdGh0C6mqBC11/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brdpOm/btsPle9rKLV/StxqkRc8mgdGh0C6mqBC11/img.jpg&quot; data-alt=&quot;[이미지20] __vectorcall (/Od) Parameter Passing Order&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brdpOm/btsPle9rKLV/StxqkRc8mgdGh0C6mqBC11/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbrdpOm%2FbtsPle9rKLV%2FStxqkRc8mgdGh0C6mqBC11%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4718&quot; height=&quot;4604&quot; data-origin-width=&quot;4718&quot; data-origin-height=&quot;4604&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지20] __vectorcall (/Od) Parameter Passing Order&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정수, 포인터 인수의 경우 첫 번째와 두 번째 인수를 각각 ECX, EDX 레지스터에 로드하고, 세 번째 이후 인수는 오른쪽에서 왼쪽 순으로 스택에 push한다. 레지스터 크기를 벗어나는 인수(64비트 자료형, 구조체 등)는 모두 오른쪽에서 왼쪽 순으로 스택에 push하며, ECX, EDX를 사용하지 않는다. 부동소수점 및 벡터 인수는 왼쪽에서 오른쪽 순으로 XMM0부터 최대 XMM5까지 채운다. 레지스터에 실리지 못한 인수는 오른쪽에서 왼쪽 순으로 스택에 push한다.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5-5-2. 인수 전달 매체&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4718&quot; data-origin-height=&quot;4604&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/A3xQO/btsPlGRV3B7/HiuXtwNwz6nZpdD6d9cqkK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/A3xQO/btsPlGRV3B7/HiuXtwNwz6nZpdD6d9cqkK/img.jpg&quot; data-alt=&quot;[이미지21] __vectorcall (/Od) Parameter Passing Medium&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/A3xQO/btsPlGRV3B7/HiuXtwNwz6nZpdD6d9cqkK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FA3xQO%2FbtsPlGRV3B7%2FHiuXtwNwz6nZpdD6d9cqkK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4718&quot; height=&quot;4604&quot; data-origin-width=&quot;4718&quot; data-origin-height=&quot;4604&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지21] __vectorcall (/Od) Parameter Passing Medium&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부동소수점 및 벡터 인수는 XMM0~XMM5 레지스터, 정수 및 포인터 인수는 ECX, EDX 레지스터로, 나머지 인수는 스택으로 전달한다.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5-5-3. 스택 유지 관리 책임&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4718&quot; data-origin-height=&quot;4604&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cmOKZv/btsPl7n4PDu/l0Dt5MLskMX2R89ZLQQ3b1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cmOKZv/btsPl7n4PDu/l0Dt5MLskMX2R89ZLQQ3b1/img.jpg&quot; data-alt=&quot;[이미지22] __vectorcall (/Od) Stack Cleanup Responsibility&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cmOKZv/btsPl7n4PDu/l0Dt5MLskMX2R89ZLQQ3b1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcmOKZv%2FbtsPl7n4PDu%2Fl0Dt5MLskMX2R89ZLQQ3b1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4718&quot; height=&quot;4604&quot; data-origin-width=&quot;4718&quot; data-origin-height=&quot;4604&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지22] __vectorcall (/Od) Stack Cleanup Responsibility&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Callee(피호출자)가 ret &amp;lt;n&amp;gt;으로 스택을 정리한다.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;5-5-4. 함수 이름 데코레이션&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4718&quot; data-origin-height=&quot;4604&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/U8W5A/btsPlALfG5H/jhf2GYIBFmVpnF7mnMsY60/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/U8W5A/btsPlALfG5H/jhf2GYIBFmVpnF7mnMsY60/img.jpg&quot; data-alt=&quot;[이미지23] __vectorcall (/Od) Name Decoration Scheme&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/U8W5A/btsPlALfG5H/jhf2GYIBFmVpnF7mnMsY60/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FU8W5A%2FbtsPlALfG5H%2Fjhf2GYIBFmVpnF7mnMsY60%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4718&quot; height=&quot;4604&quot; data-origin-width=&quot;4718&quot; data-origin-height=&quot;4604&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지23] __vectorcall (/Od) Name Decoration Scheme&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수 이름 뒤에 두 개의 앳기호(@@)가 붙고 그 뒤에 매개 변수 목록의 바이트 수(10진수) 접미사로 지정된다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;table.jpg&quot; data-origin-width=&quot;4776&quot; data-origin-height=&quot;1292&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/A3iRC/btsPDpuO03Y/erISaQKbOjRXbe9WPk8djk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/A3iRC/btsPDpuO03Y/erISaQKbOjRXbe9WPk8djk/img.jpg&quot; data-alt=&quot;[이미지24] 함수 호출 규약 (Calling Convention)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/A3iRC/btsPDpuO03Y/erISaQKbOjRXbe9WPk8djk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FA3iRC%2FbtsPDpuO03Y%2FerISaQKbOjRXbe9WPk8djk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4776&quot; height=&quot;1292&quot; data-filename=&quot;table.jpg&quot; data-origin-width=&quot;4776&quot; data-origin-height=&quot;1292&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지24] 함수 호출 규약 (Calling Convention)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;6. 함수 호출 규약의 분기 원인과 설계적 배경&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6-1. &amp;nbsp;__stdcall : Win32의 기본 호출 규약&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;__stdcall은 16비트 Windows 시절의 __pascal 호출 규약을 기반으로 만들어진 Win32의 표준 호출 규약이다. __pascal 규약처럼 피호출자(callee)가 스택을 정리한다는 특징은 유지하면서도, 인자 전달 순서는 C 언어의 관례대로 오른쪽에서 왼쪽 순으로 바꾸었다. 덕분에 호출할 때마다 스택 정리 코드를 작성할 필요가 없어 코드 크기를 줄이고 프로그래머의 실수를 줄일 수 있어 Windows API나 COM 인터페이스의 기본 호출 방식으로 자리 잡았다. standard call이라는 명칭에서도 알 수 있듯이 Windows API의 대부분 함수들이 이 규약을 따르고 있다.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6-2. &lt;span style=&quot;color: #333333;&quot;&gt;__cdecl : &lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;가변 인자를 위한 호출 규약&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdarg.h&amp;gt;

int main(void)
{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int total = var_add_fun(10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;printf(&quot;total = %d\n&quot;, total);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return 0;
}

int var_add_fun(int count, ...)
{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int result = 0;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;va_list args;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;va_start(args, count);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for (int i = 0; i &amp;lt; count; ++i) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result += va_arg(args, int);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;va_end(args);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return result;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드는 가변 인자 n개를 모두 더한 뒤 그 합계를  printf로 출력하고 종료하는 프로그램이다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;927&quot; data-origin-height=&quot;140&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ba4mrT/btsPmxN6wtr/nybg6gvVNPziADNmSk5mhK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ba4mrT/btsPmxN6wtr/nybg6gvVNPziADNmSk5mhK/img.png&quot; data-alt=&quot;[이미지25] C2373 Error&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ba4mrT/btsPmxN6wtr/nybg6gvVNPziADNmSk5mhK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fba4mrT%2FbtsPmxN6wtr%2Fnybg6gvVNPziADNmSk5mhK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;927&quot; height=&quot;140&quot; data-origin-width=&quot;927&quot; data-origin-height=&quot;140&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지25] C2373 Error&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;__stdcall로 해당 코드를 빌드할 수 없다. 그 이유는 헤더 선언이 없으면 컴파일러는 int var_add_fun(int , ...); 함수를 묵시적으로 __cdecl로 가정해 첫 선언을 만든다. &lt;span style=&quot;color: #333333;&quot;&gt;__stdcall로 빌드를 진행하면&amp;nbsp;&lt;/span&gt;실제로 작성된 함수의 정의는 int __stdcall var_add_fun(int , ... )로 설정되기 때문에 동일 식별자에 대해 두 번째 선언의 호출 규약이 다르다고 판단해 C2373 컴파일러 오류가 발생한다. __cdecl로 빌드 시 정상적으로 동작한다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;919&quot; data-origin-height=&quot;719&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/w0VlV/btsPlNqtBOv/4z3gIING7gmY2mvhQ9xOBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/w0VlV/btsPlNqtBOv/4z3gIING7gmY2mvhQ9xOBk/img.png&quot; data-alt=&quot;[이미지26] C2373 (https://learn.microsoft.com/ko-kr/cpp/error-messages/compiler-errors-1/compiler-error-c2373?view=msvc-170)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/w0VlV/btsPlNqtBOv/4z3gIING7gmY2mvhQ9xOBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fw0VlV%2FbtsPlNqtBOv%2F4z3gIING7gmY2mvhQ9xOBk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;919&quot; height=&quot;719&quot; data-origin-width=&quot;919&quot; data-origin-height=&quot;719&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지26] C2373 (https://learn.microsoft.com/ko-kr/cpp/error-messages/compiler-errors-1/compiler-error-c2373?view=msvc-170)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MSVC 에러 C2373는 같은 함수 이름이 이전 선언과 다른 호출 규약, 수식어로 다시 선언 및 정의될 때 발생한다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4369&quot; data-origin-height=&quot;1678&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nLxK7/btsPlf8XVxj/ZXrLIYKxJPzBpIr5LCJKLk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nLxK7/btsPlf8XVxj/ZXrLIYKxJPzBpIr5LCJKLk/img.jpg&quot; data-alt=&quot;[이미지27] __stdcall 선언&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nLxK7/btsPlf8XVxj/ZXrLIYKxJPzBpIr5LCJKLk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnLxK7%2FbtsPlf8XVxj%2FZXrLIYKxJPzBpIr5LCJKLk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4369&quot; height=&quot;1678&quot; data-origin-width=&quot;4369&quot; data-origin-height=&quot;1678&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지27] __stdcall 선언&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 var_add_fun 함수를 __stdcall로 선언하고, 실제로 해당 호출 규약을 __stdcall로 적용해 빌드한다면 어떤 결과가 나타날까?&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;469&quot; data-origin-height=&quot;579&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGwp9u/btsPlfVrkpw/kIkYMKJIokgvavAhjx8C3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGwp9u/btsPlfVrkpw/kIkYMKJIokgvavAhjx8C3k/img.png&quot; data-alt=&quot;[이미지28] main&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGwp9u/btsPlfVrkpw/kIkYMKJIokgvavAhjx8C3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGwp9u%2FbtsPlfVrkpw%2FkIkYMKJIokgvavAhjx8C3k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;469&quot; height=&quot;579&quot; data-origin-width=&quot;469&quot; data-origin-height=&quot;579&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지28] main&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디버깅 후 어셈블리 코드를 분석해 보면, 함수 이름 데코레이션과 호출자(Caller)가 스택을 정리한다는 점을 토대로 var_fun_add 함수가 __cdecl로 강제 변환되었음을 확인할 수 있다. 이를 통해 함수에 호출 규약을 명시하지 않은 경우, 그리고 함수 선언에 __stdcall이나 다른 규약을 명시하더라도 가변 인자 함수인 경우에는 무조건 __cdecl로 강제된다는 것을 알 수 있다(&lt;a href=&quot;https://learn.microsoft.com/ko-kr/cpp/cpp/stdcall?view=msvc-170&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;https://learn.microsoft.com/ko-kr/cpp/cpp/stdcall?view=msvc-170&lt;/span&gt;&lt;/a&gt;).&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4401&quot; data-origin-height=&quot;2479&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvCVmt/btsPmUCMX1l/2X9s65YEWkC0a3EBkLqT1k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvCVmt/btsPmUCMX1l/2X9s65YEWkC0a3EBkLqT1k/img.jpg&quot; data-alt=&quot;[이미지29] Caller Callee&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvCVmt/btsPmUCMX1l/2X9s65YEWkC0a3EBkLqT1k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbvCVmt%2FbtsPmUCMX1l%2F2X9s65YEWkC0a3EBkLqT1k%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4401&quot; height=&quot;2479&quot; data-origin-width=&quot;4401&quot; data-origin-height=&quot;2479&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지29] Caller Callee&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;__cdecl로 강제되는 이유는 __stdcall과 같이 Callee(피호출자)에서 스택을 정리하는 경우는 Callee(피호출자)에서 인자 개수를 알 수 없기 때문에 해당 호출 규약을 가변 함수에 적용할 수 없기 때문이다. 또한 호출 규약을 명시하지 않은 경우에도 인자 개수, 타입 정보를 알 수 없는 상태이기 때문에 가장 안전하고 보편적인 호출을 보장하려면 __cdecl이 기본값일 수 밖에 없다. 위 이미지를 보면 Caller(호출자)는 함수를 호출하기 전, 인자를 직접 push(또는 ESP에 mov)하기 때문에 인자의 크기를 알 수 있다. 하지만 Callee(피호출자)는 스택에 존재하는 인자값을 가져와서 함수 내부코드만 수행하기 때문에 인자의 크기를 알 수가 없는 것이다. 이 경우는 가변인자를 사용했을 때 나타나며, 인자의 개수가 고정적일 때에는 Callee(피호출자) 또한 인자의 크기를 파악할 수 있다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4401&quot; data-origin-height=&quot;2479&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/caGUVj/btsPnFx87Li/OcmKwakOZdOeow037KcLek/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/caGUVj/btsPnFx87Li/OcmKwakOZdOeow037KcLek/img.jpg&quot; data-alt=&quot;[이미지30] Caller Callee&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/caGUVj/btsPnFx87Li/OcmKwakOZdOeow037KcLek/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcaGUVj%2FbtsPnFx87Li%2FOcmKwakOZdOeow037KcLek%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4401&quot; height=&quot;2479&quot; data-origin-width=&quot;4401&quot; data-origin-height=&quot;2479&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지30] Caller Callee&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Callee에서 가변 인자의 개수를&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;절대로 &lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;알 수 없는 것은 아니다. 가변 인자 모두를 사용하도록 코드를 작성 한다면 Callee에서도 인자의 크기를 알 수 있다. 그렇다면 왜 &quot;Callee(피호출자)에서 인자의 크기를 알 수가 없다.&quot;라고 정의하는 것일까. 이 질문을 조금 바꿔서 &quot;위와 같이 Caller에서 인자의 개수를 바꿔가면서 함수를 호출했다면 컴파일 시점에서 Callee의 ret &amp;lt;n&amp;gt;에 &amp;lt;n&amp;gt; 값을 쓸 수 있는가?&quot;에 대한 답을 하면 된다. &lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;함수를 호출한다는 것은 그 함수로 jmp 한다는 것을 의미한다(push eip와 더불어). Caller에서 호출을 여러번 했지만 이는 var_add_fun 함수가 여러 개 인것을 뜻하지는 않는다. 호출에서 모두 동일한 var_add_fun에 접근하고 있다. 이 때 ret &amp;lt;n&amp;gt;에 값을 쓸 수 있을까? 컴파일 시점에서 &amp;lt;n&amp;gt;의 값을 다르게 설정하기 위해서는 함수를 호출할 때 마다 var_add_fun 전체를 복사해서 ret &amp;lt;n&amp;gt; 값을 바꿔줘야 할 것이다. 이는 코드 중복을 유발하고 실행 파일의 크기를 불필요하게 증가시키며, 함수 재사용이라는 개념을 무력화시킨다는 점에서 매우 비효율적이다.&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4401&quot; data-origin-height=&quot;2479&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6QvI4/btsPn1Vmwgi/atx4xuaCkuBPu4VSs9EGa0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6QvI4/btsPn1Vmwgi/atx4xuaCkuBPu4VSs9EGa0/img.jpg&quot; data-alt=&quot;[이미지31] Caller Callee&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6QvI4/btsPn1Vmwgi/atx4xuaCkuBPu4VSs9EGa0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6QvI4%2FbtsPn1Vmwgi%2Fatx4xuaCkuBPu4VSs9EGa0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4401&quot; height=&quot;2479&quot; data-origin-width=&quot;4401&quot; data-origin-height=&quot;2479&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지31] Caller Callee&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Caller에서 가변 인자의 크기를 계산할 수 있다면 그 값을 Callee에 넘겨줘서 &amp;lt;n&amp;gt;의 값을 바꾸면 되지 않을까? 이론적으로는 가능하지만 현실적으로는 매우 비효율적인 방식이다. ret &amp;lt;n&amp;gt;은 컴파일 시점에 상수로 결정되는 기계어 명령어이기 때문에, 실행 중에 가변적으로 값을 바꿀 수 없다. 만약 동적으로 바꾸려면 ret 명령 자체를 가변 인자 크기를 받아오는 형태로 모두 교체해야 하는데, 이는 오히려 함수 구조를 깨뜨리고 오버헤드를 유발한다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4647&quot; data-origin-height=&quot;2498&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bOz4iq/btsPmgzJRSu/G9GXzKwv8X7ewi0vmWuQ1k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bOz4iq/btsPmgzJRSu/G9GXzKwv8X7ewi0vmWuQ1k/img.jpg&quot; data-alt=&quot;[이미지32] printf&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bOz4iq/btsPmgzJRSu/G9GXzKwv8X7ewi0vmWuQ1k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbOz4iq%2FbtsPmgzJRSu%2FG9GXzKwv8X7ewi0vmWuQ1k%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4647&quot; height=&quot;2498&quot; data-origin-width=&quot;4647&quot; data-origin-height=&quot;2498&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지32] printf&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이처럼 가변 인자를 처리하는 구조적 한계로 인해, 호출 규약이 다르더라도 가변 인자 함수를 호출할 때에는 반드시 __cdecl 호출 규약을 따라야 한다. 실제로 __stdcall, __fastcall, __vectorcall 등 다른 호출 규약을 사용하는 환경에서도, printf와 같은 대표적인 가변 인자 함수는 항상 __cdecl로 호출되는 것을 확인할 수 있다. 이는 호출 규약의 선언과 무관하게, 가변 인자 함수는 Caller&lt;span style=&quot;color: #333333;&quot;&gt;(호출자&lt;/span&gt;)가 스택을 정리해야만 올바르게 동작할 수 있기 때문이다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4208&quot; data-origin-height=&quot;1256&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3UyzY/btsPmK1FMFU/Y7RDlODdsn7iFXC7cKkJ00/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3UyzY/btsPmK1FMFU/Y7RDlODdsn7iFXC7cKkJ00/img.jpg&quot; data-alt=&quot;[이미지33] nop patch&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3UyzY/btsPmK1FMFU/Y7RDlODdsn7iFXC7cKkJ00/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3UyzY%2FbtsPmK1FMFU%2FY7RDlODdsn7iFXC7cKkJ00%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4208&quot; height=&quot;1256&quot; data-origin-width=&quot;4208&quot; data-origin-height=&quot;1256&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지33] nop patch&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 가변 인자 함수를 사용하는 코드에서 __stdcall처럼 Callee(피호출자)가 스택을 정리하는 방식으로 동작하게 되면 어떤 문제가 발생할까? 앞서 설명했듯이, 이러한 상황은 컴파일러가 호출 규약과 가변 인자 구조의 불일치를 감지하여 빌드 자체를 허용하지 않기 때문에 정상적으로 생성할 수 없다. 따라서 해당 코드를 __cdecl로 빌드한 뒤, Caller(호출자)에서 수행하는 스택 정리 명령어 add esp, &amp;lt;n&amp;gt;을 nop 패치하여 강제로 호출 규약을 변경한다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;574&quot; data-origin-height=&quot;196&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bi5kSD/btsPlKnOMD3/NwTSPKwHOcnYu2uGFf0YIk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bi5kSD/btsPlKnOMD3/NwTSPKwHOcnYu2uGFf0YIk/img.png&quot; data-alt=&quot;[이미지34] 실행 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bi5kSD/btsPlKnOMD3/NwTSPKwHOcnYu2uGFf0YIk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbi5kSD%2FbtsPlKnOMD3%2FNwTSPKwHOcnYu2uGFf0YIk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;574&quot; height=&quot;196&quot; data-origin-width=&quot;574&quot; data-origin-height=&quot;196&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지34] 실행 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행 결과, 프로그램은 정상적으로 실행된다. 표면적으로는 문제가 없는 것처럼 보이지만 함수 호출 전후의 ESP 값을 비교해 보면 호출 이후 ESP가 원래 위치로 되돌아오지 않았다는 점을 통해 스택이 정리되지 않았음을 확인할 수 있다. 이는 add esp, &amp;lt;n&amp;gt; 명령어가 제거되었기 때문에, 가변 인자로 전달된 인자들이 스택에 그대로 남아 있는 상태가 된다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdarg.h&amp;gt;

int __cdecl var_add_fun(int count, ...);

int main(void)
{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for (int i = 0; i &amp;lt; 1000000; i++) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int total = var_add_fun(10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;printf(&quot;total = %d\n&quot;, total);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return 0;
}

int var_add_fun(int count, ...)
{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int result = 0;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;va_list args;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;va_start(args, count);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for (int i = 0; i &amp;lt; count; ++i) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result += va_arg(args, int);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;va_end(args);
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return result;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 함수가 프로그램 내에서 여러 번 호출되는 상황을 가정하고, 반복문을 이용해 해당 함수를 100만 회 호출한 뒤, 그 결과가 어떻게 나타나는지 확인한다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1162&quot; data-origin-height=&quot;600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sC9Fm/btsPmo5NJy6/3x5eT4khUtApS9ytZhaT1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sC9Fm/btsPmo5NJy6/3x5eT4khUtApS9ytZhaT1k/img.png&quot; data-alt=&quot;[이미지35] nop patch&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sC9Fm/btsPmo5NJy6/3x5eT4khUtApS9ytZhaT1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsC9Fm%2FbtsPmo5NJy6%2F3x5eT4khUtApS9ytZhaT1k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1162&quot; height=&quot;600&quot; data-origin-width=&quot;1162&quot; data-origin-height=&quot;600&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지35] nop patch&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;호출자에 의해 스택이 정리되지 않은 상태가 매 호출마다 누적되면서 스택 영역이 점차 소진되고 결국 가드 페이지를 침범하기 때문에 EXCEPTION_STACK_OVERFLOW 예외가 발생한다. 이러한 구조적 제약으로 인해, __stdcall 호출 규약에서는 가변 인자를 수용할 수 없고 가변 인자 함수는 반드시 Caller(호출자)가 스택을 정리하는 __cdecl 호출 규약을 따르도록 강제되는 것이다. __cdecl은 Caller(호출자)가 스택을 정리하기 때문에, __stdcall에 비해 add esp, 명령어 한 줄이 추가되어 코드 크기가 다소 커질 수 있다. 하지만 이 한 줄로 가변 인자를 포함한 다양한 호출 상황을 유연하게 처리할 수 있다는 점에서, __cdecl은 단순한 대체가 불가능한, 매우 효율적인 호출 규약이라 할 수 있다.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;6-3. __fastcall : 호출 성능 향상을 위한 레지스터 최적화&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;__fastcall은 함수 호출 시 전달되는 인자 중 일부를 레지스터로 전달함으로써 호출 성능을 개선하기 위해 도입된 호출 규약이다. 기존의 __stdcall과 __cdecl에서는 모든 인자를 스택에 push하여 전달했기 때문에, 호출 시마다 메모리 접근이 필요했고 이로 인한 오버헤드가 존재했다. __fastcall은 이러한 호출 비용을 줄이기 위해, 첫 번째와 두 번째 정수형 또는 포인터 인자를 각각 ECX, EDX 레지스터에 저장하고, 그 이후의 인자들만 스택을 통해 전달한다. 이로 인해 스택 접근을 최소화할 수 있으며, 특히 짧고 빈번하게 호출되는 함수에서 유의미한 성능 향상을 기대할 수 있다. 다만 __fastcall은 부동소수점, 구조체 등은 모두 스택을 통해 전달된다는 제약을 가진다. 또한 전달할 인자가 많을 경우, 결국 대부분의 인자가 스택으로 넘어가게 되어 성능 개선 효과가 제한적이다. 컴파일러에 따라 구현 방식이 상이하며, 표준이 아닌 비표준 확장 규약 이기 때문에, 외부 라이브러리나 플랫폼 간 호환성이 떨어질 수 있다는 문제점 또한 존재한다. 그럼에도 불구하고 __fastcall은 호출 오버헤드를 줄이려는 설계 목적에 부합하며 이는 이후 등장하는 __vectorcall 규약의 기반이 된다. 호출 규약 설계가 점점 스택 &amp;rarr; 레지스터 중심으로 최적화되는 흐름을 보여준다.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;6-4. __vectorcall : 부동소수점과 SIMD 연산을 위한 호출 최적화&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color: #333333;&quot;&gt;__fastcall은 두 개의 정수, 포인터 인수를 ECX, EDX로 전달해 스택 접근을 줄였지만, 부동소수점, SIMD 데이터에는 전혀 최적화가 없다는 한계가 있었다. x86 SSE, XMM 레지스터를 활용하지 못해 스택을 사용했고, 3D 벡터나 행렬처럼 128bit 이상 자료형은 매 호출마다 메모리를 오가야 했다. 이 병목을 해소하려고 MSVC 2013부터 도입된 규약이 __vectorcall이다. __vectorcall은 XMM, YMM 등 레지스터를 적극 활용하여 부동소수점 및 벡터 인자들을 레지스터에 우선적으로 전달하고, 레지스터 슬롯이 부족한 경우에만 나머지 인자들을 스택에 배치한다. 이 구조 덕분에 특히 수치 계산, 그래픽 처리, 물리 시뮬레이션, 신호처리 등 고성능 연산이 많은 영역에서 매우 큰 성능 개선을 기대할 수 있었다. 이 규약은 __fastcall의 단점을 보완하면서도, SIMD 중심의 현대 CPU 구조에 맞춘 고성능 연산 최적화 모델로 이해할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4021&quot; data-origin-height=&quot;1638&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oxG3c/btsPmzTy65y/kjeuzGuHY6BC2mbaEcbwS0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oxG3c/btsPmzTy65y/kjeuzGuHY6BC2mbaEcbwS0/img.jpg&quot; data-alt=&quot;[이미지36] Common Calling Convention&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oxG3c/btsPmzTy65y/kjeuzGuHY6BC2mbaEcbwS0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoxG3c%2FbtsPmzTy65y%2FkjeuzGuHY6BC2mbaEcbwS0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4021&quot; height=&quot;1638&quot; data-origin-width=&quot;4021&quot; data-origin-height=&quot;1638&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지36] Common Calling Convention&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;__stdcall, __cdecl, __fastcal, __vectorcall 성능 비교는 &lt;a href=&quot;https://kj0on.tistory.com/52&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://kj0on.tistory.com/52&lt;/a&gt;&amp;nbsp;참고&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;7. Caller-saved &amp;amp; Callee-saved&lt;/h2&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 27.3256%;&quot;&gt;용어&lt;/td&gt;
&lt;td style=&quot;width: 72.6744%;&quot;&gt;의미&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 27.3256%;&quot;&gt;Caller-saved Register&lt;/td&gt;
&lt;td style=&quot;width: 72.6744%;&quot;&gt;Caller(호출자)가 함수 호출 전 값을 보존해야 하는 레지스터. Callee(피호출자)는 해당 레지스터를 자유롭게 덮어써도 된다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 27.3256%;&quot;&gt;Callee-saved Register&lt;/td&gt;
&lt;td style=&quot;width: 72.6744%;&quot;&gt;Callee(&lt;span style=&quot;background-color: #f9f9f9; color: #333333; text-align: start;&quot;&gt;피호출자&lt;/span&gt;)가 함수 종료 시 값을 원래대로 복원해야 하는 레지스터. Caller(호출자)는 해당 레지스터를 자유롭게 덮어써도 된다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;caller saved(o).png&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;349&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzbazS/btsPregrjCb/bY28b7PhqiHafoeDcE8EaK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzbazS/btsPregrjCb/bY28b7PhqiHafoeDcE8EaK/img.png&quot; data-alt=&quot;[이미지74] Caller Saved&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzbazS/btsPregrjCb/bY28b7PhqiHafoeDcE8EaK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbzbazS%2FbtsPregrjCb%2FbY28b7PhqiHafoeDcE8EaK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;700&quot; height=&quot;349&quot; data-filename=&quot;caller saved(o).png&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;349&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지74] Caller Saved&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Caller-saved Register는 호출 규약에서 호출자 보존으로 지정된 범주로, 호출자가 함수 호출 전 해당 레지스터의 값을 스택이나 메모리 등에 저장하고 호출 후 복원할 의무를 진다. 따라서 피호출자는 이 레지스터들을 자유롭게 사용, 변경할 수 있으며, 호출자는 필요 데이터가 손상되지 않도록 사전에 보존 작업을 수행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;callee saved(O).png&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;535&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dNNBln/btsPrqHH43T/SBlRHVTNZTEVcdZcUikM1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dNNBln/btsPrqHH43T/SBlRHVTNZTEVcdZcUikM1k/img.png&quot; data-alt=&quot;[이미지75] Callee Saved&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dNNBln/btsPrqHH43T/SBlRHVTNZTEVcdZcUikM1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdNNBln%2FbtsPrqHH43T%2FSBlRHVTNZTEVcdZcUikM1k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;700&quot; height=&quot;535&quot; data-filename=&quot;callee saved(O).png&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;535&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지75] Callee Saved&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Callee-saved 레지스터는 피호출자 보존으로 지정된 범주로, 피호출 함수가 진입 시 레지스터 값을 저장하고 반환 직전에 복원해야 할 책임을 진다. 이 덕분에 호출자는 해당 레지스터들의 값이 함수 호출 전후로 유지된다는 가정하에 코드를 작성할 수 있으며, 깊은 호출 체계에서도 상위 컨텍스트가 안정적으로 유지된다.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;8. 참고 문헌&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;span style=&quot;color: #333333;&quot;&gt;[1] x86 calling conventions,&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/X86_calling_conventions&quot; target=&quot;_self&quot;&gt;&lt;span&gt;https://en.wikipedia.org/wiki/X86_calling_conventions&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;[2] Tutorial 1: The Basics, &lt;a href=&quot;https://www.plantation-productions.com/Webster/Win32Asm/IczelionTuts/tut1.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;https://www.plantation-productions.com/Webster/Win32Asm/IczelionTuts/tut1.html&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;[3] Operating&amp;nbsp;systems&amp;nbsp;C&amp;nbsp;function&amp;nbsp;call&amp;nbsp;conventions&amp;nbsp;and&amp;nbsp;stack, &lt;a href=&quot;https://piazza.com/class_profile/get_resource/il71xfllx3l16f/ilc7248vusx5h7&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://piazza.com/class_profile/get_resource/il71xfllx3l16f/ilc7248vusx5h7&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[4] What registers am I to push and pop when calling a function?, &lt;a href=&quot;https://stackoverflow.com/questions/22715001/what-registers-am-i-to-push-and-pop-when-calling-a-function&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://stackoverflow.com/questions/22715001/what-registers-am-i-to-push-and-pop-when-calling-a-function&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Reversing/Definition</category>
      <category>32bit</category>
      <category>Calling Convention</category>
      <category>__cdecl</category>
      <category>__fastcall</category>
      <category>__stdcall</category>
      <category>__vectorcall</category>
      <category>함수 호출 규약</category>
      <author>kj0on</author>
      <guid isPermaLink="true">https://kj0on.tistory.com/42</guid>
      <comments>https://kj0on.tistory.com/42#entry42comment</comments>
      <pubDate>Mon, 14 Jul 2025 17:43:42 +0900</pubDate>
    </item>
    <item>
      <title>[Definition] 32비트 스택 프레임 (32bit Stack Frame)</title>
      <link>https://kj0on.tistory.com/41</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;0. x32 ABI&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;x32 ABI는&lt;span&gt; &lt;a href=&quot;https://kj0on.tistory.com/46&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://kj0on.tistory.com/46&lt;/a&gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;참고&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 정의&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;스택 프레임(Stack Frame)은 함수가 호출될 때 스택에 형성되는 하나의 논리적 메모리 블록으로, 해당 함수 실행에 필요한 정보를 일시적으로 보관해 주는 단위이다.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 함수 프레임 (Function Frame)&lt;/h2&gt;
&lt;pre class=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

int fun3(void) {
	return 3;
}

int fun2(void) {
	fun3();
	return 2;
}

int fun1(void) {
	fun2();
	return 1;
}

int main(void) {
	printf(&quot;Hello World!\n&quot;); // Hello World!
	fun1();
	return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4512&quot; data-origin-height=&quot;2049&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xXF7j/btsPgVnQNRX/i7CPWz4T4pqMOEQLPQWUB0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xXF7j/btsPgVnQNRX/i7CPWz4T4pqMOEQLPQWUB0/img.jpg&quot; data-alt=&quot;[이미지1] 실행 흐름&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xXF7j/btsPgVnQNRX/i7CPWz4T4pqMOEQLPQWUB0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxXF7j%2FbtsPgVnQNRX%2Fi7CPWz4T4pqMOEQLPQWUB0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4512&quot; height=&quot;2049&quot; data-origin-width=&quot;4512&quot; data-origin-height=&quot;2049&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지1] 실행 흐름&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 이미지는 main&amp;rarr;printf&amp;rarr;fun1&amp;rarr;fun2&amp;rarr;fun3로 깊어졌다가, fun3&amp;rarr;fun2&amp;rarr;fun1&amp;rarr;main 으로 거꾸로 되돌아오는 함수의 호출 및 복귀 과정이다. 서로 다른 함수가 연쇄적으로 호출되는데 어떻게 꼬이지 않고 CPU는 다음에 돌아올 주소를 기억할까? 이 질문의 답을 확인하려면 같은 코드를 어셈블리언어로 들여다봐야 한다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3490&quot; data-origin-height=&quot;3386&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4FVxb/btsPfvKMqdb/0Cqp5bZWU8EowDsG4Fa231/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4FVxb/btsPfvKMqdb/0Cqp5bZWU8EowDsG4Fa231/img.jpg&quot; data-alt=&quot;[이미지2] 디버깅 (/Od, x86, Debug, /JMC-, /DYNAMICBASE:NO, /NXCOMPAT:NO, /GS-, __stdcall)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4FVxb/btsPfvKMqdb/0Cqp5bZWU8EowDsG4Fa231/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4FVxb%2FbtsPfvKMqdb%2F0Cqp5bZWU8EowDsG4Fa231%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3490&quot; height=&quot;3386&quot; data-origin-width=&quot;3490&quot; data-origin-height=&quot;3386&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지2] 디버깅 (/Od, x86, Debug, /JMC-, /DYNAMICBASE:NO, /NXCOMPAT:NO, /GS-, __stdcall)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어셈블리 단으로 내려가 보면 모든 함수에서 똑같은 패턴이 반복되는 것을 확인할 수 있다. 함수는 push ebp &amp;rarr; mov ebp, esp &amp;rarr; sub esp, &amp;lt;n&amp;gt;로 시작하며 mov esp, ebp &amp;rarr; pop ebp &amp;rarr; ret &amp;lt;n&amp;gt;으로 마무리한다. 이 기본 골격은 거의 모든 함수가 공유한다. 수십 개의 함수가 붙어 있어도 틀을 복사해 놓은 것처럼 동일한 코드 조각이 늘어선다. 한가지 유의할 점은 C언어 코드가 같아서 동일하게 나타나는 부분과 callee saved registers 부분(push ebx &amp;rarr; push esi &amp;rarr; push edi, pop ebx &amp;rarr; pop esi &amp;rarr; pop edi)은 제외했다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3185&quot; data-origin-height=&quot;2518&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cq0evL/btsPfiyaKoa/19c0dK0fsxShp8uCOM56pK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cq0evL/btsPfiyaKoa/19c0dK0fsxShp8uCOM56pK/img.jpg&quot; data-alt=&quot;[이미지3] 실행 흐름&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cq0evL/btsPfiyaKoa/19c0dK0fsxShp8uCOM56pK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcq0evL%2FbtsPfiyaKoa%2F19c0dK0fsxShp8uCOM56pK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3185&quot; height=&quot;2518&quot; data-origin-width=&quot;3185&quot; data-origin-height=&quot;2518&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지3] 실행 흐름&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수의 시작에 붙는 패턴은 프롤로그(prologue), 끝 부분에 붙는 패턴은 에필로그(epilogue)로 구분할 수 있으며, 직접 작성한 코드의 로직은 두 패턴 사이의 바디(body)에 위치하게 된다. 이러한 공통된 틀은 컴파일 단계에서 컴파일러가 자동으로 삽입한다. 덕분에 모든 함수가 일관된 스택 프레임을 유지할 수 있게 되며 중첩 호출 상황에서도 데이터와 복귀 주소가 안전하게 보호된다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 127px;&quot; border=&quot;1&quot; data-ke-style=&quot;style12&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px; text-align: justify;&quot;&gt;함수&amp;nbsp;프레임&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px; text-align: justify;&quot;&gt;어셈블리언어&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 17px; text-align: justify;&quot;&gt;의미&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 53px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 53px; text-align: justify;&quot;&gt;프롤로그 (prologue)&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 53px; text-align: justify;&quot;&gt;push ebp&lt;br /&gt;mov ebp, esp&lt;br /&gt;sub esp, &amp;lt;n&amp;gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 53px; text-align: justify;&quot;&gt;이전 EBP를 저장하고 EBP를 기준점으로 설정한 뒤, n 바이트를 예약해 새 스택 프레임을 구축&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px; text-align: justify;&quot;&gt;바디 (body)&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px; text-align: justify;&quot;&gt;ex)&lt;br /&gt;&lt;br /&gt;mov&amp;nbsp;eax,&amp;nbsp;[ebp+8] &lt;br /&gt;add&amp;nbsp;eax,&amp;nbsp;1 &lt;br /&gt;mov&amp;nbsp;[ebp‑4],&amp;nbsp;eax &lt;br /&gt;call&amp;nbsp;printf&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px; text-align: justify;&quot;&gt;연산, 조건 분기, 함수 호출 등 직접 작성한 코드가 위치. 프롤로그에서 만든 스택 프레임 안에서 로컬 변수와 인자를 사용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 35px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 35px; text-align: justify;&quot;&gt;에필로그 (epilogue)&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 35px; text-align: justify;&quot;&gt;(leave)&lt;br /&gt;mov esp, ebp&lt;br /&gt;pop ebp&lt;br /&gt;&lt;br /&gt;(ret &amp;lt;n&amp;gt;)&lt;br /&gt;pop eip&lt;br /&gt;add esp, &amp;lt;n&amp;gt;&lt;br /&gt;jmp eip&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 35px; text-align: justify;&quot;&gt;레지스터,&amp;nbsp;스택&amp;nbsp;포인터를&amp;nbsp;원래&amp;nbsp;상태로&amp;nbsp;돌려&amp;nbsp;프레임을&amp;nbsp;제거하고,&amp;nbsp;호출자에게&amp;nbsp;제어를&amp;nbsp;반환&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 표는 함수 프레임의 구성과 각 구간에서 실행되는 어셈블리 코드, 그리고 역할을 간단히 정리한 것이다. 다음으로 이 함수 프레임 안에서 실제로 스택 프레임이 어떻게 만들어지는지(프롤로그/바디/에필로그가 구체적으로 무엇을 하는지)를 살펴본다. 함수 프레임에서는 실제 동작보다 구조적인 관점에서 접근하는 것이 좋으며, 프롤로그, 바디, 에필로그가 어디에 위치하는지를 중심으로 파악하는 것이 효과적이다.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 스택 프레임 (Stack Frame)&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;br /&gt;3-1. 코드&amp;nbsp;및&amp;nbsp;스택&amp;nbsp;구조&amp;nbsp;개요&lt;/h3&gt;
&lt;pre class=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

int to_seconds(int hour, int minute, int second) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int result_hour = 0;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int result_minute = 0;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int result_second = 0;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int result_total = 0;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result_hour = hour * 3600;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result_minute = minute * 60;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result_second = second;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;result_total = result_hour + result_minute + result_second;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return result_total;

}

int main() {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int h = 1;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int m = 30;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int s = 15;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int total = to_seconds(h, m, s);

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;printf(&quot;Total seconds: %d\n&quot;, total);

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 코드는 시, 분, 초를 각각 초 단위로 환산한 뒤 합산하는 단순한 흐름으로 되어 있다. 해당 코드를 토대로 스택 프레임이 어떻게 생성되고 소멸하는지를 단계별로 살펴본다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;stack.jpg&quot; data-origin-width=&quot;3482&quot; data-origin-height=&quot;1097&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqhXbG/btsPCLkp8kK/oqjgWChsMidTo7KSebQsjk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqhXbG/btsPCLkp8kK/oqjgWChsMidTo7KSebQsjk/img.jpg&quot; data-alt=&quot;[이미지4] 스택&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqhXbG/btsPCLkp8kK/oqjgWChsMidTo7KSebQsjk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqhXbG%2FbtsPCLkp8kK%2FoqjgWChsMidTo7KSebQsjk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3482&quot; height=&quot;1097&quot; data-filename=&quot;stack.jpg&quot; data-origin-width=&quot;3482&quot; data-origin-height=&quot;1097&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지4] 스택&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;x86 환경을 고려해 스택은 Full Descending 방식으로 동작하므로, ESP 레지스터는 데이터를 저장할 때마다 더 낮은 주소로 이동한 뒤 해당 위치에 값을 기록한다. 낮은주소와 높은 주소의 위치는 위와 같으며 주소의 간격은 4byte다. 데이터를 기록할 때는 가독성을 고려해 빅엔디언 방식을 적용한다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2676&quot; data-origin-height=&quot;1407&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/chN1Rx/btsPf3ADQ24/SQasxKwUm7gH4FwiykdKyk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/chN1Rx/btsPf3ADQ24/SQasxKwUm7gH4FwiykdKyk/img.jpg&quot; data-alt=&quot;[이미지5] function call stackframe&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/chN1Rx/btsPf3ADQ24/SQasxKwUm7gH4FwiykdKyk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FchN1Rx%2FbtsPf3ADQ24%2FSQasxKwUm7gH4FwiykdKyk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2676&quot; height=&quot;1407&quot; data-origin-width=&quot;2676&quot; data-origin-height=&quot;1407&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지5] function call stackframe&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본격적으로 스택을 살펴보기에 앞서 알아두면 좋은것은 스택프레임은 함수를 호출할 때 마다 생성된다는 것이다. 한가지 유의할 점은 함수당 하나의 스택프레임을 가진다는 것이 아니라 &quot;호출할 때 마다&quot;라는 점이다.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-2. 스택 프레임 분석&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4468&quot; data-origin-height=&quot;2786&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/37u8H/btsPhvbmd5N/qCkrFKKZ3E99a65HCd4k41/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/37u8H/btsPhvbmd5N/qCkrFKKZ3E99a65HCd4k41/img.jpg&quot; data-alt=&quot;[이미지6] main&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/37u8H/btsPhvbmd5N/qCkrFKKZ3E99a65HCd4k41/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F37u8H%2FbtsPhvbmd5N%2FqCkrFKKZ3E99a65HCd4k41%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4468&quot; height=&quot;2786&quot; data-origin-width=&quot;4468&quot; data-origin-height=&quot;2786&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지6] main&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;main 함수가 시작하는 지점을 기준으로, 함수 호출에 따라 스택 프레임이 어떻게 구성되고 값이 어떻게 저장되는지를 단계적으로 살펴본다. 초기 상태는 위 이미지와 같다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4468&quot; data-origin-height=&quot;2771&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XqpXZ/btsPgdv3qir/aVHotq06zg5jct6sRj5nkK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XqpXZ/btsPgdv3qir/aVHotq06zg5jct6sRj5nkK/img.jpg&quot; data-alt=&quot;[이미지7] main prologue&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XqpXZ/btsPgdv3qir/aVHotq06zg5jct6sRj5nkK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXqpXZ%2FbtsPgdv3qir%2FaVHotq06zg5jct6sRj5nkK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4468&quot; height=&quot;2771&quot; data-origin-width=&quot;4468&quot; data-origin-height=&quot;2771&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지7] main prologue&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;push ebp 명령은 함수의 프롤로그(prologue)에서 가장 먼저 실행되는 명령어로, 현재 EBP 레지스터의 값을 스택에 저장한다. 이 값은 함수 실행이 끝난 뒤 에필로그(epilogue)에서 원래의 EBP 값을 복구하는 데 사용된다. main도 다른 함수들과 마찬가지로 호출되는 하나의 함수다. 따라서 push ebp를 통해 저장된 값 0x0019FF08은 main 함수가 호출되기 전에 사용되던 EBP 값, 즉 main을 호출한 함수의 EBP(스택 프레임 기준 주소)를 의미한다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4468&quot; data-origin-height=&quot;2771&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkTq5L/btsPgjwbVCl/zMqRrL5zSiFeyZcZSTqSO0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkTq5L/btsPgjwbVCl/zMqRrL5zSiFeyZcZSTqSO0/img.jpg&quot; data-alt=&quot;[이미지8] main prologue&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkTq5L/btsPgjwbVCl/zMqRrL5zSiFeyZcZSTqSO0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkTq5L%2FbtsPgjwbVCl%2FzMqRrL5zSiFeyZcZSTqSO0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4468&quot; height=&quot;2771&quot; data-origin-width=&quot;4468&quot; data-origin-height=&quot;2771&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지8] main prologue&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;mov ebp, esp는 현재 ESP 값을 EBP에 복사하는 명령어로, EBP를 ESP가 가리키는 값으로 변경한다. 결과적으로 ESP와 EBP가 가리키는 지점이 같아진다. 이 명령은 함수의 프롤로그에서 push ebp 다음에 실행되며, 이제부터 해당 함수는 EBP를 기준으로 지역 변수와 매개변수에 안정적으로 접근할 수 있게 된다. 쉽게 말해 main 함수 스택 프레임의 시작지점을 의미한다. 즉, mov ebp, esp는 기준점을 설정하는 동작이다. SFP는 Saved Frame Pointer의 약자로, 이전(호출한 함수)의 EBP를 의미한다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4468&quot; data-origin-height=&quot;2771&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AWhlo/btsPfwpwYJG/yKLSvud769qkJpYy1rO4KK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AWhlo/btsPfwpwYJG/yKLSvud769qkJpYy1rO4KK/img.jpg&quot; data-alt=&quot;[이미지9] main prologue&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AWhlo/btsPfwpwYJG/yKLSvud769qkJpYy1rO4KK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAWhlo%2FbtsPfwpwYJG%2FyKLSvud769qkJpYy1rO4KK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4468&quot; height=&quot;2771&quot; data-origin-width=&quot;4468&quot; data-origin-height=&quot;2771&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지9] main prologue&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sub esp, &amp;lt;n&amp;gt; 명령은 mov ebp, esp 다음에 사용되어 스택에 &amp;lt;n&amp;gt; 바이트만큼의 공간을 확보하는 역할을 하며, 이 공간은 주로 지역 변수나 임시 데이터를 저장하기 위한 용도로 사용된다. 또한 sub esp, &amp;lt;n&amp;gt;은 단순 &quot;공간 확보&quot; 이상의 의미를 가진다. 해당 명령어를 통해 ESP가 가리키고 있는 위치는 현재 함수가 사용하는 지역전용 작업 구역을 분리해 두는 경계라고 할 수 있다. 만약 이 경계가 없으면 함수 내부에서 call, push, saved register, 보안 검사의 동작에 따라 로컬 데이터를 덮어 버릴 수 있다. 그렇기 때문에 이 명령어는 &quot;지역 변수를 사용하기 위한 공간 확보&quot; 그 이상의 의미인 &quot;로컬 데이터 보호, 호출 규약 준수, 정렬, 보안 요구 사항을 한꺼번에 충족시키기 위한 함수 전용의 안전지대&quot; 라고 할 수 있다. 명령어에서 &amp;lt;n&amp;gt;의 값은 함수 내 지역 변수의 크기, 스택 정렬 규칙, 임시 저장 공간 확보 여부 등에 따라 달라질 수 있다. 이 값은 컴파일러가 함수의 특성에 맞게 유동적으로 결정한다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4468&quot; data-origin-height=&quot;2771&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RdH2x/btsPg5RuUQ7/Isym7JjETC6Z4hlktj4Nsk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RdH2x/btsPg5RuUQ7/Isym7JjETC6Z4hlktj4Nsk/img.jpg&quot; data-alt=&quot;[이미지10] main prologue&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RdH2x/btsPg5RuUQ7/Isym7JjETC6Z4hlktj4Nsk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRdH2x%2FbtsPg5RuUQ7%2FIsym7JjETC6Z4hlktj4Nsk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4468&quot; height=&quot;2771&quot; data-origin-width=&quot;4468&quot; data-origin-height=&quot;2771&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지10] main prologue&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;push  ebx, push esi, push edi는 함수 호출 규약에서 지정된 레지스터의 현재 값을 스택에 저장하는 명령으로, 함수가 이 레지스터들을 수정할 가능성이 있을 때 프롤로그에 포함된다. 이렇게 저장해 두면 함수 내부동작 중 레지스터를 임시 변수처럼 쓰면서 값이 변경돼도 원래 값을 에필로그에서 복원할 수 있다. 레지스터를 보존하기 위한 명령어로, 고정적으로 프롤로그에 나타나는 패턴은 아니다. 해당 코드에서는 &lt;span style=&quot;color: #333333;&quot;&gt;최적화 옵션을 비활성화 했기 때문에 프롤로그에 포함되었다. 스택 프레임의 구조나 동작 원리를 이해하는 데 직접적인 영향을 주는 요소는 아니므로, 해당 글에서는 중요하게 보지 않아도 된다.&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4468&quot; data-origin-height=&quot;2771&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uN6Xx/btsPg9sQST6/fkaugoUbPI9EYhbwmJUR81/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uN6Xx/btsPg9sQST6/fkaugoUbPI9EYhbwmJUR81/img.jpg&quot; data-alt=&quot;[이미지11] main body&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uN6Xx/btsPg9sQST6/fkaugoUbPI9EYhbwmJUR81/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuN6Xx%2FbtsPg9sQST6%2FfkaugoUbPI9EYhbwmJUR81%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4468&quot; height=&quot;2771&quot; data-origin-width=&quot;4468&quot; data-origin-height=&quot;2771&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지11] main body&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에필로그 이후에는 사용자가 작성한 main 함수의 실제 코드, 즉 바디(body) 부분이 이어진다. 이 구간에서는 시간(h), 분(m), 초(s)와 같은 변수를 선언하고 초기화하는 동작이 수행된다. 앞서 mov ebp, esp 명령으로 기준점을 설정해두었기 때문에, 이후 지역 변수들은 EBP를 기준으로 안정적으로 접근할 수 있다. 코드에는 자세하게 나타나 있지 않지만 dword ptr [ebp - &amp;lt;n&amp;gt;]으로 각 지역변수에 접근해 값을 저장한다. 시간(h)는 [ebp - 0x4]의 위치에, 분(m)은 [&lt;span style=&quot;color: #333333;&quot;&gt;ebp - 0x8]의 위치에, 초(s)는&lt;/span&gt; [&lt;span style=&quot;color: #333333;&quot;&gt;ebp - 0xC]의 위치에 저장된다.&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4468&quot; data-origin-height=&quot;2771&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/81N3x/btsPgd3Vqpp/Gad1CSv8ikV0qzB43t82G1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/81N3x/btsPgd3Vqpp/Gad1CSv8ikV0qzB43t82G1/img.jpg&quot; data-alt=&quot;[이미지12] main body&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/81N3x/btsPgd3Vqpp/Gad1CSv8ikV0qzB43t82G1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F81N3x%2FbtsPgd3Vqpp%2FGad1CSv8ikV0qzB43t82G1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4468&quot; height=&quot;2771&quot; data-origin-width=&quot;4468&quot; data-origin-height=&quot;2771&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지12] main body&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;to_seconds 함수를 호출하기 전, push를 통해 전달할 인자를 스택에 저장하는 동작을 하고 있다. 컴파일러는 인자 값의 위치, 재사용 여부, 레지스터 여유, 호출 규약을 종합해서 인자를 어떻게 전달할 지를 결정한다. 인자값을 어떻게 어떤 순서로 전달하는지는 함수 호출규약에서 다루기 때문에 해당 글에서는 중요하게 보지 않아도 된다. push하는 부분에서 어떤 값을 스택에 쌓는지를 확인해 보면 이전에 저장한 지역변수의 위치에서 &lt;span style=&quot;color: #333333;&quot;&gt;시간(h), 분(m), 초(s) 값을 참조해 스택에 집어넣는것을 확인할 수 있다. &lt;/span&gt;앞서 sub esp, &amp;lt;n&amp;gt;으로 지역 변수 영역과 호출 인자 영역 사이의 경계를 확보해 두었기 때문에, 인자들을 push해도 로컬 데이터와 겹칠 위험 없이 안전하게 저장할 수 있다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4468&quot; data-origin-height=&quot;2771&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pTYEA/btsPfHEh1GO/8T1pXkE5KwKzeDOQFl3cRK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pTYEA/btsPfHEh1GO/8T1pXkE5KwKzeDOQFl3cRK/img.jpg&quot; data-alt=&quot;[이미지13] main body&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pTYEA/btsPfHEh1GO/8T1pXkE5KwKzeDOQFl3cRK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpTYEA%2FbtsPfHEh1GO%2F8T1pXkE5KwKzeDOQFl3cRK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4468&quot; height=&quot;2771&quot; data-origin-width=&quot;4468&quot; data-origin-height=&quot;2771&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지13] main body&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수에 전달할 인자를 모두 스택에 push 한 뒤, to_seconds 함수를 호출하는 동작으로 이어진다. call 명령어에는 중요한 동작이 포함되어 있는데, 현재 EIP값(다음에 실행될 명령의 주소 0x41163F)을 스택에 push한다는 점이다. 이 값은 함수 실행이 끝난 후 에필로그 단계에서 ret 명령을 통해 복원되며, 호출 지점으로 정확히 되돌아가기 위해 사용된다. EIP와 SFP는 스택 프레임에서 매우 중요한 요소로, 함수 호출 이전 상태를 기억하는 일종의 세이브 포인트 역할을 한다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4467&quot; data-origin-height=&quot;2771&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRRRA2/btsPfAyNvcB/zu5giAA2C4X4t8lHlsfVHk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRRRA2/btsPfAyNvcB/zu5giAA2C4X4t8lHlsfVHk/img.jpg&quot; data-alt=&quot;[이미지14] to_seconds prologue&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRRRA2/btsPfAyNvcB/zu5giAA2C4X4t8lHlsfVHk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRRRA2%2FbtsPfAyNvcB%2Fzu5giAA2C4X4t8lHlsfVHk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4467&quot; height=&quot;2771&quot; data-origin-width=&quot;4467&quot; data-origin-height=&quot;2771&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지14] to_seconds prologue&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;call 명령어는 내부적으로 두 가지 동작으로 구성되어 있다. 먼저 현재 EIP 값을 스택에 push하고, 이어서 호출 대상 함수의 주소로 jmp한다. 즉, call to_seconds는 실제로는 push eip &amp;rarr; jmp to_seconds 형태로 동작한다. 따라서 EIP는 &lt;span style=&quot;color: #333333;&quot;&gt;to_seconds의 시작 지점에 대한 값으로 변경되며 이후 &lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;to_seconds 함수 코드가 실행된다. &lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;to_seconds에서 처음 실행되는 명령어를 보면 다시 에필로그가 나타난다는 것을 확인할 수 있다. main의 시작지점과 동일하게 push ebp를 통해 현재 EBP를 스택에 저장한다. 이 값은 to_seconds 함수가 호출되기 전에 사용되던 EBP 값, 즉 main 함수의 EBP(스택 프레임 기준 주소 0x19FEE8)를 의미한다.&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4467&quot; data-origin-height=&quot;2771&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b9vtEu/btsPgd3VwPU/b35qgdHPiGzg7R8BKm5yKK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b9vtEu/btsPgd3VwPU/b35qgdHPiGzg7R8BKm5yKK/img.jpg&quot; data-alt=&quot;[이미지15] to_seconds prologue&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b9vtEu/btsPgd3VwPU/b35qgdHPiGzg7R8BKm5yKK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb9vtEu%2FbtsPgd3VwPU%2Fb35qgdHPiGzg7R8BKm5yKK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4467&quot; height=&quot;2771&quot; data-origin-width=&quot;4467&quot; data-origin-height=&quot;2771&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지15] to_seconds prologue&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;mov ebp, esp를 통해 기준점을 main 함수에서&amp;nbsp; to_seconds 함수로 설정한다. 해당 EBP를 기준으로 &lt;span style=&quot;color: #333333;&quot;&gt;to_seconds 내부의&amp;nbsp;&lt;/span&gt;지역 변수와 매개변수에 안정적으로 접근할 수 있게 된다. 컴파일러는 자신의 스택 프레임 안에서만 EBP와 상대 오프셋을 사용해 데이터를 다루도록 설계되어 있기 때문에, main의 지역 변수 주소 범위는 to_seconds 함수에서 다루지 않게 된다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;왜 함수 호출마다 EBP를 갱신하는가? (GPT)&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 배경&amp;nbsp;― &amp;ldquo;고정 EBP 모델&amp;rdquo;이란?&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;전제&lt;/b&gt; : 스레드마다 스택의 시작 지점을 StartEBP로 고정하고,&lt;br /&gt;모든 함수가 &lt;b&gt;EBP를 옮기지 않은 채&lt;/b&gt; 매개변수&amp;middot;지역변수 주소를&lt;br /&gt;StartEBP&amp;nbsp;&amp;ndash; (depth &amp;times; frameSize)&amp;nbsp;&amp;plusmn; 상수&amp;nbsp;오프셋 방식으로 계산한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;목표&lt;/b&gt; : 함수 호출 시 mov ebp, esp를 생략하고도 재귀&amp;middot;중첩 호출이 가능하도록 하려는 가정.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 실행 단계에서 나타나는 문제점&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;① 주소 계산 부담&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&amp;bull; 스택을 참조할 때마다 &lt;b&gt;현재 호출 깊이(depth)&lt;/b&gt; 를 구해 레지스터에 로드&amp;bull; depth&amp;nbsp;&amp;times;&amp;nbsp;frameSize 산술 계산 후 StartEBP에 더&amp;middot;빼기&lt;/td&gt;
&lt;td&gt;&amp;rarr; &lt;b&gt;명령어 수&amp;middot;ALU 사용량&lt;/b&gt; 증가 &amp;rarr; 성능 저하, 코드 부피 증가&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;② depth 값의 동적 특성&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;재귀&amp;middot;분기&amp;middot;루프 때문에 호출 깊이는 &lt;b&gt;컴파일 시점에 예측 불가&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&amp;rarr; 실행 중 계산 또는 최악‑깊이 가정이 필요&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;③ 컴파일 타임 하드코딩의 비현실성&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&amp;ldquo;모든 깊이별 오프셋&amp;rdquo;을 미리 박으려면&amp;bull; 최대재귀&amp;nbsp;N &amp;times; frameSize 만큼 스택 예약&amp;bull; 함수마다 N 단계용 코드&amp;middot;테이블 중복&lt;/td&gt;
&lt;td&gt;&amp;rarr; 스택 공간과 코드 크기 &lt;b&gt;폭발적 낭비&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;④ 멀티스레드&amp;middot;레지스터 압박&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;스레드별 depth&amp;nbsp;변수와 StartEBP 유지 &amp;rarr; 레지스터 고정 또는 메모리 전역 접근 필요 &amp;rarr; 스레드 동기화 비용&lt;/td&gt;
&lt;td&gt;&amp;rarr; 동시성에서 &lt;b&gt;성능 손실&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;⑤ 디버깅&amp;middot;언와인드&amp;middot;보안 기능 붕괴&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&amp;bull; Saved‑EBP 체인 부재 &amp;rarr; 전통적 스택 추적&amp;middot;예외 언와인드 불가&amp;bull; 스택 쿠키, CET Shadow Stack 등 &lt;b&gt;프레임 단위&lt;/b&gt; 보안 장치 재설계 필요&lt;/td&gt;
&lt;td&gt;&amp;rarr; 툴체인&amp;middot;OS &lt;b&gt;대규모 수정&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 성능&amp;middot;메모리&amp;middot;유지보수 영향&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;주소 계산&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;[ebp&amp;plusmn;disp] &amp;rarr; 하드웨어가 1 사이클 처리&lt;/td&gt;
&lt;td&gt;mov/imul/lea 등 여러 명령 필요&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;명령어 크기&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;2&amp;ndash;3 바이트(짧은 disp)&lt;/td&gt;
&lt;td&gt;8&amp;ndash;12 바이트 이상&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;스택 공간&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;호출 깊이에 맞춰 &lt;b&gt;필요한 만큼만 즉시 사용&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;최악‑깊이 가정해 &lt;b&gt;미리 예약&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;디버깅&amp;middot;예외 처리&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Saved‑EBP 체인으로 즉시 가능&lt;/td&gt;
&lt;td&gt;별도 CFI/스택맵 구축 필요&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;보안 장치&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;스택 쿠키&amp;middot;Shadow Stack 그대로 사용&lt;/td&gt;
&lt;td&gt;커스텀 보안 메커니즘 재작성&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;레지스터 사용&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;EBP 고정, 나머지 자유&lt;/td&gt;
&lt;td&gt;depth&amp;middot;StartEBP 보관용 레지스터 고정&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 결론 ― &lt;b&gt;EBP를 매 호출마다 이동하는 근본적 이유&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;가장 짧고 빠른 주소 계산&lt;/b&gt;&amp;nbsp;&amp;ndash; [EBP &amp;plusmn; disp] 변위는 하드웨어가 무료로 처리한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;동적 호출 격리&lt;/b&gt;&amp;nbsp;&amp;ndash; 재귀&amp;middot;중첩&amp;middot;멀티스레드에서도 로컬 데이터가 절대 겹치지 않는다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;완전한 호환성&lt;/b&gt;&amp;nbsp;&amp;ndash; 기존 디버거, 예외 언와인더, 스택 가드, CET Shadow Stack과 그대로 연동된다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;메모리&amp;middot;코드 효율&lt;/b&gt;&amp;nbsp;&amp;ndash; 프레임마다 필요한 만큼만 스택을 쓰고, 함수 코드도 최소화된다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 &amp;ldquo;EBP 고정 + depth‑기반 오프셋&amp;rdquo; 모델은 &lt;b&gt;이론적 실행 가능성&lt;/b&gt;은 있으나&lt;br /&gt;성능 손해, 메모리 낭비, 툴체인&amp;middot;보안 재설계라는 대가가 너무 커 &lt;b&gt;실무에서는 채택되지 않으며&lt;/b&gt;,&lt;br /&gt;호출마다 EBP를 갱신하는 현행 스택‑프레임 방식이 &lt;b&gt;실용성&amp;middot;효율&amp;middot;안정성 면에서 모든 면에서 우수&lt;/b&gt;하다는 결론이 내려진다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4467&quot; data-origin-height=&quot;2771&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eqvk2v/btsPfJhRSWp/l9vXM7FoE6eBq5AnJ5MLN0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eqvk2v/btsPfJhRSWp/l9vXM7FoE6eBq5AnJ5MLN0/img.jpg&quot; data-alt=&quot;[이미지16] to_seconds prologue&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eqvk2v/btsPfJhRSWp/l9vXM7FoE6eBq5AnJ5MLN0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Feqvk2v%2FbtsPfJhRSWp%2Fl9vXM7FoE6eBq5AnJ5MLN0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4467&quot; height=&quot;2771&quot; data-origin-width=&quot;4467&quot; data-origin-height=&quot;2771&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지16] to_seconds prologue&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sub esp, &amp;lt;n&amp;gt;의 명령어로 to_seconds 함수 전용 안전지대의 경계를 설정한다. 이 명령어를 통해 함수 내부에서 지역 데이터를 안전하게 보호하면서 접근할 수 있게 된다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4467&quot; data-origin-height=&quot;2771&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwRAGe/btsPgAxJWvX/n0N6PA01kLngkbVI8KC4A0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwRAGe/btsPgAxJWvX/n0N6PA01kLngkbVI8KC4A0/img.jpg&quot; data-alt=&quot;[이미지17] to_seconds prologue&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwRAGe/btsPgAxJWvX/n0N6PA01kLngkbVI8KC4A0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwRAGe%2FbtsPgAxJWvX%2Fn0N6PA01kLngkbVI8KC4A0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4467&quot; height=&quot;2771&quot; data-origin-width=&quot;4467&quot; data-origin-height=&quot;2771&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지17] to_seconds prologue&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;레지스터를 보존하기 위한 명령어로, 원래 값을 에필로그에서 복원할 수 있다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4467&quot; data-origin-height=&quot;2771&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GLmK1/btsPgAR0JGb/ApqGkKaVussYjKc2IXUOxK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GLmK1/btsPgAR0JGb/ApqGkKaVussYjKc2IXUOxK/img.jpg&quot; data-alt=&quot;[이미지18] to_seconds body&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GLmK1/btsPgAR0JGb/ApqGkKaVussYjKc2IXUOxK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGLmK1%2FbtsPgAR0JGb%2FApqGkKaVussYjKc2IXUOxK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4467&quot; height=&quot;2771&quot; data-origin-width=&quot;4467&quot; data-origin-height=&quot;2771&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지18] to_seconds body&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 to_seconds의 코드가 존재하는 바디부분이다. main과 마찬가지로 앞서 mov ebp, esp를 통해 설정한 기준점 EBP를 통해 오프셋으로 지역변수에 접근한다. 각 변수를 선언하고, 값을 0으로 초기화 하는 동작을 수행한다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4467&quot; data-origin-height=&quot;2771&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bG1aO9/btsPgUiqeiS/Owb98gAe7I08XiPncKIyJK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bG1aO9/btsPgUiqeiS/Owb98gAe7I08XiPncKIyJK/img.jpg&quot; data-alt=&quot;[이미지19] to_seconds body&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bG1aO9/btsPgUiqeiS/Owb98gAe7I08XiPncKIyJK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbG1aO9%2FbtsPgUiqeiS%2FOwb98gAe7I08XiPncKIyJK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4467&quot; height=&quot;2771&quot; data-origin-width=&quot;4467&quot; data-origin-height=&quot;2771&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지19] to_seconds body&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 시간(h)을 초 단위로 환산하는 코드로, imul 명령을 통해 연산을 수행한 뒤 결과를 EAX 레지스터에 저장하고, 이를 [ebp - 0x4] 위치에 기록한다. 이 과정에서 필요한 시간(h) 값은 main 함수에서 push한 인자를 사용하며, 호출된 함수는 EBP를 기준으로 스택 상의 위치에 접근해 읽어온다. 이처럼 호출된 함수는 고정된 프레임 구조를 기반으로 인자에 접근하므로, 함수 실행 중에도 안정적으로 값을 참조할 수 있다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4467&quot; data-origin-height=&quot;2771&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lOzYR/btsPhkAWXft/f5k6KsuCcZdTarNiypY1o1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lOzYR/btsPhkAWXft/f5k6KsuCcZdTarNiypY1o1/img.jpg&quot; data-alt=&quot;[이미지20] to_seconds body&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lOzYR/btsPhkAWXft/f5k6KsuCcZdTarNiypY1o1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlOzYR%2FbtsPhkAWXft%2Ff5k6KsuCcZdTarNiypY1o1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4467&quot; height=&quot;2771&quot; data-origin-width=&quot;4467&quot; data-origin-height=&quot;2771&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지20] to_seconds body&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;분(m)을 초 단위로 환산하는 코드로 마찬가지로 EBP를 기준으로 스택 상의 위치에 접근해 읽어온다. 해당 연산 결과를 &lt;span style=&quot;color: #333333;&quot;&gt;[ebp - 0x8] 위치에 기록한다.&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4467&quot; data-origin-height=&quot;2771&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/miF0Z/btsPfZY2lO8/jr4pfyE5vkmvZnilkRIc3k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/miF0Z/btsPfZY2lO8/jr4pfyE5vkmvZnilkRIc3k/img.jpg&quot; data-alt=&quot;[이미지21] to_seconds body&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/miF0Z/btsPfZY2lO8/jr4pfyE5vkmvZnilkRIc3k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmiF0Z%2FbtsPfZY2lO8%2Fjr4pfyE5vkmvZnilkRIc3k%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4467&quot; height=&quot;2771&quot; data-origin-width=&quot;4467&quot; data-origin-height=&quot;2771&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지21] to_seconds body&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;초(s)를 읽어서 기록하는 코드로,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;EBP를 기준으로 스택 상의 위치에 접근해 읽어온다. 해당 값을&amp;nbsp;&lt;/span&gt;[ebp - 0xC] 위치에 기록한다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4467&quot; data-origin-height=&quot;2771&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Y7m36/btsPhujfs5V/TECbadlKoDlxGmrKgv6fXk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Y7m36/btsPhujfs5V/TECbadlKoDlxGmrKgv6fXk/img.jpg&quot; data-alt=&quot;[이미지22] to_seconds body&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Y7m36/btsPhujfs5V/TECbadlKoDlxGmrKgv6fXk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FY7m36%2FbtsPhujfs5V%2FTECbadlKoDlxGmrKgv6fXk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4467&quot; height=&quot;2771&quot; data-origin-width=&quot;4467&quot; data-origin-height=&quot;2771&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지22] to_seconds body&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞선 연산 결과를 모두 더해주는 코드로, 시간(h), 분(m), 초(s)를 모두 합산한 결과를 [ebp - 0x10] 위치에 기록한다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4467&quot; data-origin-height=&quot;2771&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FMtSt/btsPgBJXKGZ/5kc96LnBD8Kkov05FwV9H1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FMtSt/btsPgBJXKGZ/5kc96LnBD8Kkov05FwV9H1/img.jpg&quot; data-alt=&quot;[이미지23] to_seconds body&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FMtSt/btsPgBJXKGZ/5kc96LnBD8Kkov05FwV9H1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFMtSt%2FbtsPgBJXKGZ%2F5kc96LnBD8Kkov05FwV9H1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4467&quot; height=&quot;2771&quot; data-origin-width=&quot;4467&quot; data-origin-height=&quot;2771&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지23] to_seconds body&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;return을 통해 함수의 연산 결과 값이 호출자에게 전달 될 수 있도록 한다. 이는 주로 EAX 레지스터에 결과를 저장하는 방식으로 이루어진다. 중요하게 봐야 할 점은 return 구문 자체가 실제 어셈블리 수준에서는 mov eax, &amp;lt;n&amp;gt;와 같은 명령으로 변환된다는 것이다. 제어가 원래 위치로 복귀하는 동작은 에필로그 단계에서 수행된다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4467&quot; data-origin-height=&quot;2771&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WsFLF/btsPgfUU2s1/JxVYXKMNafmKYdTgf1qoo0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WsFLF/btsPgfUU2s1/JxVYXKMNafmKYdTgf1qoo0/img.jpg&quot; data-alt=&quot;[이미지24] to_seconds epilogue&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WsFLF/btsPgfUU2s1/JxVYXKMNafmKYdTgf1qoo0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWsFLF%2FbtsPgfUU2s1%2FJxVYXKMNafmKYdTgf1qoo0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4467&quot; height=&quot;2771&quot; data-origin-width=&quot;4467&quot; data-origin-height=&quot;2771&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지24] to_seconds epilogue&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;앞서 push해 두었던 레지스터를 &lt;/span&gt;복원하는 코드로, &lt;span style=&quot;color: #333333;&quot;&gt;고정적으로 에필로그에 나타나는 패턴은 아니다. 해당 코드에서는&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;최적화 옵션을 비활성화 했기 때문에 에필로그에 포함되었다.&amp;nbsp;스택 프레임의 구조나 동작 원리를 이해하는 데 직접적인 영향을 주는 요소는 아니므로, 해당 글에서는 중요하게 보지 않아도 된다.&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4467&quot; data-origin-height=&quot;2771&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0GQsi/btsPgtrVqcR/8xKuK8HM1glhWtiiDBurkk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0GQsi/btsPgtrVqcR/8xKuK8HM1glhWtiiDBurkk/img.jpg&quot; data-alt=&quot;[이미지25] to_seconds epilogue&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0GQsi/btsPgtrVqcR/8xKuK8HM1glhWtiiDBurkk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0GQsi%2FbtsPgtrVqcR%2F8xKuK8HM1glhWtiiDBurkk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4467&quot; height=&quot;2771&quot; data-origin-width=&quot;4467&quot; data-origin-height=&quot;2771&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지25] to_seconds epilogue&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;mov esp, ebp &lt;span style=&quot;color: #333333;&quot;&gt;명령은 함수의 에필로그(epilogue)에서 가장 먼저 실행되는 명령어로, EBP 값을 ESP에 복사하여 ESP를 EBP가 가리키는 값으로 변경한다. 결과적으로 함수 실행 중에 변경되었던 ESP가 EBP(&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;to_seconds 함수의 스택프레임 기준점&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;)으로 복원된다. 이는 sub esp, &amp;lt;n&amp;gt;을 통해 설정했던 경계를 해제하는 작업이며, 스택을 정리해서 확보했던 공간을 더 이상 사용하지 않겠다는 의미다. 이 과정은 단지 ESP 값을 되돌리는 것일 뿐, 스택에 저장되어 있던 실제 데이터를 삭제하거나 지우는 동작은 수행하지 않는다. 기존 값들은 메모리에 그대로 남아 있지만, 이후 다른 동작으로 인해 새로운 데이터가 덮어씌워진다. 따라서 ESP 값을 되돌린다는 것은 논리적으로 그 공간이 더 이상 유효하지 않은 상태가 된다는 것을 의미한다.&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4467&quot; data-origin-height=&quot;2771&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TvpXs/btsPftTSDvG/8Xji1koSKQwlxGSgpT1Nek/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TvpXs/btsPftTSDvG/8Xji1koSKQwlxGSgpT1Nek/img.jpg&quot; data-alt=&quot;[이미지26] to_seconds epilogue&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TvpXs/btsPftTSDvG/8Xji1koSKQwlxGSgpT1Nek/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTvpXs%2FbtsPftTSDvG%2F8Xji1koSKQwlxGSgpT1Nek%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4467&quot; height=&quot;2771&quot; data-origin-width=&quot;4467&quot; data-origin-height=&quot;2771&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지26] to_seconds epilogue&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;pop ebp 명령은 스택에 저장되어 있던 SFP를 다시 EBP에 복원하는 역할을 한다. 이 명령어 하나로 EBP는 to_seconds 함수 호출 이전의 main의 EBP 값이 복원되고, ESP는 자동으로 반환 주소(EIP)를 가리키게 되어 복귀 준비까지 완료된다. 매우 간단한 코드 한 줄 인데 치밀하고 정교한 설계 덕분에 이 짧은 코드가 수행하는 논리적 동작은 엄청나다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4467&quot; data-origin-height=&quot;2771&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cGaXk6/btsPfv5eHM6/iS987gsUAhSG14k86K1i1k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cGaXk6/btsPfv5eHM6/iS987gsUAhSG14k86K1i1k/img.jpg&quot; data-alt=&quot;[이미지27] to_seconds epilogue&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cGaXk6/btsPfv5eHM6/iS987gsUAhSG14k86K1i1k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcGaXk6%2FbtsPfv5eHM6%2FiS987gsUAhSG14k86K1i1k%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4467&quot; height=&quot;2771&quot; data-origin-width=&quot;4467&quot; data-origin-height=&quot;2771&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지27] to_seconds epilogue&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ret &amp;lt;n&amp;gt; 명령은 내부적으로 세 가지 동작 pop eip &amp;rarr; add esp, &amp;lt;n&amp;gt; &amp;rarr; jmp eip으로 구성된다. 이 중 첫 번째인 pop eip는 call 명령어로 함수에 진입할 때 스택에 저장해 두었던 복귀 주소(EIP)를 꺼내어 복원하는 단계다. &lt;span style=&quot;color: #333333;&quot;&gt;mov esp, ebp와 pop ebp의 과정을 거쳐 ESP는 main에서 call to_seconds를 할 때 스택에 저장해 두었던 EIP의 위치를 가리키게 된다. pop eip&lt;/span&gt;를 통해 현재 EIP를 갱신하며, 제어 흐름을 함수 호출 직후 위치로 되돌아갈 준비가 완료된다. ret를 pop eip &amp;rarr; jmp eip 처럼 풀어 쓰는 것은 개념을 나누어 설명하기 위한 표현일 뿐, 실제로는 pop eip만으로도 흐름이 바뀐다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4467&quot; data-origin-height=&quot;2771&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ysYVj/btsPfIpHJe7/5Uj0XtVL81xEoYDK3eJxA1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ysYVj/btsPfIpHJe7/5Uj0XtVL81xEoYDK3eJxA1/img.jpg&quot; data-alt=&quot;[이미지28] to_seconds epilogue&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ysYVj/btsPfIpHJe7/5Uj0XtVL81xEoYDK3eJxA1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FysYVj%2FbtsPfIpHJe7%2F5Uj0XtVL81xEoYDK3eJxA1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4467&quot; height=&quot;2771&quot; data-origin-width=&quot;4467&quot; data-origin-height=&quot;2771&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지28] to_seconds epilogue&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;add esp, &amp;lt;n&amp;gt; 명령은 ret &amp;lt;n&amp;gt;의 두 번째 단계로 함수 호출 시 스택에 쌓였던 인자들을 정리하는 역할을 한다. &amp;lt;n&amp;gt; 바이트만큼 ESP를 증가시켜 인자들이 차지했던 공간을 건너뛰며 스택을 정리한다. 이 동작을 통해 함수 호출 전(인자 push 전)의 스택 상태로 복구할 수 있게 된다. 단, 인자 정리 방식은 함수 호출 규약에 따라 달라질 수 있다. (ret &amp;lt;n&amp;gt;에서 &amp;lt;n&amp;gt;이 있을 경우에만 add esp, &amp;lt;n&amp;gt;을 실행한다.)&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4468&quot; data-origin-height=&quot;2771&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tp35w/btsPg0W6jcS/TklC42eqmBsnP54Ok0mKe0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tp35w/btsPg0W6jcS/TklC42eqmBsnP54Ok0mKe0/img.jpg&quot; data-alt=&quot;[이미지29] main body&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tp35w/btsPg0W6jcS/TklC42eqmBsnP54Ok0mKe0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Ftp35w%2FbtsPg0W6jcS%2FTklC42eqmBsnP54Ok0mKe0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4468&quot; height=&quot;2771&quot; data-origin-width=&quot;4468&quot; data-origin-height=&quot;2771&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지29] main body&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;pop eip가 실행되면서 제어가 다시 main으로 넘어가고, to_seconds 함수에서 return result_total; 을 통해 EAX 레지스터에 담아 둔 연산 결과도 그대로 유지된다. 이어서 이 EAX 값을 [ebp-0x10] 위치에 저장하는데, 이 코드가 정상적으로 동작하는 이유는 to_seconds의 에필로그 과정에서 이미 main의 EBP가 복원되었기 때문이다. 따라서 [ebp-0x10]가 main의 지역 변수 영역을 가리키게 된다. 결과적으로, 반환된 값이 main의 로컬 변수로 전달된다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4468&quot; data-origin-height=&quot;2771&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwhfdA/btsPfz0Ukwm/OM0qnMXyFmcz4kGeylhLD1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwhfdA/btsPfz0Ukwm/OM0qnMXyFmcz4kGeylhLD1/img.jpg&quot; data-alt=&quot;[이미지30] main body&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwhfdA/btsPfz0Ukwm/OM0qnMXyFmcz4kGeylhLD1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwhfdA%2FbtsPfz0Ukwm%2FOM0qnMXyFmcz4kGeylhLD1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4468&quot; height=&quot;2771&quot; data-origin-width=&quot;4468&quot; data-origin-height=&quot;2771&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지30] main body&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;printf 호출 시에도 마찬가지로, 먼저 포맷 문자열과 인자들이 push되어 스택에 적재되고, EIP와 SFP가 차례로 스택에 저장된다. 이어서 printf 내부의 프롤로그가 새로운 스택프레임을 설정하고, 바디에서 포맷 문자열을 해석해 콘솔(cmd) 창에 지정된 문자열을 출력한다. 에필로그 단계에서 ESP와 EBP를 원래 상태로 복원한다. 마지막으로 ret이 실행되면 printf를 호출 할 때 저장된 EIP가 복원되어 호출 지점으로 되돌아가면서 제어가 다시 main 함수로 넘어온다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4468&quot; data-origin-height=&quot;2771&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bO4CAA/btsPhtxRFA7/IueT1D7k8OsZMrsGFBxC31/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bO4CAA/btsPhtxRFA7/IueT1D7k8OsZMrsGFBxC31/img.jpg&quot; data-alt=&quot;[이미지31] main body&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bO4CAA/btsPhtxRFA7/IueT1D7k8OsZMrsGFBxC31/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbO4CAA%2FbtsPhtxRFA7%2FIueT1D7k8OsZMrsGFBxC31%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4468&quot; height=&quot;2771&quot; data-origin-width=&quot;4468&quot; data-origin-height=&quot;2771&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지31] main body&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;to_seconds와 달리 &lt;span style=&quot;color: #333333;&quot;&gt;printf는 &lt;/span&gt;가변 인자 함수이기 때문에, 호출이 끝난 후 스택에 쌓인 인자들을 호출자인 main 함수에서 정리해야 한다는 차이점이 있다. 해당 내용은 함수 호출 규약에서 자세하게 다루기 때문에 이 글에서는 중요하게 보지 않아도 된다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4468&quot; data-origin-height=&quot;2771&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cHqiSV/btsPfvjRkbr/N4Tokw1UnzvqkBYuu60bU0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cHqiSV/btsPfvjRkbr/N4Tokw1UnzvqkBYuu60bU0/img.jpg&quot; data-alt=&quot;[이미지32] main epilogue&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cHqiSV/btsPfvjRkbr/N4Tokw1UnzvqkBYuu60bU0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcHqiSV%2FbtsPfvjRkbr%2FN4Tokw1UnzvqkBYuu60bU0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4468&quot; height=&quot;2771&quot; data-origin-width=&quot;4468&quot; data-origin-height=&quot;2771&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지32] main epilogue&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;앞서 main 함수의 프롤로그에서 push해 두었던 레지스터를&amp;nbsp;&lt;/span&gt;복원하는 코드가 실행된다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4468&quot; data-origin-height=&quot;2771&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8062T/btsPhlNvXSl/os7kPVKqnDDtCx4gsvFZKk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8062T/btsPhlNvXSl/os7kPVKqnDDtCx4gsvFZKk/img.jpg&quot; data-alt=&quot;[이미지33] main epilogue&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8062T/btsPhlNvXSl/os7kPVKqnDDtCx4gsvFZKk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8062T%2FbtsPhlNvXSl%2Fos7kPVKqnDDtCx4gsvFZKk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4468&quot; height=&quot;2771&quot; data-origin-width=&quot;4468&quot; data-origin-height=&quot;2771&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지33] main epilogue&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;main 함수도 다른 함수들과 마찬가지로 호출되는 함수이기 때문에 스택 프레임을 구성하고 해제하는 과정 역시 동일하다. mov esp, ebp 명령은 sub esp, &amp;lt;n&amp;gt;를 통해 설정했던 경계를 해제하고 확보했던 지역 변수 및 임시 공간을 정리한다. 또한 ESP를 복원하는 역할도 한다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4468&quot; data-origin-height=&quot;2786&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bLPbZo/btsPiFSJAUj/HJQr3Cj6RXjz1CV4LrlLnk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bLPbZo/btsPiFSJAUj/HJQr3Cj6RXjz1CV4LrlLnk/img.jpg&quot; data-alt=&quot;[이미지34] main epilogue&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bLPbZo/btsPiFSJAUj/HJQr3Cj6RXjz1CV4LrlLnk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbLPbZo%2FbtsPiFSJAUj%2FHJQr3Cj6RXjz1CV4LrlLnk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4468&quot; height=&quot;2786&quot; data-origin-width=&quot;4468&quot; data-origin-height=&quot;2786&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지34] main epilogue&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;pop ebp로 SFP를 다시 EBP에 복원한다. ESP는 자동으로 반환 주소(EIP)를 가리키게 된다. 해당 SFP와 EIP는 main 함수 진입 시 call main과 main 함수 프롤로그에서 저장해 둔 값이다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4468&quot; data-origin-height=&quot;2786&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqhNxN/btsPhuXQc3a/D1hCQPvBjH3jql2v3s2cQ1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqhNxN/btsPhuXQc3a/D1hCQPvBjH3jql2v3s2cQ1/img.jpg&quot; data-alt=&quot;[이미지35] main epilogue&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqhNxN/btsPhuXQc3a/D1hCQPvBjH3jql2v3s2cQ1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqhNxN%2FbtsPhuXQc3a%2FD1hCQPvBjH3jql2v3s2cQ1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4468&quot; height=&quot;2786&quot; data-origin-width=&quot;4468&quot; data-origin-height=&quot;2786&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지35] main epilogue&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ret의 pop eip의 동작을 통해 제어 흐름을 main 함수 호출 직후 위치로 변경한다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;732&quot; data-origin-height=&quot;80&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sbp8f/btsPg1hlSvN/EQJ6Lq3C6Y5Isjix9VlbX0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sbp8f/btsPg1hlSvN/EQJ6Lq3C6Y5Isjix9VlbX0/img.png&quot; data-alt=&quot;[이미지36] x32dbg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sbp8f/btsPg1hlSvN/EQJ6Lq3C6Y5Isjix9VlbX0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fsbp8f%2FbtsPg1hlSvN%2FEQJ6Lq3C6Y5Isjix9VlbX0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;732&quot; height=&quot;80&quot; data-origin-width=&quot;732&quot; data-origin-height=&quot;80&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지36] x32dbg&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;x32dbg에서 확인해 보면 해당 EIP 값은 0x00411BC3으로 나타난다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;339&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/o519A/btsPhFLzZxk/8VriY0uhDxL3kI1WhEktOK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/o519A/btsPhFLzZxk/8VriY0uhDxL3kI1WhEktOK/img.png&quot; data-alt=&quot;[이미지37] x32dbg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/o519A/btsPhFLzZxk/8VriY0uhDxL3kI1WhEktOK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fo519A%2FbtsPhFLzZxk%2F8VriY0uhDxL3kI1WhEktOK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;720&quot; height=&quot;339&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;339&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지37] x32dbg&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;main 함수가 호출된 위치는 위와 같으며 main 함수 종료 후, 에필로그의 ret에서 pop eip를 통해 0x00411BC3의 코드가 실행된다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-3. 스택 프레임의 경계&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;한 함수가 실행되는 동안 독립적으로 점유하는 메모리 구간을 나누어 &quot;프레임&quot;이라 부른다. 이 경계를 명확히 해야 연속된 스택 공간 안에서 함수 호출마다 차지하는 범위를 일정하게 구분할 수 있으며, 어디까지를 하나의 단위로 묶을지를 결정할 수 있다. 즉, 스택 상에 저장된 정보 중 어느 지점을 경계로 삼아 한 함수의 프레임이 시작되고 끝나는지를 정의하는 기준이 필요하며, 이 기준에 따라 호출 흐름이나 데이터 구조를 해석하는 방식이 달라질 수 있다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;br /&gt;3-3-1. 구조 중심 경계&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4011&quot; data-origin-height=&quot;2139&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPmrIK/btsPg8a3PLO/rLGSWsSqKsqkeEDOAwCuk0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPmrIK/btsPg8a3PLO/rLGSWsSqKsqkeEDOAwCuk0/img.jpg&quot; data-alt=&quot;[이미지38] 스택 프레임 경계 (구조)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPmrIK/btsPg8a3PLO/rLGSWsSqKsqkeEDOAwCuk0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPmrIK%2FbtsPg8a3PLO%2FrLGSWsSqKsqkeEDOAwCuk0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4011&quot; height=&quot;2139&quot; data-origin-width=&quot;4011&quot; data-origin-height=&quot;2139&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지38] 스택 프레임 경계 (구조)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;경계 기준&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수 프레임 구조를 고려해 함수 진입 직후 프롤로그에서 저장되는 이전 프레임의 SFP(push ebp)부터, 함수 호출 지점(call)에서 push된 반환 주소(EIP) 까지를 하나의 프레임으로 본다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;장점&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;호출 단계를 명확히 구분할 수 있다. 함수 프레임과 스택 프레임을 1대1로 대응해 호출 관계를 파악하기 용이하다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;단점&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 프레임안에 이전 프레임의 SFP, &lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;로컬 변수,&amp;nbsp;&lt;/span&gt; 호출 인자, 함수 호출 지점 EIP가 섞여 존재한다. 이로 인해 데이터의 기능별 영역 구분이 흐려지고, 함수 내에서 실제 어떤 값이 어떻게 사용되는지를 해석하기 어렵다.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3-3-2. 기능 중심 경계&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3848&quot; data-origin-height=&quot;2139&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p1ABw/btsPjhjDpy0/LQ2uiDlPpUgNKHMs8220n0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p1ABw/btsPjhjDpy0/LQ2uiDlPpUgNKHMs8220n0/img.jpg&quot; data-alt=&quot;[이미지39] 스택 프레임 경계 (구조)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p1ABw/btsPjhjDpy0/LQ2uiDlPpUgNKHMs8220n0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp1ABw%2FbtsPjhjDpy0%2FLQ2uiDlPpUgNKHMs8220n0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3848&quot; height=&quot;2139&quot; data-origin-width=&quot;3848&quot; data-origin-height=&quot;2139&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지39] 스택 프레임 경계 (구조)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;경계 기준&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수 내부에서 실질적으로 참조하거나 사용하는 데이터를 중심으로 SFP, Local Data, EIP, Argument의 영역을 통합해 하나의 프레임으로 본다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;장점&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수가 실제로 읽고 쓰는 메모리 구조를 파악하기 쉬워지며, 코드의 동작 흐름과 연관 지어 의미를 해석하기에 적합하다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;단점&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스택 프레임과 호출 단계가 1:1로 대응되지 않기 때문에, 호출 관계를 직접적으로 파악하기 어렵고 프레임을 통합해서 해석해야 호출 흐름을 재구성할 수 있다.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3-3-3. 구분&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3772&quot; data-origin-height=&quot;2424&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wArVb/btsPhGkXEh5/aAsZzZyfkKyRB35HV3csn1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wArVb/btsPhGkXEh5/aAsZzZyfkKyRB35HV3csn1/img.jpg&quot; data-alt=&quot;[이미지40] 스택 프레임 경계&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wArVb/btsPhGkXEh5/aAsZzZyfkKyRB35HV3csn1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwArVb%2FbtsPhGkXEh5%2FaAsZzZyfkKyRB35HV3csn1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3772&quot; height=&quot;2424&quot; data-origin-width=&quot;3772&quot; data-origin-height=&quot;2424&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[이미지40] 스택 프레임 경계&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;경계 지정 방식&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;경계기준&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;장점&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;단점&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;구조 중심&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;함수 프레임 구조를 고려해 함수 진입 직후 프롤로그에서 저장되는 이전 프레임의 SFP(push ebp)부터, 함수 호출 지점(call)에서 push된 반환 주소(EIP) 까지를 하나의 프레임으로 본다.&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;호출 단계를 명확히 구분할 수 있다. 함수 프레임과 스택 프레임을 1대1로 대응해 호출 관계를 파악하기 용이하다.&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;한 프레임안에 이전 프레임의 SFP,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&amp;nbsp;로컬 변수,&amp;nbsp;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;호출 인자, 함수 호출 지점 EIP가 섞여 존재한다. 이로 인해 데이터의 기능별 영역 구분이 흐려지고, 함수 내에서 실제 어떤 값이 어떻게 사용되는지를 해석하기 어렵다.&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;기능 중심&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;함수 내부에서 실질적으로 참조하거나 사용하는 데이터를 중심으로 SFP, Local Data, EIP, Argument의 영역을 통합해 하나의 프레임으로 본다.&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;함수가 실제로 읽고 쓰는 메모리 구조를 파악하기 쉬워지며, 코드의 동작 흐름과 연관 지어 의미를 해석하기에 적합하다.&lt;/td&gt;
&lt;td style=&quot;width: 25%;&quot;&gt;스택 프레임과 호출 단계가 1:1로 대응되지 않기 때문에, 호출 관계를 직접적으로 파악하기 어렵고 프레임을 통합해서 해석해야 호출 흐름을 재구성할 수 있다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Reversing/Definition</category>
      <category>stack frame</category>
      <category>x32</category>
      <category>스택프레임</category>
      <author>kj0on</author>
      <guid isPermaLink="true">https://kj0on.tistory.com/41</guid>
      <comments>https://kj0on.tistory.com/41#entry41comment</comments>
      <pubDate>Sun, 13 Jul 2025 12:51:22 +0900</pubDate>
    </item>
    <item>
      <title>[Programmers] 코딩 기초 트레이닝 (124 문제)</title>
      <link>https://kj0on.tistory.com/40</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;programmers-logo-dark.png&quot; data-origin-width=&quot;683&quot; data-origin-height=&quot;161&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UsozV/btsPE5qiLq9/0w0PlRqOilNl3KgQrXLk5K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UsozV/btsPE5qiLq9/0w0PlRqOilNl3KgQrXLk5K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UsozV/btsPE5qiLq9/0w0PlRqOilNl3KgQrXLk5K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUsozV%2FbtsPE5qiLq9%2F0w0PlRqOilNl3KgQrXLk5K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;683&quot; height=&quot;161&quot; data-filename=&quot;programmers-logo-dark.png&quot; data-origin-width=&quot;683&quot; data-origin-height=&quot;161&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;1. 조건에&amp;nbsp;맞게&amp;nbsp;수열&amp;nbsp;변환하기&amp;nbsp;1&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;1-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수 배열 arr가 주어집니다. arr의 각 원소에 대해 값이 50보다 크거나 같은 짝수라면 2로 나누고, 50보다 작은 홀수라면 2를 곱합니다. 그 결과인 정수 배열을 return 하는 solution 함수를 완성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181882&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181882&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;1-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753962717510&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(arr):
    answer = []
    for i in arr:
        if i &amp;gt;= 50 and i % 2 == 0:
            answer.append(i // 2)
        elif i &amp;lt; 50 and i % 2 == 1:
            answer.append(i * 2)
        else:
            answer.append(i)
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181882.%E2%80%85%EC%A1%B0%EA%B1%B4%EC%97%90%E2%80%85%EB%A7%9E%EA%B2%8C%E2%80%85%EC%88%98%EC%97%B4%E2%80%85%EB%B3%80%ED%99%98%ED%95%98%EA%B8%B0%E2%80%851&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181882.%E2%80%85%EC%A1%B0%EA%B1%B4%EC%97%90%E2%80%85%EB%A7%9E%EA%B2%8C%E2%80%85%EC%88%98%EC%97%B4%E2%80%85%EB%B3%80%ED%99%98%ED%95%98%EA%B8%B0%E2%80%851&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;2. n보다&amp;nbsp;커질&amp;nbsp;때까지&amp;nbsp;더하기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;2-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수 배열 numbers와 정수 n이 매개변수로 주어집니다. numbers의 원소를 앞에서부터 하나씩 더하다가 그 합이 n보다 커지는 순간 이때까지 더했던 원소들의 합을 return 하는 solution 함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181884&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181884&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;2-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753962758955&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(numbers, n):
    answer = 0
    for i in numbers:
        answer += i
        if answer &amp;gt; n:
            break
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181884.%E2%80%85n%EB%B3%B4%EB%8B%A4%E2%80%85%EC%BB%A4%EC%A7%88%E2%80%85%EB%95%8C%EA%B9%8C%EC%A7%80%E2%80%85%EB%8D%94%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181884.%E2%80%85n%EB%B3%B4%EB%8B%A4%E2%80%85%EC%BB%A4%EC%A7%88%E2%80%85%EB%95%8C%EA%B9%8C%EC%A7%80%E2%80%85%EB%8D%94%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;3. 5명씩&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;3-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;최대 5명씩 탑승가능한 놀이기구를 타기 위해 줄을 서있는 사람들의 이름이 담긴 문자열 리스트 names가 주어질 때, 앞에서 부터 5명씩 묶은 그룹의 가장 앞에 서있는 사람들의 이름을 담은 리스트를 return하도록 solution 함수를 완성해주세요. 마지막 그룹이 5명이 되지 않더라도 가장 앞에 있는 사람의 이름을 포함합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181886&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181886&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;3-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753962796163&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(names):
    answer = []
    for i in range(0, len(names), 5):
        answer.append(names[i])
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181886.%E2%80%855%EB%AA%85%EC%94%A9&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181886.%E2%80%855%EB%AA%85%EC%94%A9&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;4. 순서&amp;nbsp;바꾸기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;4-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수 리스트 num_list와 정수 n이 주어질 때, num_list를 n 번째 원소 이후의 원소들과 n 번째까지의 원소들로 나눠 n 번째 원소 이후의 원소들을 n 번째까지의 원소들 앞에 붙인 리스트를 return하도록 solution 함수를 완성해주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181891&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181891&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;4-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753962830133&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(num_list, n):
    answer = num_list[n:] + num_list[:n]
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181891.%E2%80%85%EC%88%9C%EC%84%9C%E2%80%85%EB%B0%94%EA%BE%B8%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181891.%E2%80%85%EC%88%9C%EC%84%9C%E2%80%85%EB%B0%94%EA%BE%B8%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;5. 카운트&amp;nbsp;다운&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;5-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수 start_num와 end_num가 주어질 때, start_num에서 end_num까지 1씩 감소하는 수들을 차례로 담은 리스트를 return하도록 solution 함수를 완성해주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181899&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181899&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;5-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753962864319&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(start_num, end_num):
    answer = [i for i in range(start_num, end_num - 1, -1)]
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181899.%E2%80%85%EC%B9%B4%EC%9A%B4%ED%8A%B8%E2%80%85%EB%8B%A4%EC%9A%B4&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181899.%E2%80%85%EC%B9%B4%EC%9A%B4%ED%8A%B8%E2%80%85%EB%8B%A4%EC%9A%B4&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;6. 배열&amp;nbsp;만들기&amp;nbsp;1&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;6-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수 n과 k가 주어졌을 때, 1 이상 n이하의 정수 중에서 k의 배수를 오름차순으로 저장한 배열을 return 하는 solution 함수를 완성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181901&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181901&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;6-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753962903708&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(n, k):
    answer = [i for i in range(k, n + 1, k)]
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181901.%E2%80%85%EB%B0%B0%EC%97%B4%E2%80%85%EB%A7%8C%EB%93%A4%EA%B8%B0%E2%80%851&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181901.%E2%80%85%EB%B0%B0%EC%97%B4%E2%80%85%EB%A7%8C%EB%93%A4%EA%B8%B0%E2%80%851&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;7. 접두사인지&amp;nbsp;확인하기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;7-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;어떤 문자열에 대해서 접두사는 특정 인덱스까지의 문자열을 의미합니다. 예를 들어, &quot;banana&quot;의 모든 접두사는 &quot;b&quot;, &quot;ba&quot;, &quot;ban&quot;, &quot;bana&quot;, &quot;banan&quot;, &quot;banana&quot;입니다. 문자열 my_string과 is_prefix가 주어질 때, is_prefix가 my_string의 접두사라면 1을, 아니면 0을 return 하는 solution 함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181906&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181906&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;7-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753962958121&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(my_string, is_prefix):
    prefix = [my_string[:i+1] for i in range(len(my_string))]
    answer = 1 if is_prefix in prefix else 0
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181906.%E2%80%85%EC%A0%91%EB%91%90%EC%82%AC%EC%9D%B8%EC%A7%80%E2%80%85%ED%99%95%EC%9D%B8%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181906.%E2%80%85%EC%A0%91%EB%91%90%EC%82%AC%EC%9D%B8%EC%A7%80%E2%80%85%ED%99%95%EC%9D%B8%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;8. 접미사&amp;nbsp;배열&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;8-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;어떤 문자열에 대해서 접미사는 특정 인덱스부터 시작하는 문자열을 의미합니다. 예를 들어, &quot;banana&quot;의 모든 접미사는 &quot;banana&quot;, &quot;anana&quot;, &quot;nana&quot;, &quot;ana&quot;, &quot;na&quot;, &quot;a&quot;입니다. 문자열 my_string이 매개변수로 주어질 때, my_string의 모든 접미사를 사전순으로 정렬한 문자열 배열을 return 하는 solution 함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181909&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181909&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;8-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753962995689&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(my_string):
    answer = sorted([my_string[i:] for i in range(len(my_string))])
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181909.%E2%80%85%EC%A0%91%EB%AF%B8%EC%82%AC%E2%80%85%EB%B0%B0%EC%97%B4&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181909.%E2%80%85%EC%A0%91%EB%AF%B8%EC%82%AC%E2%80%85%EB%B0%B0%EC%97%B4&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;9. 부분&amp;nbsp;문자열&amp;nbsp;이어&amp;nbsp;붙여&amp;nbsp;문자열&amp;nbsp;만들기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;9-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;길이가 같은 문자열 배열 my_strings와 이차원 정수 배열 parts가 매개변수로 주어집니다. parts[i]는 [s, e] 형태로, my_string[i]의 인덱스 s부터 인덱스 e까지의 부분 문자열을 의미합니다. 각 my_strings의 원소의 parts에 해당하는 부분 문자열을 순서대로 이어 붙인 문자열을 return 하는 solution 함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181911&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181911&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;9-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753963037588&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(my_strings, parts):
    answer = ''
    for p, idx in zip(my_strings, parts):
        answer += p[idx[0]:idx[1] + 1]
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181911.%E2%80%85%EB%B6%80%EB%B6%84%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%E2%80%85%EC%9D%B4%EC%96%B4%E2%80%85%EB%B6%99%EC%97%AC%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%E2%80%85%EB%A7%8C%EB%93%A4%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181911.%E2%80%85%EB%B6%80%EB%B6%84%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%E2%80%85%EC%9D%B4%EC%96%B4%E2%80%85%EB%B6%99%EC%97%AC%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%E2%80%85%EB%A7%8C%EB%93%A4%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;10. 글자&amp;nbsp;이어&amp;nbsp;붙여&amp;nbsp;문자열&amp;nbsp;만들기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;10-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;문자열 my_string과 정수 배열 index_list가 매개변수로 주어집니다. my_string의 index_list의 원소들에 해당하는 인덱스의 글자들을 순서대로 이어 붙인 문자열을 return 하는 solution 함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181915&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181915&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;10-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753963097931&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(my_string, index_list):
    answer = ''.join([my_string[i] for i in index_list])
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181915.%E2%80%85%EA%B8%80%EC%9E%90%E2%80%85%EC%9D%B4%EC%96%B4%E2%80%85%EB%B6%99%EC%97%AC%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%E2%80%85%EB%A7%8C%EB%93%A4%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181915.%E2%80%85%EA%B8%80%EC%9E%90%E2%80%85%EC%9D%B4%EC%96%B4%E2%80%85%EB%B6%99%EC%97%AC%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%E2%80%85%EB%A7%8C%EB%93%A4%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;11. 콜라츠&amp;nbsp;수열&amp;nbsp;만들기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;11-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;모든 자연수 x에 대해서 현재 값이 x이면 x가 짝수일 때는 2로 나누고, x가 홀수일 때는 3 * x + 1로 바꾸는 계산을 계속해서 반복하면 언젠가는 반드시 x가 1이 되는지 묻는 문제를 콜라츠 문제라고 부릅니다. &lt;br /&gt;&lt;br /&gt;그리고 위 과정에서 거쳐간 모든 수를 기록한 수열을 콜라츠 수열이라고 부릅니다. &lt;br /&gt;&lt;br /&gt;계산 결과 1,000 보다 작거나 같은 수에 대해서는 전부 언젠가 1에 도달한다는 것이 알려져 있습니다. &lt;br /&gt;&lt;br /&gt;임의의 1,000 보다 작거나 같은 양의 정수 n이 주어질 때 초기값이 n인 콜라츠 수열을 return 하는 solution 함수를 완성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181919&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181919&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;11-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753963209450&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(n):
    answer = [n]
    while n != 1:
        n = n // 2 if n % 2 == 0 else 3 * n + 1
        answer.append(n)
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181919.%E2%80%85%EC%BD%9C%EB%9D%BC%EC%B8%A0%E2%80%85%EC%88%98%EC%97%B4%E2%80%85%EB%A7%8C%EB%93%A4%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181919.%E2%80%85%EC%BD%9C%EB%9D%BC%EC%B8%A0%E2%80%85%EC%88%98%EC%97%B4%E2%80%85%EB%A7%8C%EB%93%A4%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;12. 수&amp;nbsp;조작하기&amp;nbsp;2&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;12-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수 배열 numLog가 주어집니다. 처음에 numLog[0]에서 부터 시작해 &quot;w&quot;, &quot;a&quot;, &quot;s&quot;, &quot;d&quot;로 이루어진 문자열을 입력으로 받아 순서대로 다음과 같은 조작을 했다고 합시다. &lt;br /&gt;&lt;br /&gt;&quot;w&quot; : 수에 1을 더한다. &lt;br /&gt;&quot;s&quot; : 수에 1을 뺀다. &lt;br /&gt;&quot;d&quot; : 수에 10을 더한다. &lt;br /&gt;&quot;a&quot; : 수에 10을 뺀다. &lt;br /&gt;&lt;br /&gt;그리고 매번 조작을 할 때마다 결괏값을 기록한 정수 배열이 numLog입니다. 즉, numLog[i]는 numLog[0]로부터 총 i번의 조작을 가한 결과가 저장되어 있습니다. &lt;br /&gt;&lt;br /&gt;주어진 정수 배열 numLog에 대해 조작을 위해 입력받은 문자열을 return 하는 solution 함수를 완성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181925&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181925&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;12-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753963263879&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(numLog):
    c = {1:'w', -1:'s', 10:'d', -10:'a'}
    answer = ''.join([c[numLog[i + 1] - numLog[i]] for i in range(len(numLog) - 1)])
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181925.%E2%80%85%EC%88%98%E2%80%85%EC%A1%B0%EC%9E%91%ED%95%98%EA%B8%B0%E2%80%852&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181925.%E2%80%85%EC%88%98%E2%80%85%EC%A1%B0%EC%9E%91%ED%95%98%EA%B8%B0%E2%80%852&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;13. 수&amp;nbsp;조작하기&amp;nbsp;1&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;13-1. 문제 설명&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;정수 n과 문자열 control이 주어집니다. control은 &quot;w&quot;, &quot;a&quot;, &quot;s&quot;, &quot;d&quot;의 4개의 문자로 이루어져 있으며, control의 앞에서부터 순서대로 문자에 따라 n의 값을 바꿉니다. &lt;br /&gt;&lt;br /&gt;&quot;w&quot; : n이 1 커집니다.&lt;br /&gt;&quot;s&quot; : n이 1 작아집니다. &lt;br /&gt;&quot;d&quot; : n이 10 커집니다.&lt;br /&gt;&quot;a&quot; : n이 10 작아집니다. &lt;br /&gt;&lt;br /&gt;위 규칙에 따라 n을 바꿨을 때 가장 마지막에 나오는 n의 값을 return 하는 solution 함수를 완성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181926&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181926&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;13-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753963957358&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(n, control):
    answer = n
    c = { 'w':1, 's':-1, 'd':10, 'a':-10}
    for i in control:
        answer += c[i]
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181926.%E2%80%85%EC%88%98%E2%80%85%EC%A1%B0%EC%9E%91%ED%95%98%EA%B8%B0%E2%80%851&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181926.%E2%80%85%EC%88%98%E2%80%85%EC%A1%B0%EC%9E%91%ED%95%98%EA%B8%B0%E2%80%851&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;14. 마지막&amp;nbsp;두&amp;nbsp;원소&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;14-1. 문제 설명&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;정수 리스트 num_list가 주어질 때, 마지막 원소가 그전 원소보다 크면 마지막 원소에서 그전 원소를 뺀 값을 마지막 원소가 그전 원소보다 크지 않다면 마지막 원소를 두 배한 값을 추가하여 return하도록 solution 함수를 완성해주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181927&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181927&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;14-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753964250868&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(num_list):
    num_list.append(num_list[-1] - num_list[-2]) if num_list[-1] &amp;gt; num_list[-2] else num_list.append(num_list[-1] * 2)
    answer = num_list
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181927.%E2%80%85%EB%A7%88%EC%A7%80%EB%A7%89%E2%80%85%EB%91%90%E2%80%85%EC%9B%90%EC%86%8C&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181927.%E2%80%85%EB%A7%88%EC%A7%80%EB%A7%89%E2%80%85%EB%91%90%E2%80%85%EC%9B%90%EC%86%8C&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;15. 주사위&amp;nbsp;게임&amp;nbsp;2&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;15-1. 문제 설명&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;1부터 6까지 숫자가 적힌 주사위가 세 개 있습니다. 세 주사위를 굴렸을 때 나온 숫자를 각각 a, b, c라고 했을 때 얻는 점수는 다음과 같습니다. &lt;br /&gt;&lt;br /&gt;세 숫자가 모두 다르다면 a + b + c 점을 얻습니다. &lt;br /&gt;세 숫자 중 어느 두 숫자는 같고 나머지 다른 숫자는 다르다면 (a + b + c) &amp;times; (a2 + b2 + c2 )점을 얻습니다. &lt;br /&gt;세 숫자가 모두 같다면 (a + b + c) &amp;times; (a2 + b2 + c2 ) &amp;times; (a3 + b3 + c3 )점을 얻습니다. &lt;br /&gt;&lt;br /&gt;세 정수 a, b, c가 매개변수로 주어질 때, 얻는 점수를 return 하는 solution 함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181930&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181930&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;15-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753964301466&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(a, b, c):
    answer = 0
    if a != b and b != c and a != c:
        answer = a + b + c
    elif a == b and b == c and a == c:
        answer = (a + b + c) * (a ** 2 + b ** 2 + c ** 2) * (a ** 3 + b ** 3 + c ** 3)
    elif a == b or b == c or a == c:
        answer = (a + b + c) * (a ** 2 + b **2 + c ** 2)
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181930.%E2%80%85%EC%A3%BC%EC%82%AC%EC%9C%84%E2%80%85%EA%B2%8C%EC%9E%84%E2%80%852&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181930.%E2%80%85%EC%A3%BC%EC%82%AC%EC%9C%84%E2%80%85%EA%B2%8C%EC%9E%84%E2%80%852&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;16. 문자열&amp;nbsp;돌리기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;16-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;문자열 str이 주어집니다.&lt;br /&gt;문자열을 시계방향으로 90도 돌려서 아래 입출력 예와 같이 출력하는 코드를 작성해 보세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181945&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181945&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;16-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753964337897&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;str = input()
for i in str:
    print(i)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181945.%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%E2%80%85%EB%8F%8C%EB%A6%AC%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181945.%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%E2%80%85%EB%8F%8C%EB%A6%AC%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;17. 덧셈식&amp;nbsp;출력하기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;17-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;두 정수 a, b가 주어질 때 다음과 같은 형태의 계산식을 출력하는 코드를 작성해 보세요. &lt;br /&gt;&lt;br /&gt;a + b = c&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181947&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181947&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;17-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753964376592&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;a, b = map(int, input().strip().split(' '))
print(f&quot;{a} + {b} = {a+b}&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181947.%E2%80%85%EB%8D%A7%EC%85%88%EC%8B%9D%E2%80%85%EC%B6%9C%EB%A0%A5%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181947.%E2%80%85%EB%8D%A7%EC%85%88%EC%8B%9D%E2%80%85%EC%B6%9C%EB%A0%A5%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;18. A&amp;nbsp;강조하기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;18-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;문자열 myString이 주어집니다. myString에서 알파벳 &quot;a&quot;가 등장하면 전부 &quot;A&quot;로 변환하고, &quot;A&quot;가 아닌 모든 대문자 알파벳은 소문자 알파벳으로 변환하여 return 하는 solution 함수를 완성하세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181874&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181874&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;18-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753964415697&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(myString):
    answer = myString.lower().replace('a', 'A')
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181874.%E2%80%85A%E2%80%85%EA%B0%95%EC%A1%B0%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181874.%E2%80%85A%E2%80%85%EA%B0%95%EC%A1%B0%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;19. 특정한&amp;nbsp;문자를&amp;nbsp;대문자로&amp;nbsp;바꾸기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;19-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;영소문자로 이루어진 문자열 my_string과 영소문자 1글자로 이루어진 문자열 alp가 매개변수로 주어질 때, my_string에서 alp에 해당하는 모든 글자를 대문자로 바꾼 문자열을 return 하는 solution 함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181873&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181873&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;19-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753964446460&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(my_string, alp):
    answer = my_string.replace(alp, alp.upper())
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181873.%E2%80%85%ED%8A%B9%EC%A0%95%ED%95%9C%E2%80%85%EB%AC%B8%EC%9E%90%EB%A5%BC%E2%80%85%EB%8C%80%EB%AC%B8%EC%9E%90%EB%A1%9C%E2%80%85%EB%B0%94%EA%BE%B8%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181873.%E2%80%85%ED%8A%B9%EC%A0%95%ED%95%9C%E2%80%85%EB%AC%B8%EC%9E%90%EB%A5%BC%E2%80%85%EB%8C%80%EB%AC%B8%EC%9E%90%EB%A1%9C%E2%80%85%EB%B0%94%EA%BE%B8%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;20. 조건에&amp;nbsp;맞게&amp;nbsp;수열&amp;nbsp;변환하기&amp;nbsp;3&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;20-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수 배열 arr와 자연수 k가 주어집니다. &lt;br /&gt;&lt;br /&gt;만약 k가 홀수라면 arr의 모든 원소에 k를 곱하고, k가 짝수라면 arr의 모든 원소에 k를 더합니다. &lt;br /&gt;&lt;br /&gt;이러한 변환을 마친 후의 arr를 return 하는 solution 함수를 완성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181835&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181835&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;20-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753964482986&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(arr, k):
    answer = list(map(lambda x: x * k if k % 2 == 1 else x + k, arr))
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181835.%E2%80%85%EC%A1%B0%EA%B1%B4%EC%97%90%E2%80%85%EB%A7%9E%EA%B2%8C%E2%80%85%EC%88%98%EC%97%B4%E2%80%85%EB%B3%80%ED%99%98%ED%95%98%EA%B8%B0%E2%80%853&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181835.%E2%80%85%EC%A1%B0%EA%B1%B4%EC%97%90%E2%80%85%EB%A7%9E%EA%B2%8C%E2%80%85%EC%88%98%EC%97%B4%E2%80%85%EB%B3%80%ED%99%98%ED%95%98%EA%B8%B0%E2%80%853&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;21. l로&amp;nbsp;만들기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;21-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;알파벳 소문자로 이루어진 문자열 myString이 주어집니다. 알파벳 순서에서 &quot;l&quot;보다 앞서는 모든 문자를 &quot;l&quot;로 바꾼 문자열을 return 하는 solution 함수를 완성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181834&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181834&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;21-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753964518454&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(myString):
    answer = ''.join([i if i &amp;gt; 'l' else 'l' for i in myString])
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181834.%E2%80%85l%EB%A1%9C%E2%80%85%EB%A7%8C%EB%93%A4%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181834.%E2%80%85l%EB%A1%9C%E2%80%85%EB%A7%8C%EB%93%A4%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;22. 정수&amp;nbsp;부분&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;22-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;실수 flo가 매개 변수로 주어질 때, flo의 정수 부분을 return하도록 solution 함수를 완성해주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181850&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181850&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;22-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753964544437&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(flo):
    answer = int(flo)
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181850.%E2%80%85%EC%A0%95%EC%88%98%E2%80%85%EB%B6%80%EB%B6%84&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181850.%E2%80%85%EC%A0%95%EC%88%98%E2%80%85%EB%B6%80%EB%B6%84&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;23. 문자열&amp;nbsp;바꿔서&amp;nbsp;찾기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;23-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;문자 &quot;A&quot;와 &quot;B&quot;로 이루어진 문자열 myString과 pat가 주어집니다. myString의 &quot;A&quot;를 &quot;B&quot;로, &quot;B&quot;를 &quot;A&quot;로 바꾼 문자열의 연속하는 부분 문자열 중 pat이 있으면 1을 아니면 0을 return 하는 solution 함수를 완성하세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181864&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181864&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;23-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753964583511&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(myString, pat):
    c = {'A':'B', 'B':'A'}
    answer = 1 if pat in ''.join([c[i] for i in myString]) else 0
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181864.%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%E2%80%85%EB%B0%94%EA%BF%94%EC%84%9C%E2%80%85%EC%B0%BE%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181864.%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%E2%80%85%EB%B0%94%EA%BF%94%EC%84%9C%E2%80%85%EC%B0%BE%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;24. 정수&amp;nbsp;찾기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;24-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수 리스트 num_list와 찾으려는 정수 n이 주어질 때, num_list안에 n이 있으면 1을 없으면 0을 return하도록 solution 함수를 완성해주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181840&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181840&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;24-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753964611069&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(num_list, n):
    answer = 1 if n in num_list else 0
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181840.%E2%80%85%EC%A0%95%EC%88%98%E2%80%85%EC%B0%BE%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181840.%E2%80%85%EC%A0%95%EC%88%98%E2%80%85%EC%B0%BE%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;25. 배열의&amp;nbsp;원소&amp;nbsp;삭제하기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;25-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수 배열 arr과 delete_list가 있습니다. arr의 원소 중 delete_list의 원소를 모두 삭제하고 남은 원소들은 기존의 arr에 있던 순서를 유지한 배열을 return 하는 solution 함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181844&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181844&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;25-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753964658157&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(arr, delete_list):
    answer = list()
    for i in arr:
        if i not in delete_list:
            answer.append(i)
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181844.%E2%80%85%EB%B0%B0%EC%97%B4%EC%9D%98%E2%80%85%EC%9B%90%EC%86%8C%E2%80%85%EC%82%AD%EC%A0%9C%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181844.%E2%80%85%EB%B0%B0%EC%97%B4%EC%9D%98%E2%80%85%EC%9B%90%EC%86%8C%E2%80%85%EC%82%AD%EC%A0%9C%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;26. 꼬리&amp;nbsp;문자열&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;26-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;문자열들이 담긴 리스트가 주어졌을 때, 모든 문자열들을 순서대로 합친 문자열을 꼬리 문자열이라고 합니다. 꼬리 문자열을 만들 때 특정 문자열을 포함한 문자열은 제외시키려고 합니다. 예를 들어 문자열 리스트 [&quot;abc&quot;, &quot;def&quot;, &quot;ghi&quot;]가 있고 문자열 &quot;ef&quot;를 포함한 문자열은 제외하고 꼬리 문자열을 만들면 &quot;abcghi&quot;가 됩니다.&lt;br /&gt;&lt;br /&gt;문자열 리스트 str_list와 제외하려는 문자열 ex가 주어질 때, str_list에서 ex를 포함한 문자열을 제외하고 만든 꼬리 문자열을 return하도록 solution 함수를 완성해주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181841&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181841&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;26-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753964701193&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(str_list, ex):
    answer = ''.join(i for i in str_list if ex not in i)
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181841.%E2%80%85%EA%BC%AC%EB%A6%AC%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181841.%E2%80%85%EA%BC%AC%EB%A6%AC%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;27. 0&amp;nbsp;떼기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;27-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수로 이루어진 문자열 n_str이 주어질 때, n_str의 가장 왼쪽에 처음으로 등장하는 0들을 뗀 문자열을 return하도록 solution 함수를 완성해주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181847&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181847&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;27-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753964732868&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(n_str):
    answer = str(int(n_str))
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181847.%E2%80%850%E2%80%85%EB%96%BC%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181847.%E2%80%850%E2%80%85%EB%96%BC%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;28. 부분&amp;nbsp;문자열&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;28-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;어떤 문자열 A가 다른 문자열 B안에 속하면 A를 B의 부분 문자열이라고 합니다. 예를 들어 문자열 &quot;abc&quot;는 문자열 &quot;aabcc&quot;의 부분 문자열입니다. &lt;br /&gt;&lt;br /&gt;문자열 str1과 str2가 주어질 때, str1이 str2의 부분 문자열이라면 1을 부분 문자열이 아니라면 0을 return하도록 solution 함수를 완성해주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181842&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181842&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;28-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753964771473&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(str1, str2):
    answer = int(str1 in str2)
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181842.%E2%80%85%EB%B6%80%EB%B6%84%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181842.%E2%80%85%EB%B6%80%EB%B6%84%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;29. 특별한&amp;nbsp;이차원&amp;nbsp;배열&amp;nbsp;2&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;29-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;n &amp;times; n 크기의 이차원 배열 arr이 매개변수로 주어질 때, arr이 다음을 만족하면 1을 아니라면 0을 return 하는 solution 함수를 작성해 주세요.&lt;br /&gt;&lt;br /&gt;0 &amp;le; i, j &amp;lt; n인 정수 i, j에 대하여 arr[i][j] = arr[j][i]&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181831&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181831&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;29-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753964824046&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(arr):
    answer = 1
    n = len(arr)
    for i in range(n):
        for j in range(n):
            if arr[i][j] != arr[j][i]:
                answer = 0
                break
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181831.%E2%80%85%ED%8A%B9%EB%B3%84%ED%95%9C%E2%80%85%EC%9D%B4%EC%B0%A8%EC%9B%90%E2%80%85%EB%B0%B0%EC%97%B4%E2%80%852&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181831.%E2%80%85%ED%8A%B9%EB%B3%84%ED%95%9C%E2%80%85%EC%9D%B4%EC%B0%A8%EC%9B%90%E2%80%85%EB%B0%B0%EC%97%B4%E2%80%852&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;30. 특별한&amp;nbsp;이차원&amp;nbsp;배열&amp;nbsp;1&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;30-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수 n이 매개변수로 주어질 때, 다음과 같은 n &amp;times; n 크기의 이차원 배열 arr를 return 하는 solution 함수를 작성해 주세요.&lt;br /&gt;&lt;br /&gt;arr[i][j] (0 &amp;le; i, j &amp;lt; n)의 값은 i = j라면 1, 아니라면 0입니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181833&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181833&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;30-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753964861778&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(n):
    answer = [[1 if j==i else 0 for j in range(n)] for i in range(n)]
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181833.%E2%80%85%ED%8A%B9%EB%B3%84%ED%95%9C%E2%80%85%EC%9D%B4%EC%B0%A8%EC%9B%90%E2%80%85%EB%B0%B0%EC%97%B4%E2%80%851&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181833.%E2%80%85%ED%8A%B9%EB%B3%84%ED%95%9C%E2%80%85%EC%9D%B4%EC%B0%A8%EC%9B%90%E2%80%85%EB%B0%B0%EC%97%B4%E2%80%851&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;31. 부분&amp;nbsp;문자열인지&amp;nbsp;확인하기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;31-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;부분 문자열이란 문자열에서 연속된 일부분에 해당하는 문자열을 의미합니다. 예를 들어, 문자열 &quot;ana&quot;, &quot;ban&quot;, &quot;anana&quot;, &quot;banana&quot;, &quot;n&quot;는 모두 문자열 &quot;banana&quot;의 부분 문자열이지만, &quot;aaa&quot;, &quot;bnana&quot;, &quot;wxyz&quot;는 모두 &quot;banana&quot;의 부분 문자열이 아닙니다.&lt;br /&gt;&lt;br /&gt;문자열 my_string과 target이 매개변수로 주어질 때, target이 문자열 my_string의 부분 문자열이라면 1을, 아니라면 0을 return 하는 solution 함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181843&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181843&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;31-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753964900119&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(my_string, target):
    answer = int(target in my_string)
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181843.%E2%80%85%EB%B6%80%EB%B6%84%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%EC%9D%B8%EC%A7%80%E2%80%85%ED%99%95%EC%9D%B8%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181843.%E2%80%85%EB%B6%80%EB%B6%84%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%EC%9D%B8%EC%A7%80%E2%80%85%ED%99%95%EC%9D%B8%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;32. 문자열로&amp;nbsp;변환&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;32-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수 n이 주어질 때, n을 문자열로 변환하여 return하도록 solution 함수를 완성해주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181845&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181845&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;32-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753964927134&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(n):
    answer = str(n)
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181845.%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%EB%A1%9C%E2%80%85%EB%B3%80%ED%99%98&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181845.%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%EB%A1%9C%E2%80%85%EB%B3%80%ED%99%98&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;33. 뒤에서&amp;nbsp;5등&amp;nbsp;위로&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;33-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수로 이루어진 리스트 num_list가 주어집니다. num_list에서 가장 작은 5개의 수를 제외한 수들을 오름차순으로 담은 리스트를 return하도록 solution 함수를 완성해주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181852&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181852&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;33-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753964959865&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(num_list):
    answer = sorted(num_list)[5:]
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181852.%E2%80%85%EB%92%A4%EC%97%90%EC%84%9C%E2%80%855%EB%93%B1%E2%80%85%EC%9C%84%EB%A1%9C&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181852.%E2%80%85%EB%92%A4%EC%97%90%EC%84%9C%E2%80%855%EB%93%B1%E2%80%85%EC%9C%84%EB%A1%9C&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;34.문자열&amp;nbsp;정수의&amp;nbsp;합&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;34-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;한 자리 정수로 이루어진 문자열 num_str이 주어질 때, 각 자리수의 합을 return하도록 solution 함수를 완성해주세요.&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181849&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181849&lt;/a&gt;&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;34-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753964985995&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(num_str):
    answer = sum([int(i) for i in num_str])
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181849.%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%E2%80%85%EC%A0%95%EC%88%98%EC%9D%98%E2%80%85%ED%95%A9&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181849.%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%E2%80%85%EC%A0%95%EC%88%98%EC%9D%98%E2%80%85%ED%95%A9&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;35. 문자열을&amp;nbsp;정수로&amp;nbsp;변환하기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;35-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;숫자로만 이루어진 문자열 n_str이 주어질 때, n_str을 정수로 변환하여 return하도록 solution 함수를 완성해주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181848&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181848&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;35-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753965017834&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(n_str):
    answer = int(n_str)
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181848.%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%EC%9D%84%E2%80%85%EC%A0%95%EC%88%98%EB%A1%9C%E2%80%85%EB%B3%80%ED%99%98%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181848.%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%EC%9D%84%E2%80%85%EC%A0%95%EC%88%98%EB%A1%9C%E2%80%85%EB%B3%80%ED%99%98%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;36. 뒤에서&amp;nbsp;5등까지&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;36-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수로 이루어진 리스트 num_list가 주어집니다. num_list에서 가장 작은 5개의 수를 오름차순으로 담은 리스트를 return하도록 solution 함수를 완성해주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181853&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181853&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;36-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753965051149&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(num_list):
    answer = sorted(num_list)[:5]
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181853.%E2%80%85%EB%92%A4%EC%97%90%EC%84%9C%E2%80%855%EB%93%B1%EA%B9%8C%EC%A7%80&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181853.%E2%80%85%EB%92%A4%EC%97%90%EC%84%9C%E2%80%855%EB%93%B1%EA%B9%8C%EC%A7%80&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;37. 배열의&amp;nbsp;길이에&amp;nbsp;따라&amp;nbsp;다른&amp;nbsp;연산하기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;37-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수 배열 arr과 정수 n이 매개변수로 주어집니다. arr의 길이가 홀수라면 arr의 모든 짝수 인덱스 위치에 n을 더한 배열을, arr의 길이가 짝수라면 arr의 모든 홀수 인덱스 위치에 n을 더한 배열을 return 하는 solution 함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181854&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181854&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;37-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753965081982&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(arr, n):
    for i in range(int(len(arr) % 2 == 0), len(arr),2):
        arr[i] += n
    answer = arr
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181854.%E2%80%85%EB%B0%B0%EC%97%B4%EC%9D%98%E2%80%85%EA%B8%B8%EC%9D%B4%EC%97%90%E2%80%85%EB%94%B0%EB%9D%BC%E2%80%85%EB%8B%A4%EB%A5%B8%E2%80%85%EC%97%B0%EC%82%B0%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181854.%E2%80%85%EB%B0%B0%EC%97%B4%EC%9D%98%E2%80%85%EA%B8%B8%EC%9D%B4%EC%97%90%E2%80%85%EB%94%B0%EB%9D%BC%E2%80%85%EB%8B%A4%EB%A5%B8%E2%80%85%EC%97%B0%EC%82%B0%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;38. 배열&amp;nbsp;비교하기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;38-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;이 문제에서 두 정수 배열의 대소관계를 다음과 같이 정의합니다.&lt;br /&gt;&lt;br /&gt;두 배열의 길이가 다르다면, 배열의 길이가 긴 쪽이 더 큽니다.&lt;br /&gt;배열의 길이가 같다면 각 배열에 있는 모든 원소의 합을 비교하여 다르다면 더 큰 쪽이 크고, 같다면 같습니다.&lt;br /&gt;&lt;br /&gt;두 정수 배열 arr1과 arr2가 주어질 때, 위에서 정의한 배열의 대소관계에 대하여 arr2가 크다면 -1, arr1이 크다면 1, 두 배열이 같다면 0을 return 하는 solution 함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181856&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181856&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;38-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753965141955&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(arr1, arr2):
    answer = 0
    if len(arr1) &amp;gt; len(arr2):
        answer = 1
    elif len(arr1) &amp;lt; len(arr2):
        answer = -1
    else:
        if sum(arr1) == sum(arr2):
            answer = 0
        elif sum(arr1) &amp;gt; sum(arr2):
            answer = 1
        elif sum(arr1) &amp;lt; sum(arr2):
            answer = -1
        else:
            raise ValueError
        
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181856.%E2%80%85%EB%B0%B0%EC%97%B4%E2%80%85%EB%B9%84%EA%B5%90%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181856.%E2%80%85%EB%B0%B0%EC%97%B4%E2%80%85%EB%B9%84%EA%B5%90%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;39. 주사위&amp;nbsp;게임&amp;nbsp;1&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;39-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;1부터 6까지 숫자가 적힌 주사위가 두 개 있습니다. 두 주사위를 굴렸을 때 나온  숫자를 각각 a, b라고 했을 때 얻는 점수는 다음과 같습니다.&lt;br /&gt;&lt;br /&gt;a와 b가 모두 홀수라면 a2 + b2 점을 얻습니다.&lt;br /&gt;a와 b 중 하나만 홀수라면 2 &amp;times; (a + b) 점을 얻습니다.&lt;br /&gt;a와 b 모두 홀수가 아니라면 |a - b| 점을 얻습니다.&lt;br /&gt;&lt;br /&gt;두 정수 a와 b가 매개변수로 주어질 때, 얻는 점수를 return 하는 solution 함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181839&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181839&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;39-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753965202440&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(a, b):
    answer = 0
    if a % 2 == 1 and b % 2 == 1:
        answer = a ** 2 + b ** 2
    elif a % 2 != 1 and b % 2 != 1:
        answer = abs(a - b)
    else:
        answer = 2 * (a + b)
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181839.%E2%80%85%EC%A3%BC%EC%82%AC%EC%9C%84%E2%80%85%EA%B2%8C%EC%9E%84%E2%80%851&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181839.%E2%80%85%EC%A3%BC%EC%82%AC%EC%9C%84%E2%80%85%EA%B2%8C%EC%9E%84%E2%80%851&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;40. ad&amp;nbsp;제거하기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;40-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;문자열 배열 strArr가 주어집니다. 배열 내의 문자열 중 &quot;ad&quot;라는 부분 문자열을 포함하고 있는 모든 문자열을 제거하고 남은 문자열을 순서를 유지하여 배열로 return 하는 solution 함수를 완성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181870&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181870&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;40-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753965234679&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(strArr):
    answer = [i for i in strArr if &quot;ad&quot; not in i]
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181870.%E2%80%85ad%E2%80%85%EC%A0%9C%EA%B1%B0%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181870.%E2%80%85ad%E2%80%85%EC%A0%9C%EA%B1%B0%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;41. 배열의&amp;nbsp;원소만큼&amp;nbsp;추가하기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;41-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;아무 원소도 들어있지 않은 빈 배열 X가 있습니다. 양의 정수 배열 arr가 매개변수로 주어질 때, arr의 앞에서부터 차례대로 원소를 보면서 원소가 a라면 X의 맨 뒤에 a를 a번 추가하는 일을 반복한 뒤의 배열 X를 return 하는 solution 함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아무&amp;nbsp;원소도&amp;nbsp;들어있지&amp;nbsp;않은&amp;nbsp;빈&amp;nbsp;배열&amp;nbsp;X가&amp;nbsp;있습니다.&amp;nbsp;양의&amp;nbsp;정수&amp;nbsp;배열&amp;nbsp;arr가&amp;nbsp;매개변수로&amp;nbsp;주어질&amp;nbsp;때,&amp;nbsp;arr의&amp;nbsp;앞에서부터&amp;nbsp;차례대로&amp;nbsp;원소를&amp;nbsp;보면서&amp;nbsp;원소가&amp;nbsp;a라면&amp;nbsp;X의&amp;nbsp;맨&amp;nbsp;뒤에&amp;nbsp;a를&amp;nbsp;a번&amp;nbsp;추가하는&amp;nbsp;일을&amp;nbsp;반복한&amp;nbsp;뒤의&amp;nbsp;배열&amp;nbsp;X를&amp;nbsp;return&amp;nbsp;하는&amp;nbsp;solution&amp;nbsp;함수를&amp;nbsp;작성해&amp;nbsp;주세요.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;41-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753965269613&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(arr):
    answer = [i for i in arr for _ in range(i)]
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181861.%E2%80%85%EB%B0%B0%EC%97%B4%EC%9D%98%E2%80%85%EC%9B%90%EC%86%8C%EB%A7%8C%ED%81%BC%E2%80%85%EC%B6%94%EA%B0%80%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181861.%E2%80%85%EB%B0%B0%EC%97%B4%EC%9D%98%E2%80%85%EC%9B%90%EC%86%8C%EB%A7%8C%ED%81%BC%E2%80%85%EC%B6%94%EA%B0%80%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;42. x&amp;nbsp;사이의&amp;nbsp;개수&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;42-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;문자열 myString이 주어집니다. myString을 문자 &quot;x&quot;를 기준으로 나눴을 때 나눠진 문자열 각각의 길이를 순서대로 저장한 배열을 return 하는 solution 함수를 완성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181867&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181867&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;42-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753965322869&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(myString):
    answer = [len(i) for i in myString.split('x')]
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181867.%E2%80%85x%E2%80%85%EC%82%AC%EC%9D%B4%EC%9D%98%E2%80%85%EA%B0%9C%EC%88%98&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181867.%E2%80%85x%E2%80%85%EC%82%AC%EC%9D%B4%EC%9D%98%E2%80%85%EA%B0%9C%EC%88%98&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;43. 홀수&amp;nbsp;vs&amp;nbsp;짝수&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;43-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수 리스트 num_list가 주어집니다. 가장 첫 번째 원소를 1번 원소라고 할 때, 홀수 번째 원소들의 합과 짝수 번째 원소들의 합 중 큰 값을 return 하도록 solution 함수를 완성해주세요. 두 값이 같을 경우 그 값을 return합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정수&amp;nbsp;리스트&amp;nbsp;num_list가&amp;nbsp;주어집니다.&amp;nbsp;가장&amp;nbsp;첫&amp;nbsp;번째&amp;nbsp;원소를&amp;nbsp;1번&amp;nbsp;원소라고&amp;nbsp;할&amp;nbsp;때,&amp;nbsp;홀수&amp;nbsp;번째&amp;nbsp;원소들의&amp;nbsp;합과&amp;nbsp;짝수&amp;nbsp;번째&amp;nbsp;원소들의&amp;nbsp;합&amp;nbsp;중&amp;nbsp;큰&amp;nbsp;값을&amp;nbsp;return&amp;nbsp;하도록&amp;nbsp;solution&amp;nbsp;함수를&amp;nbsp;완성해주세요.&amp;nbsp;두&amp;nbsp;값이&amp;nbsp;같을&amp;nbsp;경우&amp;nbsp;그&amp;nbsp;값을&amp;nbsp;return합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;43-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753965354800&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(num_list):
    answer = max(sum(num_list[::2]), sum(num_list[1::2]))
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181887.%E2%80%85%ED%99%80%EC%88%98%E2%80%85vs%E2%80%85%EC%A7%9D%EC%88%98&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181887.%E2%80%85%ED%99%80%EC%88%98%E2%80%85vs%E2%80%85%EC%A7%9D%EC%88%98&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;44. 공백으로&amp;nbsp;구분하기&amp;nbsp;2&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;44-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;단어가 공백 한 개 이상으로 구분되어 있는 문자열 my_string이 매개변수로 주어질 때, my_string에 나온 단어를 앞에서부터 순서대로 담은 문자열 배열을 return 하는 solution 함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181868&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181868&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;44-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753965383548&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(my_string):
    answer = [i for i in my_string.strip().split()]
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181868.%E2%80%85%EA%B3%B5%EB%B0%B1%EC%9C%BC%EB%A1%9C%E2%80%85%EA%B5%AC%EB%B6%84%ED%95%98%EA%B8%B0%E2%80%852&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181868.%E2%80%85%EA%B3%B5%EB%B0%B1%EC%9C%BC%EB%A1%9C%E2%80%85%EA%B5%AC%EB%B6%84%ED%95%98%EA%B8%B0%E2%80%852&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;45. rny_string&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;45-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;'m'과 &quot;rn&quot;이 모양이 비슷하게 생긴 점을 활용해 문자열에 장난을 하려고 합니다. 문자열 rny_string이 주어질 때, rny_string의 모든 'm'을 &quot;rn&quot;으로 바꾼 문자열을 return 하는 solution 함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181863&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181863&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;45-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753965414070&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(rny_string):
    answer = rny_string.replace(&quot;m&quot;, &quot;rn&quot;)
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181863.%E2%80%85rny%EF%BC%BFstring&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181863.%E2%80%85rny%EF%BC%BFstring&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;46. 공백으로&amp;nbsp;구분하기&amp;nbsp;1&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;46-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;단어가 공백 한 개로 구분되어 있는 문자열 my_string이 매개변수로 주어질 때, my_string에 나온 단어를 앞에서부터 순서대로 담은 문자열 배열을 return 하는 solution 함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181869&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181869&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;46-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753965449065&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(my_string):
    answer = my_string.split()
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181869.%E2%80%85%EA%B3%B5%EB%B0%B1%EC%9C%BC%EB%A1%9C%E2%80%85%EA%B5%AC%EB%B6%84%ED%95%98%EA%B8%B0%E2%80%851&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181869.%E2%80%85%EA%B3%B5%EB%B0%B1%EC%9C%BC%EB%A1%9C%E2%80%85%EA%B5%AC%EB%B6%84%ED%95%98%EA%B8%B0%E2%80%851&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;47. 배열에서&amp;nbsp;문자열&amp;nbsp;대소문자&amp;nbsp;변환하기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;47-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;문자열 배열 strArr가 주어집니다. 모든 원소가 알파벳으로만 이루어져 있을 때, 배열에서 홀수번째 인덱스의 문자열은 모든 문자를 대문자로, 짝수번째 인덱스의 문자열은 모든 문자를 소문자로 바꿔서 반환하는 solution 함수를 완성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181875&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181875&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;47-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753965478115&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(strArr):
    answer = [strArr[i].upper() if i % 2 else strArr[i].lower() for i in range(len(strArr))]
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181875.%E2%80%85%EB%B0%B0%EC%97%B4%EC%97%90%EC%84%9C%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%E2%80%85%EB%8C%80%EC%86%8C%EB%AC%B8%EC%9E%90%E2%80%85%EB%B3%80%ED%99%98%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181875.%E2%80%85%EB%B0%B0%EC%97%B4%EC%97%90%EC%84%9C%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%E2%80%85%EB%8C%80%EC%86%8C%EB%AC%B8%EC%9E%90%E2%80%85%EB%B3%80%ED%99%98%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;48. 간단한&amp;nbsp;식&amp;nbsp;계산하기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;48-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;문자열 binomial이 매개변수로 주어집니다. binomial은 &quot;a op b&quot; 형태의 이항식이고 a와 b는 음이 아닌 정수, op는 '+', '-', '*' 중 하나입니다. 주어진 식을 계산한 정수를 return 하는 solution 함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181865&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181865&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;48-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753965512020&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(binomial):
    answer = eval(binomial)
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181865.%E2%80%85%EA%B0%84%EB%8B%A8%ED%95%9C%E2%80%85%EC%8B%9D%E2%80%85%EA%B3%84%EC%82%B0%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181865.%E2%80%85%EA%B0%84%EB%8B%A8%ED%95%9C%E2%80%85%EC%8B%9D%E2%80%85%EA%B3%84%EC%82%B0%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;49. 소문자로&amp;nbsp;바꾸기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;49-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;알파벳으로 이루어진 문자열 myString이 주어집니다. 모든 알파벳을 소문자로 변환하여 return 하는 solution 함수를 완성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181876&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181876&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style2&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;49-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753965547871&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(myString):
    answer = myString.lower()
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181876.%E2%80%85%EC%86%8C%EB%AC%B8%EC%9E%90%EB%A1%9C%E2%80%85%EB%B0%94%EA%BE%B8%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181876.%E2%80%85%EC%86%8C%EB%AC%B8%EC%9E%90%EB%A1%9C%E2%80%85%EB%B0%94%EA%BE%B8%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;50. 가까운&amp;nbsp;1&amp;nbsp;찾기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;50-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수 배열 arr가 주어집니다. 이때 arr의 원소는 1 또는 0입니다. 정수 idx가 주어졌을 때, idx보다 크면서 배열의 값이 1인 가장 작은 인덱스를 찾아서 반환하는 solution 함수를 완성해 주세요. &lt;br /&gt;&lt;br /&gt;단, 만약 그러한 인덱스가 없다면 -1을 반환합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181898&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181898&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;50-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753965581434&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(arr, idx):
    answer = arr.index(1, idx) if 1 in arr[idx:] else -1
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181898.%E2%80%85%EA%B0%80%EA%B9%8C%EC%9A%B4%E2%80%851%E2%80%85%EC%B0%BE%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181898.%E2%80%85%EA%B0%80%EA%B9%8C%EC%9A%B4%E2%80%851%E2%80%85%EC%B0%BE%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;51. 더&amp;nbsp;크게&amp;nbsp;합치기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;51-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;연산 &amp;oplus;는 두 정수에 대한 연산으로 두 정수를 붙여서 쓴 값을 반환합니다. 예를 들면 다음과 같습니다. &lt;br /&gt;&lt;br /&gt;12 &amp;oplus; 3 = 123 &lt;br /&gt;3 &amp;oplus; 12 = 312 &lt;br /&gt;&lt;br /&gt;양의 정수 a와 b가 주어졌을 때, a &amp;oplus; b와 b &amp;oplus; a 중 더 큰 값을 return 하는 solution 함수를 완성해 주세요. &lt;br /&gt;단, a &amp;oplus; b와 b &amp;oplus; a가 같다면 a &amp;oplus; b를 return 합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181939&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181939&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;51-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753965643877&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(a, b):
    answer = max(int(str(a) + str(b)), int(str(b) + str(a)))
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181939.%E2%80%85%EB%8D%94%E2%80%85%ED%81%AC%EA%B2%8C%E2%80%85%ED%95%A9%EC%B9%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181939.%E2%80%85%EB%8D%94%E2%80%85%ED%81%AC%EA%B2%8C%E2%80%85%ED%95%A9%EC%B9%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;52. 원하는&amp;nbsp;문자열&amp;nbsp;찾기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;52-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;알파벳으로 이루어진 문자열 myString과 pat이 주어집니다. myString의 연속된 부분 문자열 중 pat이 존재하면 1을 그렇지 않으면 0을 return 하는 solution 함수를 완성해 주세요. &lt;br /&gt;&lt;br /&gt;단, 알파벳 대문자와 소문자는 구분하지 않습니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181878&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181878&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;52-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753965678073&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(myString, pat):
    answer = int(pat.lower() in myString.lower())
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181878.%E2%80%85%EC%9B%90%ED%95%98%EB%8A%94%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%E2%80%85%EC%B0%BE%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181878.%E2%80%85%EC%9B%90%ED%95%98%EB%8A%94%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%E2%80%85%EC%B0%BE%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;53. 배열&amp;nbsp;만들기&amp;nbsp;3&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;53-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수 배열 arr와 2개의 구간이 담긴 배열 intervals가 주어집니다. &lt;br /&gt;&lt;br /&gt;intervals는 항상 [[a1, b1], [a2, b2]]의 꼴로 주어지며 각 구간은 닫힌 구간입니다. &lt;br /&gt;닫힌 구간은 양 끝값과 그 사이의 값을 모두 포함하는 구간을 의미합니다. &lt;br /&gt;&lt;br /&gt;이때 배열 arr의 첫 번째 구간에 해당하는 배열과 두 번째 구간에 해당하는 배열을 앞뒤로 붙여 새로운 배열을 만들어 return 하는 solution 함수를 완성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181895&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181895&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;53-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753965722164&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(arr, intervals):
    answer = [i for s, e in intervals for i in arr[s:e+1]]
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181895.%E2%80%85%EB%B0%B0%EC%97%B4%E2%80%85%EB%A7%8C%EB%93%A4%EA%B8%B0%E2%80%853&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181895.%E2%80%85%EB%B0%B0%EC%97%B4%E2%80%85%EB%A7%8C%EB%93%A4%EA%B8%B0%E2%80%853&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;54. 첫&amp;nbsp;번째로&amp;nbsp;나오는&amp;nbsp;음수&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;54-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수 리스트 num_list가 주어질 때, 첫 번째로 나오는 음수의 인덱스를 return하도록 solution 함수를 완성해주세요. 음수가 없다면 -1을 return합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181896&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181896&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;54-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753965753672&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(num_list):
    answer = [idx for idx, i in enumerate(num_list) if i &amp;lt; 0]
    answer = answer[0] if answer else -1
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181896.%E2%80%85%EC%B2%AB%E2%80%85%EB%B2%88%EC%A7%B8%EB%A1%9C%E2%80%85%EB%82%98%EC%98%A4%EB%8A%94%E2%80%85%EC%9D%8C%EC%88%98&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181896.%E2%80%85%EC%B2%AB%E2%80%85%EB%B2%88%EC%A7%B8%EB%A1%9C%E2%80%85%EB%82%98%EC%98%A4%EB%8A%94%E2%80%85%EC%9D%8C%EC%88%98&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;55. 길이에&amp;nbsp;따른&amp;nbsp;연산&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;55-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수가 담긴 리스트 num_list가 주어질 때, 리스트의 길이가 11 이상이면 리스트에 있는 모든 원소의 합을 10 이하이면 모든 원소의 곱을 return하도록 solution 함수를 완성해주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181879&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181879&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;55-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753965786829&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import math
def solution(num_list):
    answer = sum(num_list) if len(num_list) &amp;gt;= 11 else math.prod(num_list)
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181879.%E2%80%85%EA%B8%B8%EC%9D%B4%EC%97%90%E2%80%85%EB%94%B0%EB%A5%B8%E2%80%85%EC%97%B0%EC%82%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181879.%E2%80%85%EA%B8%B8%EC%9D%B4%EC%97%90%E2%80%85%EB%94%B0%EB%A5%B8%E2%80%85%EC%97%B0%EC%82%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;56. 두&amp;nbsp;수의&amp;nbsp;연산값&amp;nbsp;비교하기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;56-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;연산 &amp;oplus;는 두 정수에 대한 연산으로 두 정수를 붙여서 쓴 값을 반환합니다. 예를 들면 다음과 같습니다. &lt;br /&gt;&lt;br /&gt;12 &amp;oplus; 3 = 123 &lt;br /&gt;3 &amp;oplus; 12 = 312 &lt;br /&gt;&lt;br /&gt;양의 정수 a와 b가 주어졌을 때, a &amp;oplus; b와 2 * a * b 중 더 큰 값을 return하는 solution 함수를 완성해 주세요. &lt;br /&gt;&lt;br /&gt;단, a &amp;oplus; b와 2 * a * b가 같으면 a &amp;oplus; b를 return 합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181938&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181938&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;56-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753965829445&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(a, b):
    answer = max(int(str(a) + str(b)), 2 * a * b)
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181938.%E2%80%85%EB%91%90%E2%80%85%EC%88%98%EC%9D%98%E2%80%85%EC%97%B0%EC%82%B0%EA%B0%92%E2%80%85%EB%B9%84%EA%B5%90%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181938.%E2%80%85%EB%91%90%E2%80%85%EC%88%98%EC%9D%98%E2%80%85%EC%97%B0%EC%82%B0%EA%B0%92%E2%80%85%EB%B9%84%EA%B5%90%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;57. 접미사인지&amp;nbsp;확인하기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;57-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;어떤 문자열에 대해서 접미사는 특정 인덱스부터 시작하는 문자열을 의미합니다. 예를 들어, &quot;banana&quot;의 모든 접미사는 &quot;banana&quot;, &quot;anana&quot;, &quot;nana&quot;, &quot;ana&quot;, &quot;na&quot;, &quot;a&quot;입니다. 문자열 my_string과 is_suffix가 주어질 때, is_suffix가 my_string의 접미사라면 1을, 아니면 0을 return 하는 solution 함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181908&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181908&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;57-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753965865084&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(my_string, is_suffix):
    answer = int(is_suffix in [my_string[i:] for i in range(len(my_string))])
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181908.%E2%80%85%EC%A0%91%EB%AF%B8%EC%82%AC%EC%9D%B8%EC%A7%80%E2%80%85%ED%99%95%EC%9D%B8%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181908.%E2%80%85%EC%A0%91%EB%AF%B8%EC%82%AC%EC%9D%B8%EC%A7%80%E2%80%85%ED%99%95%EC%9D%B8%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;58. 카운트&amp;nbsp;업&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;58-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수 start_num와 end_num가 주어질 때, start_num부터 end_num까지의 숫자를 차례로 담은 리스트를 return하도록 solution 함수를 완성해주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181920&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181920&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;58-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753965901752&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(start_num, end_num):
    answer = [i for i in range(start_num, end_num + 1)]
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181920.%E2%80%85%EC%B9%B4%EC%9A%B4%ED%8A%B8%E2%80%85%EC%97%85&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181920.%E2%80%85%EC%B9%B4%EC%9A%B4%ED%8A%B8%E2%80%85%EC%97%85&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;59. 문자열&amp;nbsp;곱하기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;59-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;문자열 my_string과 정수 k가 주어질 때, my_string을 k번 반복한 문자열을 return 하는 solution 함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181940&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181940&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;59-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753965934813&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(my_string, k):
    answer = my_string * k
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181940.%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%E2%80%85%EA%B3%B1%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181940.%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%E2%80%85%EA%B3%B1%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;60. n&amp;nbsp;번째&amp;nbsp;원소까지&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;60-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수 리스트 num_list와 정수 n이 주어질 때, num_list의 첫 번째 원소부터 n 번째 원소까지의 모든 원소를 담은 리스트를 return하도록 solution 함수를 완성해주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181889&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181889&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;60-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753965962473&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(num_list, n):
    answer = num_list[:n]
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181889.%E2%80%85n%E2%80%85%EB%B2%88%EC%A7%B8%E2%80%85%EC%9B%90%EC%86%8C%EA%B9%8C%EC%A7%80&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181889.%E2%80%85n%E2%80%85%EB%B2%88%EC%A7%B8%E2%80%85%EC%9B%90%EC%86%8C%EA%B9%8C%EC%A7%80&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;61. 문자열의&amp;nbsp;뒤의&amp;nbsp;n글자&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;61-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;문자열 my_string과 정수 n이 매개변수로 주어질 때, my_string의 뒤의 n글자로 이루어진 문자열을 return 하는 solution 함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181910&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181910&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;61-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753965992114&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(my_string, n):
    answer = my_string[-n:]
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181910.%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%EC%9D%98%E2%80%85%EB%92%A4%EC%9D%98%E2%80%85n%EA%B8%80%EC%9E%90&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181910.%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%EC%9D%98%E2%80%85%EB%92%A4%EC%9D%98%E2%80%85n%EA%B8%80%EC%9E%90&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;62. 홀짝&amp;nbsp;구분하기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;62-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;자연수 n이 입력으로 주어졌을 때 만약 n이 짝수이면 &quot;n is even&quot;을, 홀수이면 &quot;n is odd&quot;를 출력하는 코드를 작성해 보세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181944&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181944&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;62-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753966028467&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;a = int(input())
print(f&quot;{a} is odd&quot;) if a % 2 else print(f&quot;{a} is even&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181944.%E2%80%85%ED%99%80%EC%A7%9D%E2%80%85%EA%B5%AC%EB%B6%84%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181944.%E2%80%85%ED%99%80%EC%A7%9D%E2%80%85%EA%B5%AC%EB%B6%84%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;63. 홀짝에&amp;nbsp;따라&amp;nbsp;다른&amp;nbsp;값&amp;nbsp;반환하기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;63-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;양의 정수 n이 매개변수로 주어질 때, n이 홀수라면 n 이하의 홀수인 모든 양의 정수의 합을 return 하고 n이 짝수라면 n 이하의 짝수인 모든 양의 정수의 제곱의 합을 return 하는 solution 함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181935&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181935&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;63-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753966081950&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(n):
    numbers = [i for i in range(n + 1)]
    answer = sum(numbers[1:n + 1:2]) if n % 2 else sum(list(map(lambda x: x ** 2, numbers[:n + 1:2]))) 
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181935.%E2%80%85%ED%99%80%EC%A7%9D%EC%97%90%E2%80%85%EB%94%B0%EB%9D%BC%E2%80%85%EB%8B%A4%EB%A5%B8%E2%80%85%EA%B0%92%E2%80%85%EB%B0%98%ED%99%98%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181935.%E2%80%85%ED%99%80%EC%A7%9D%EC%97%90%E2%80%85%EB%94%B0%EB%9D%BC%E2%80%85%EB%8B%A4%EB%A5%B8%E2%80%85%EA%B0%92%E2%80%85%EB%B0%98%ED%99%98%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;64. 대문자로&amp;nbsp;바꾸기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;64-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;알파벳으로 이루어진 문자열 myString이 주어집니다. 모든 알파벳을 대문자로 변환하여 return 하는 solution 함수를 완성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181877&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181877&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;64-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753966136873&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(myString):
    answer = myString.upper()
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181877.%E2%80%85%EB%8C%80%EB%AC%B8%EC%9E%90%EB%A1%9C%E2%80%85%EB%B0%94%EA%BE%B8%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181877.%E2%80%85%EB%8C%80%EB%AC%B8%EC%9E%90%EB%A1%9C%E2%80%85%EB%B0%94%EA%BE%B8%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;65. n개&amp;nbsp;간격의&amp;nbsp;원소들&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;65-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수 리스트 num_list와 정수 n이 주어질 때, num_list의 첫 번째 원소부터 마지막 원소까지 n개 간격으로 저장되어있는 원소들을 차례로 담은 리스트를 return하도록 solution 함수를 완성해주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181888&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181888&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;65-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753966177192&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(num_list, n):
    answer = [num_list[i] for i in range(0, len(num_list), n)]
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181888.%E2%80%85n%EA%B0%9C%E2%80%85%EA%B0%84%EA%B2%A9%EC%9D%98%E2%80%85%EC%9B%90%EC%86%8C%EB%93%A4&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181888.%E2%80%85n%EA%B0%9C%E2%80%85%EA%B0%84%EA%B2%A9%EC%9D%98%E2%80%85%EC%9B%90%EC%86%8C%EB%93%A4&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;66. 이어&amp;nbsp;붙인&amp;nbsp;수&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;66-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수가 담긴 리스트 num_list가 주어집니다. num_list의 홀수만 순서대로 이어 붙인 수와 짝수만 순서대로 이어 붙인 수의 합을 return하도록 solution 함수를 완성해주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181928&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181928&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;66-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753966206362&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(num_list):
    a = int(''.join([str(i) for i in num_list if i % 2 == 1]))
    b = int(''.join([str(i) for i in num_list if i % 2 == 0]))
    answer = a + b
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181928.%E2%80%85%EC%9D%B4%EC%96%B4%E2%80%85%EB%B6%99%EC%9D%B8%E2%80%85%EC%88%98&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181928.%E2%80%85%EC%9D%B4%EC%96%B4%E2%80%85%EB%B6%99%EC%9D%B8%E2%80%85%EC%88%98&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;67. 할&amp;nbsp;일&amp;nbsp;목록&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;67-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;오늘 해야 할 일이 담긴 문자열 배열 todo_list와 각각의 일을 지금 마쳤는지를 나타내는 boolean 배열 finished가 매개변수로 주어질 때, todo_list에서 아직 마치지 못한 일들을 순서대로 담은 문자열 배열을 return 하는 solution 함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181885&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181885&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;67-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753966243158&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(todo_list, finished):
    answer = [todo_list[i] for i in range(len(todo_list)) if not finished[i]]
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181885.%E2%80%85%ED%95%A0%E2%80%85%EC%9D%BC%E2%80%85%EB%AA%A9%EB%A1%9D&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181885.%E2%80%85%ED%95%A0%E2%80%85%EC%9D%BC%E2%80%85%EB%AA%A9%EB%A1%9D&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;68. flag에&amp;nbsp;따라&amp;nbsp;다른&amp;nbsp;값&amp;nbsp;반환하기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;68-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;두 정수 a, b와 boolean 변수 flag가 매개변수로 주어질 때, flag가 true면 a + b를 false면 a - b를 return 하는 solution 함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181933&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181933&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;68-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753966274125&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(a, b, flag):
    answer = a + b if flag else a - b
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181933.%E2%80%85flag%EC%97%90%E2%80%85%EB%94%B0%EB%9D%BC%E2%80%85%EB%8B%A4%EB%A5%B8%E2%80%85%EA%B0%92%E2%80%85%EB%B0%98%ED%99%98%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181933.%E2%80%85flag%EC%97%90%E2%80%85%EB%94%B0%EB%9D%BC%E2%80%85%EB%8B%A4%EB%A5%B8%E2%80%85%EA%B0%92%E2%80%85%EB%B0%98%ED%99%98%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;69. 원소들의&amp;nbsp;곱과&amp;nbsp;합&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;69-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수가 담긴 리스트 num_list가 주어질 때, 모든 원소들의 곱이 모든 원소들의 합의 제곱보다 작으면 1을 크면 0을 return하도록 solution 함수를 완성해주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181929&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181929&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;69-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753966302942&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import math
def solution(num_list):
    answer = int(math.prod(num_list) &amp;lt; math.pow(sum(num_list), 2))
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181929.%E2%80%85%EC%9B%90%EC%86%8C%EB%93%A4%EC%9D%98%E2%80%85%EA%B3%B1%EA%B3%BC%E2%80%85%ED%95%A9&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181929.%E2%80%85%EC%9B%90%EC%86%8C%EB%93%A4%EC%9D%98%E2%80%85%EA%B3%B1%EA%B3%BC%E2%80%85%ED%95%A9&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;70. 문자열의&amp;nbsp;앞의&amp;nbsp;n글자&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;70-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;문자열 my_string과 정수 n이 매개변수로 주어질 때, my_string의 앞의 n글자로 이루어진 문자열을 return 하는 solution 함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181907&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181907&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;70-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753966333348&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(my_string, n):
    answer = my_string[:n]
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;71. 문자&amp;nbsp;리스트를&amp;nbsp;문자열로&amp;nbsp;변환하기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;71-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;문자들이 담겨있는 배열 arr가 주어집니다. arr의 원소들을 순서대로 이어 붙인 문자열을 return 하는 solution함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181941&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181941&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;71-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753966396139&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(arr):
    answer = ''.join(arr)
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181941.%E2%80%85%EB%AC%B8%EC%9E%90%E2%80%85%EB%A6%AC%EC%8A%A4%ED%8A%B8%EB%A5%BC%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%EB%A1%9C%E2%80%85%EB%B3%80%ED%99%98%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181941.%E2%80%85%EB%AC%B8%EC%9E%90%E2%80%85%EB%A6%AC%EC%8A%A4%ED%8A%B8%EB%A5%BC%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%EB%A1%9C%E2%80%85%EB%B3%80%ED%99%98%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;72. 문자열&amp;nbsp;붙여서&amp;nbsp;출력하기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;72-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;두 개의 문자열 str1, str2가 공백으로 구분되어 입력으로 주어집니다. &lt;br /&gt;입출력 예와 같이 str1과 str2을 이어서 출력하는 코드를 작성해 보세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181946&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181946&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;72-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753966429431&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;str1, str2 = input().strip().split(' ')
print(str1 + str2)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181946.%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%E2%80%85%EB%B6%99%EC%97%AC%EC%84%9C%E2%80%85%EC%B6%9C%EB%A0%A5%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181946.%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%E2%80%85%EB%B6%99%EC%97%AC%EC%84%9C%E2%80%85%EC%B6%9C%EB%A0%A5%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;73. n&amp;nbsp;번째&amp;nbsp;원소부터&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;73-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수 리스트 num_list와 정수 n이 주어질 때, n 번째 원소부터 마지막 원소까지의 모든 원소를 담은 리스트를 return하도록 solution 함수를 완성해주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181892&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181892&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;73-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753966467501&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(num_list, n):
    answer = num_list[n - 1:]
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181892.%E2%80%85n%E2%80%85%EB%B2%88%EC%A7%B8%E2%80%85%EC%9B%90%EC%86%8C%EB%B6%80%ED%84%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181892.%E2%80%85n%E2%80%85%EB%B2%88%EC%A7%B8%E2%80%85%EC%9B%90%EC%86%8C%EB%B6%80%ED%84%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;74. 공배수&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;74-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수 number와 n, m이 주어집니다. number가 n의 배수이면서 m의 배수이면 1을 아니라면 0을 return하도록 solution 함수를 완성해주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181936&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181936&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;74-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753966496375&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(number, n, m):
    answer = int(number % n == 0 and number % m == 0)
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181936.%E2%80%85%EA%B3%B5%EB%B0%B0%EC%88%98&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181936.%E2%80%85%EA%B3%B5%EB%B0%B0%EC%88%98&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;75. n의&amp;nbsp;배수&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;75-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수 num과 n이 매개 변수로 주어질 때, num이 n의 배수이면 1을 return n의 배수가 아니라면 0을 return하도록 solution 함수를 완성해주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181937&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181937&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;75-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753966528602&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(num, n):
    answer = int(not num % n)
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181937.%E2%80%85n%EC%9D%98%E2%80%85%EB%B0%B0%EC%88%98&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181937.%E2%80%85n%EC%9D%98%E2%80%85%EB%B0%B0%EC%88%98&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;76. 문자열&amp;nbsp;잘라서&amp;nbsp;정렬하기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;76-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;문자열 myString이 주어집니다. &quot;x&quot;를 기준으로 해당 문자열을 잘라내 배열을 만든 후 사전순으로 정렬한 배열을 return 하는 solution 함수를 완성해 주세요. &lt;br /&gt;&lt;br /&gt;단, 빈 문자열은 반환할 배열에 넣지 않습니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181866&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181866&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;76-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753966558583&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(myString):
    answer = sorted(myString.replace('x', ' ').strip().split())
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181866.%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%E2%80%85%EC%9E%98%EB%9D%BC%EC%84%9C%E2%80%85%EC%A0%95%EB%A0%AC%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181866.%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%E2%80%85%EC%9E%98%EB%9D%BC%EC%84%9C%E2%80%85%EC%A0%95%EB%A0%AC%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;77. 세로&amp;nbsp;읽기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;77-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;문자열 my_string과 두 정수 m, c가 주어집니다. my_string을 한 줄에 m 글자씩 가로로 적었을 때 왼쪽부터 세로로 c번째 열에 적힌 글자들을 문자열로 return 하는 solution 함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181904&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181904&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;77-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753966601538&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(my_string, m, c):
    answer = my_string[c-1::m]
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181904.%E2%80%85%EC%84%B8%EB%A1%9C%E2%80%85%EC%9D%BD%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181904.%E2%80%85%EC%84%B8%EB%A1%9C%E2%80%85%EC%9D%BD%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;78. 이차원&amp;nbsp;배열&amp;nbsp;대각선&amp;nbsp;순회하기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;78-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;2차원 정수 배열 board와 정수 k가 주어집니다.&lt;br /&gt;&lt;br /&gt;i + j &amp;lt;= k를 만족하는 모든 (i, j)에 대한 board[i][j]의 합을 return 하는 solution 함수를 완성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181829&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181829&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;78-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753966639292&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(board, k):
    answer = 0
    for i in range(len(board)):
        for j in range(len(board[0])):
            if i + j &amp;lt;= k:
                answer += board[i][j]
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181829.%E2%80%85%EC%9D%B4%EC%B0%A8%EC%9B%90%E2%80%85%EB%B0%B0%EC%97%B4%E2%80%85%EB%8C%80%EA%B0%81%EC%84%A0%E2%80%85%EC%88%9C%ED%9A%8C%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181829.%E2%80%85%EC%9D%B4%EC%B0%A8%EC%9B%90%E2%80%85%EB%B0%B0%EC%97%B4%E2%80%85%EB%8C%80%EA%B0%81%EC%84%A0%E2%80%85%EC%88%9C%ED%9A%8C%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;79. 문자열&amp;nbsp;섞기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;79-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;길이가 같은 두 문자열 str1과 str2가 주어집니다. &lt;br /&gt;&lt;br /&gt;두 문자열의 각 문자가 앞에서부터 서로 번갈아가면서 한 번씩 등장하는 문자열을 만들어 return 하는 solution 함수를 완성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181942&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181942&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;79-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753966676516&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(str1, str2):
    answer = ''.join(i for j in map(list, zip(str1, str2)) for i in j)
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181942.%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%E2%80%85%EC%84%9E%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181942.%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%E2%80%85%EC%84%9E%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;80. 9로&amp;nbsp;나눈&amp;nbsp;나머지&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;80-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;음이 아닌 정수를 9로 나눈 나머지는 그 정수의 각 자리 숫자의 합을 9로 나눈 나머지와 같은 것이 알려져 있습니다. &lt;br /&gt;&lt;br /&gt;이 사실을 이용하여 음이 아닌 정수가 문자열 number로 주어질 때, 이 정수를 9로 나눈 나머지를 return 하는 solution 함수를 작성해주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181914&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181914&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;80-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1753966708809&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(number):
    answer = sum([int(i) for i in number]) % 9
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181914.%E2%80%859%EB%A1%9C%E2%80%85%EB%82%98%EB%88%88%E2%80%85%EB%82%98%EB%A8%B8%EC%A7%80&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181914.%E2%80%859%EB%A1%9C%E2%80%85%EB%82%98%EB%88%88%E2%80%85%EB%82%98%EB%A8%B8%EC%A7%80&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;81. 날짜&amp;nbsp;비교하기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;81-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수 배열 date1과 date2가 주어집니다. 두 배열은 각각 날짜를 나타내며 [year, month, day] 꼴로 주어집니다. 각 배열에서 year는 연도를, month는 월을, day는 날짜를 나타냅니다. &lt;br /&gt;&lt;br /&gt;만약 date1이 date2보다 앞서는 날짜라면 1을, 아니면 0을 return 하는 solution 함수를 완성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181838&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181838&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;81-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754024213031&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(date1, date2):
    answer = int(int(''.join([str(i) for i in date1])) &amp;lt; int(''.join([str(i) for i in date2])))
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181838.%E2%80%85%EB%82%A0%EC%A7%9C%E2%80%85%EB%B9%84%EA%B5%90%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181838.%E2%80%85%EB%82%A0%EC%A7%9C%E2%80%85%EB%B9%84%EA%B5%90%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;82. 빈&amp;nbsp;배열에&amp;nbsp;추가,&amp;nbsp;삭제하기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;82-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;아무 원소도 들어있지 않은 빈 배열 X가 있습니다. 길이가 같은 정수 배열 arr과 boolean 배열 flag가 매개변수로 주어질 때, flag를 차례대로 순회하며 flag[i]가 true라면 X의 뒤에 arr[i]를 arr[i] &amp;times; 2 번 추가하고, flag[i]가 false라면 X에서 마지막 arr[i]개의 원소를 제거한 뒤 X를 return 하는 solution 함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181860&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181860&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;82-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754024262624&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(arr, flag):
    answer = []
    for i, f in zip(arr, flag):
        if f:
            answer.extend([i] * i * 2)
        else:
            answer = answer[:-i]
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181860.%E2%80%85%EB%B9%88%E2%80%85%EB%B0%B0%EC%97%B4%EC%97%90%E2%80%85%EC%B6%94%EA%B0%80%EF%BC%8C%E2%80%85%EC%82%AD%EC%A0%9C%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181860.%E2%80%85%EB%B9%88%E2%80%85%EB%B0%B0%EC%97%B4%EC%97%90%E2%80%85%EC%B6%94%EA%B0%80%EF%BC%8C%E2%80%85%EC%82%AD%EC%A0%9C%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;83. 수열과&amp;nbsp;구간&amp;nbsp;쿼리&amp;nbsp;1&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;83-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수 배열 arr와 2차원 정수 배열 queries이 주어집니다. &lt;br /&gt;&lt;br /&gt;queries의 원소는 각각 하나의 query를 나타내며, [s, e] 꼴입니다. 각 query마다 순서대로 s &amp;le; i &amp;le; e인 모든 i에 대해 arr[i]에 1을 더합니다. &lt;br /&gt;&lt;br /&gt;위 규칙에 따라 queries를 처리한 이후의 arr를 return 하는 solution 함수를 완성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181883&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181883&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;83-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754024309988&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(arr, queries):
    for s, e in queries:
        for i in range(s, e + 1):
            arr[i] += 1
    answer = arr
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181883.%E2%80%85%EC%88%98%EC%97%B4%EA%B3%BC%E2%80%85%EA%B5%AC%EA%B0%84%E2%80%85%EC%BF%BC%EB%A6%AC%E2%80%851&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181883.%E2%80%85%EC%88%98%EC%97%B4%EA%B3%BC%E2%80%85%EA%B5%AC%EA%B0%84%E2%80%85%EC%BF%BC%EB%A6%AC%E2%80%851&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;84. 글자&amp;nbsp;지우기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;84-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;문자열 my_string과 정수 배열 indices가 주어질 때, my_string에서 indices의 원소에 해당하는 인덱스의 글자를 지우고 이어 붙인 문자열을 return 하는 solution 함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181900&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181900&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;84-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754024351211&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(my_string, indices):
    my_string = list(my_string)
    for i in indices:
        my_string[i] = ''
    answer = ''.join(my_string)
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181900.%E2%80%85%EA%B8%80%EC%9E%90%E2%80%85%EC%A7%80%EC%9A%B0%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181900.%E2%80%85%EA%B8%80%EC%9E%90%E2%80%85%EC%A7%80%EC%9A%B0%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;85. 배열&amp;nbsp;만들기&amp;nbsp;5&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;85-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;문자열 배열 intStrs와 정수 k, s, l가 주어집니다. intStrs의 원소는 숫자로 이루어져 있습니다. &lt;br /&gt;&lt;br /&gt;배열 intStrs의 각 원소마다 s번 인덱스에서 시작하는 길이 l짜리 부분 문자열을 잘라내 정수로 변환합니다. 이때 변환한 정수값이 k보다 큰 값들을 담은 배열을 return 하는 solution 함수를 완성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181912&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181912&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;85-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754024394636&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(intStrs, k, s, l):
    answer = [int(i[s:s+l]) for i in intStrs if int(i[s:s+l]) &amp;gt; k]
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181912.%E2%80%85%EB%B0%B0%EC%97%B4%E2%80%85%EB%A7%8C%EB%93%A4%EA%B8%B0%E2%80%855&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181912.%E2%80%85%EB%B0%B0%EC%97%B4%E2%80%85%EB%A7%8C%EB%93%A4%EA%B8%B0%E2%80%855&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;86. 등차수열의&amp;nbsp;특정한&amp;nbsp;항만&amp;nbsp;더하기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;86-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;두 정수 a, d와 길이가 n인 boolean 배열 included가 주어집니다. 첫째항이 a, 공차가 d인 등차수열에서 included[i]가 i + 1항을 의미할 때, 이 등차수열의 1항부터 n항까지 included가 true인 항들만 더한 값을 return 하는 solution 함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181931&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181931&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;86-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754024428965&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(a, d, included):
    answer = sum([a + d * i for i in range(len(included)) if included[i]])
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181931.%E2%80%85%EB%93%B1%EC%B0%A8%EC%88%98%EC%97%B4%EC%9D%98%E2%80%85%ED%8A%B9%EC%A0%95%ED%95%9C%E2%80%85%ED%95%AD%EB%A7%8C%E2%80%85%EB%8D%94%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181931.%E2%80%85%EB%93%B1%EC%B0%A8%EC%88%98%EC%97%B4%EC%9D%98%E2%80%85%ED%8A%B9%EC%A0%95%ED%95%9C%E2%80%85%ED%95%AD%EB%A7%8C%E2%80%85%EB%8D%94%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;87. 1로&amp;nbsp;만들기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;87-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수가 있을 때, 짝수라면 반으로 나누고, 홀수라면 1을 뺀 뒤 반으로 나누면, 마지막엔 1이 됩니다. 예를 들어 10이 있다면 다음과 같은 과정으로 1이 됩니다.&lt;br /&gt;&lt;br /&gt;10 / 2 = 5 &lt;br /&gt;(5 - 1) / 2 = 2 &lt;br /&gt;2 / 2 = 1&lt;br /&gt;위와 같이 3번의 나누기 연산으로 1이 되었습니다.&lt;br /&gt;&lt;br /&gt;정수들이 담긴 리스트 num_list가 주어질 때, num_list의 모든 원소를 1로 만들기 위해서 필요한 나누기 연산의 횟수를 return하도록 solution 함수를 완성해주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181880&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181880&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;87-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754024494395&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(num_list):
    answer = 0
    for i in num_list:
        n = i
        while n != 1:
            if n % 2:
                n -= 1
                n //= 2
            else:
                n //= 2
            answer += 1
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181880.%E2%80%851%EB%A1%9C%E2%80%85%EB%A7%8C%EB%93%A4%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181880.%E2%80%851%EB%A1%9C%E2%80%85%EB%A7%8C%EB%93%A4%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;88. 문자열&amp;nbsp;뒤집기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;88-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;문자열 my_string과 정수 s, e가 매개변수로 주어질 때, my_string에서 인덱스 s부터 인덱스 e까지를 뒤집은 문자열을 return 하는 solution 함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181905&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181905&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;88-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754024530688&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(my_string, s, e):
    answer = my_string[:s] + my_string[s:e+1][::-1] + my_string[e+1:]
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181905.%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%E2%80%85%EB%92%A4%EC%A7%91%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181905.%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%E2%80%85%EB%92%A4%EC%A7%91%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;89. 특정&amp;nbsp;문자열로&amp;nbsp;끝나는&amp;nbsp;가장&amp;nbsp;긴&amp;nbsp;부분&amp;nbsp;문자열&amp;nbsp;찾기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;89-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;문자열 myString과 pat가 주어집니다. myString의 부분 문자열중 pat로 끝나는 가장 긴 부분 문자열을 찾아서 return 하는 solution 함수를 완성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181872&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181872&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;89-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754024566800&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(myString, pat):
    answer = myString[:myString.rfind(pat)] + pat
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181872.%E2%80%85%ED%8A%B9%EC%A0%95%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%EB%A1%9C%E2%80%85%EB%81%9D%EB%82%98%EB%8A%94%E2%80%85%EA%B0%80%EC%9E%A5%E2%80%85%EA%B8%B4%E2%80%85%EB%B6%80%EB%B6%84%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%E2%80%85%EC%B0%BE%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181872.%E2%80%85%ED%8A%B9%EC%A0%95%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%EB%A1%9C%E2%80%85%EB%81%9D%EB%82%98%EB%8A%94%E2%80%85%EA%B0%80%EC%9E%A5%E2%80%85%EA%B8%B4%E2%80%85%EB%B6%80%EB%B6%84%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%E2%80%85%EC%B0%BE%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;90. 문자열이&amp;nbsp;몇&amp;nbsp;번&amp;nbsp;등장하는지&amp;nbsp;세기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;90-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;문자열 myString과 pat이 주어집니다. myString에서 pat이 등장하는 횟수를 return 하는 solution 함수를 완성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181871&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181871&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;90-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754024600251&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(myString, pat):
    answer = 0
    i = 0
    while True:
        myString = myString[i:]
        if pat in myString:
            answer += 1
        else:
            break
        i = myString.find(pat) + 1
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181871.%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%EC%9D%B4%E2%80%85%EB%AA%87%E2%80%85%EB%B2%88%E2%80%85%EB%93%B1%EC%9E%A5%ED%95%98%EB%8A%94%EC%A7%80%E2%80%85%EC%84%B8%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181871.%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%EC%9D%B4%E2%80%85%EB%AA%87%E2%80%85%EB%B2%88%E2%80%85%EB%93%B1%EC%9E%A5%ED%95%98%EB%8A%94%EC%A7%80%E2%80%85%EC%84%B8%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;91. 수열과&amp;nbsp;구간&amp;nbsp;쿼리&amp;nbsp;3&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;91-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수 배열 arr와 2차원 정수 배열 queries이 주어집니다. queries의 원소는 각각 하나의 query를 나타내며, [i, j] 꼴입니다.&lt;br /&gt;&lt;br /&gt;각 query마다 순서대로 arr[i]의 값과 arr[j]의 값을 서로 바꿉니다. &lt;br /&gt;&lt;br /&gt;위 규칙에 따라 queries를 처리한 이후의 arr를 return 하는 solution 함수를 완성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181924&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181924&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;91-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754024659984&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(arr, queries):
    for a, b in queries:
        arr[a], arr[b] = arr[b], arr[a]
    answer = arr
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181924.%E2%80%85%EC%88%98%EC%97%B4%EA%B3%BC%E2%80%85%EA%B5%AC%EA%B0%84%E2%80%85%EC%BF%BC%EB%A6%AC%E2%80%853&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181924.%E2%80%85%EC%88%98%EC%97%B4%EA%B3%BC%E2%80%85%EA%B5%AC%EA%B0%84%E2%80%85%EC%BF%BC%EB%A6%AC%E2%80%853&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;92. 배열의&amp;nbsp;길이를&amp;nbsp;2의&amp;nbsp;거듭제곱으로&amp;nbsp;만들기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;92-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수 배열 arr이 매개변수로 주어집니다. arr의 길이가 2의 정수 거듭제곱이 되도록 arr 뒤에 정수 0을 추가하려고 합니다. arr에 최소한의 개수로 0을 추가한 배열을 return 하는 solution 함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181857&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181857&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;92-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754024696765&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import math
def solution(arr):
    l = math.log(len(arr), 2)
    length = 2 ** (int(l) + 1) - len(arr)
    answer = arr if l == int(l) else arr + [0 for _ in range(length)]
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181857.%E2%80%85%EB%B0%B0%EC%97%B4%EC%9D%98%E2%80%85%EA%B8%B8%EC%9D%B4%EB%A5%BC%E2%80%852%EC%9D%98%E2%80%85%EA%B1%B0%EB%93%AD%EC%A0%9C%EA%B3%B1%EC%9C%BC%EB%A1%9C%E2%80%85%EB%A7%8C%EB%93%A4%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181857.%E2%80%85%EB%B0%B0%EC%97%B4%EC%9D%98%E2%80%85%EA%B8%B8%EC%9D%B4%EB%A5%BC%E2%80%852%EC%9D%98%E2%80%85%EA%B1%B0%EB%93%AD%EC%A0%9C%EA%B3%B1%EC%9C%BC%EB%A1%9C%E2%80%85%EB%A7%8C%EB%93%A4%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;93. 문자열&amp;nbsp;묶기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;93-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;문자열 배열 strArr이 주어집니다. strArr의 원소들을 길이가 같은 문자열들끼리 그룹으로 묶었을 때 가장 개수가 많은 그룹의 크기를 return 하는 solution 함수를 완성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181855&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181855&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;93-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754024742925&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(strArr):
    answer = dict()
    for s in strArr:
        answer[len(s)] = answer.get(len(s), 0) + 1
    answer = max(answer.values())
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181855.%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%E2%80%85%EB%AC%B6%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181855.%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%E2%80%85%EB%AC%B6%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;94. 세&amp;nbsp;개의&amp;nbsp;구분자&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;94-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;임의의 문자열이 주어졌을 때 문자 &quot;a&quot;, &quot;b&quot;, &quot;c&quot;를 구분자로 사용해 문자열을 나누고자 합니다.&lt;br /&gt;&lt;br /&gt;예를 들어 주어진 문자열이 &quot;baconlettucetomato&quot;라면 나눠진 문자열 목록은 [&quot;onlettu&quot;, &quot;etom&quot;, &quot;to&quot;] 가 됩니다.&lt;br /&gt;&lt;br /&gt;문자열 myStr이 주어졌을 때 위 예시와 같이 &quot;a&quot;, &quot;b&quot;, &quot;c&quot;를 사용해 나눠진 문자열을 순서대로 저장한 배열을 return 하는 solution 함수를 완성해 주세요.&lt;br /&gt;&lt;br /&gt;단, 두 구분자 사이에 다른 문자가 없을 경우에는 아무것도 저장하지 않으며, return할 배열이 빈 배열이라면 [&quot;EMPTY&quot;]를 return 합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181862&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181862&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;94-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754024813722&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(myStr):
    answer = myStr.replace('a', ' ').replace('b', ' ').replace('c', ' ').strip().split()
    answer = answer if answer else [&quot;EMPTY&quot;]
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181862.%E2%80%85%EC%84%B8%E2%80%85%EA%B0%9C%EC%9D%98%E2%80%85%EA%B5%AC%EB%B6%84%EC%9E%90&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181862.%E2%80%85%EC%84%B8%E2%80%85%EA%B0%9C%EC%9D%98%E2%80%85%EA%B5%AC%EB%B6%84%EC%9E%90&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;95. 2의&amp;nbsp;영역&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;95-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수 배열 arr가 주어집니다. 배열 안의 2가 모두 포함된 가장 작은 연속된 부분 배열을 return 하는 solution 함수를 완성해 주세요. &lt;br /&gt;&lt;br /&gt;단, arr에 2가 없는 경우 [-1]을 return 합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181894&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181894&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;95-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754024856375&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(arr):
    answer = arr[arr.index(2):len(arr) - arr[::-1].index(2)] if 2 in arr else [-1]
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181894.%E2%80%852%EC%9D%98%E2%80%85%EC%98%81%EC%97%AD&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181894.%E2%80%852%EC%9D%98%E2%80%85%EC%98%81%EC%97%AD&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;96. 리스트&amp;nbsp;자르기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;96-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수 n과 정수 3개가 담긴 리스트 slicer 그리고 정수 여러 개가 담긴 리스트 num_list가 주어집니다. slicer에 담긴 정수를 차례대로 a, b, c라고 할 때, n에 따라 다음과 같이 num_list를 슬라이싱 하려고 합니다.&lt;br /&gt;&lt;br /&gt;n = 1 : num_list의 0번 인덱스부터 b번 인덱스까지 &lt;br /&gt;n = 2 : num_list의 a번 인덱스부터 마지막 인덱스까지 &lt;br /&gt;n = 3 : num_list의 a번 인덱스부터 b번 인덱스까지 &lt;br /&gt;n = 4 : num_list의 a번 인덱스부터 b번 인덱스까지 c 간격으로&lt;br /&gt;&lt;br /&gt;올바르게 슬라이싱한 리스트를 return하도록 solution 함수를 완성해주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181897&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181897&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;96-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754024913137&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(n, slicer, num_list):
    a, b, c = slicer
    if n == 1:
        num_list = num_list[:b + 1]
    elif n == 2:
        num_list = num_list[a:]
    elif n == 3:
        num_list = num_list[a:b + 1]
    elif n == 4:
        num_list = num_list[a:b + 1:c]
    answer = num_list
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181897.%E2%80%85%EB%A6%AC%EC%8A%A4%ED%8A%B8%E2%80%85%EC%9E%90%EB%A5%B4%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181897.%E2%80%85%EB%A6%AC%EC%8A%A4%ED%8A%B8%E2%80%85%EC%9E%90%EB%A5%B4%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;97. 문자열&amp;nbsp;반복해서&amp;nbsp;출력하기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;97-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;문자열 str과 정수 n이 주어집니다. &lt;br /&gt;str이 n번 반복된 문자열을 만들어 출력하는 코드를 작성해 보세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181950&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181950&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;97-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754024952779&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;str, n = input().strip().split(' ')
n = int(n)
print(str * n)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181950.%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%E2%80%85%EB%B0%98%EB%B3%B5%ED%95%B4%EC%84%9C%E2%80%85%EC%B6%9C%EB%A0%A5%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181950.%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%E2%80%85%EB%B0%98%EB%B3%B5%ED%95%B4%EC%84%9C%E2%80%85%EC%B6%9C%EB%A0%A5%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;98. 수열과&amp;nbsp;구간&amp;nbsp;쿼리&amp;nbsp;4&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;98-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수 배열 arr와 2차원 정수 배열 queries이 주어집니다. queries의 원소는 각각 하나의 query를 나타내며, [s, e, k] 꼴입니다.&lt;br /&gt;&lt;br /&gt;각 query마다 순서대로 s &amp;le; i &amp;le; e인 모든 i에 대해 i가 k의 배수이면 arr[i]에 1을 더합니다.&lt;br /&gt;&lt;br /&gt;위 규칙에 따라 queries를 처리한 이후의 arr를 return 하는 solution 함수를 완성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181922&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181922&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;98-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754025010002&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(arr, queries):
    for s, e, k in queries:
        for i in range(s, e + 1):
            if i % k == 0:
                arr[i] += 1
    answer = arr
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181922.%E2%80%85%EC%88%98%EC%97%B4%EA%B3%BC%E2%80%85%EA%B5%AC%EA%B0%84%E2%80%85%EC%BF%BC%EB%A6%AC%E2%80%854&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181922.%E2%80%85%EC%88%98%EC%97%B4%EA%B3%BC%E2%80%85%EA%B5%AC%EA%B0%84%E2%80%85%EC%BF%BC%EB%A6%AC%E2%80%854&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;99. qr&amp;nbsp;code&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;99-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;두 정수 q, r과 문자열 code가 주어질 때, code의 각 인덱스를 q로 나누었을 때 나머지가 r인 위치의 문자를 앞에서부터 순서대로 이어 붙인 문자열을 return 하는 solution 함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181903&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181903&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;99-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754025047495&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(q, r, code):
    answer = code[r::q]
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181903.%E2%80%85qr%E2%80%85code&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181903.%E2%80%85qr%E2%80%85code&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;100. 조건에&amp;nbsp;맞게&amp;nbsp;수열&amp;nbsp;변환하기&amp;nbsp;2&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;100-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수 배열 arr가 주어집니다. arr의 각 원소에 대해 값이 50보다 크거나 같은 짝수라면 2로 나누고, 50보다 작은 홀수라면 2를 곱하고 다시 1을 더합니다.&lt;br /&gt;&lt;br /&gt;이러한 작업을 x번 반복한 결과인 배열을 arr(x)라고 표현했을 때, arr(x) = arr(x + 1)인 x가 항상 존재합니다. 이러한 x 중 가장 작은 값을 return 하는 solution 함수를 완성해 주세요.&lt;br /&gt;&lt;br /&gt;단, 두 배열에 대한 &quot;=&quot;는 두 배열의 크기가 서로 같으며, 같은 인덱스의 원소가 각각 서로 같음을 의미합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181881&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181881&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;100-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754025097821&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(arr):
    for x in range(len(arr)):
        temp_list = arr.copy()
        for idx, i in enumerate(arr):
            if i &amp;gt;= 50 and i % 2 == 0:
                arr[idx] = i // 2
            elif 50 &amp;gt; i and i % 2 == 1:
                arr[idx] = i * 2 + 1
        if temp_list == arr:
            answer = x
            break

    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181881.%E2%80%85%EC%A1%B0%EA%B1%B4%EC%97%90%E2%80%85%EB%A7%9E%EA%B2%8C%E2%80%85%EC%88%98%EC%97%B4%E2%80%85%EB%B3%80%ED%99%98%ED%95%98%EA%B8%B0%E2%80%852&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181881.%E2%80%85%EC%A1%B0%EA%B1%B4%EC%97%90%E2%80%85%EB%A7%9E%EA%B2%8C%E2%80%85%EC%88%98%EC%97%B4%E2%80%85%EB%B3%80%ED%99%98%ED%95%98%EA%B8%B0%E2%80%852&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;101. 간단한&amp;nbsp;논리&amp;nbsp;연산&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;101-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;boolean 변수 x1, x2, x3, x4가 매개변수로 주어질 때, 다음의 식의 true/false를 return 하는 solution 함수를 작성해 주세요.&lt;br /&gt;(x1 &amp;or; x2) &amp;and; (x3 &amp;or; x4)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181917&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181917&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;101-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754025169337&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(x1, x2, x3, x4):
    answer = (x1 | x2) &amp;amp; (x3 | x4)
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181917.%E2%80%85%EA%B0%84%EB%8B%A8%ED%95%9C%E2%80%85%EB%85%BC%EB%A6%AC%E2%80%85%EC%97%B0%EC%82%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181917.%E2%80%85%EA%B0%84%EB%8B%A8%ED%95%9C%E2%80%85%EB%85%BC%EB%A6%AC%E2%80%85%EC%97%B0%EC%82%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;102. 커피&amp;nbsp;심부름&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;102-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;팀의 막내인 철수는 아메리카노와 카페 라테만 판매하는 카페에서 팀원들의 커피를 사려고 합니다. 아메리카노와 카페 라테의 가격은 차가운 것과 뜨거운 것 상관없이 각각 4500, 5000원입니다. 각 팀원에게 마실 메뉴를 적어달라고 하였고, 그 중에서 메뉴만 적은 팀원의 것은 차가운 것으로 통일하고 &quot;아무거나&quot;를 적은 팀원의 것은 차가운 아메리카노로 통일하기로 하였습니다.&lt;br /&gt;&lt;br /&gt;각 직원이 적은 메뉴가 문자열 배열 order로 주어질 때, 카페에서 결제하게 될 금액을 return 하는 solution 함수를 작성해주세요. order의 원소는 아래의 것들만 들어오고, 각각의 의미는 다음과 같습니다.&lt;br /&gt;&lt;br /&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;order의&amp;nbsp;원소&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;의미&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&quot;iceamericano&quot;,&amp;nbsp;&quot;americanoice&quot;&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;차가운&amp;nbsp;아메리카노&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&quot;hotamericano&quot;,&amp;nbsp;&quot;americanohot&quot;&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;따뜻한&amp;nbsp;아메리카노&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&quot;icecafelatte&quot;,&amp;nbsp;&quot;cafelatteice&quot;&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;차가운&amp;nbsp;카페&amp;nbsp;라테&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&quot;hotcafelatte&quot;,&amp;nbsp;&quot;cafelattehot&quot;&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;따뜻한&amp;nbsp;카페&amp;nbsp;라테&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&quot;americano&quot;&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;아메리카노&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&quot;cafelatte&quot;&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;카페&amp;nbsp;라테&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&quot;anything&quot;&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;아무거나&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181837&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181837&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;102-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754025328476&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(order):
    order = ''.join(order)
    answer = (order.count(&quot;americano&quot;) + order.count(&quot;anything&quot;)) * 4500 + order.count(&quot;cafelatte&quot;) * 5000
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181837.%E2%80%85%EC%BB%A4%ED%94%BC%E2%80%85%EC%8B%AC%EB%B6%80%EB%A6%84&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181837.%E2%80%85%EC%BB%A4%ED%94%BC%E2%80%85%EC%8B%AC%EB%B6%80%EB%A6%84&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;103. 특수문자&amp;nbsp;출력하기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;103-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;다음과 같이 출력하도록 코드를 작성해 주세요.&lt;br /&gt;!@#$%^&amp;amp;*(\'&quot;&amp;lt;&amp;gt;?:;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181948&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181948&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;103-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754025373414&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;print(r'!@#$%^&amp;amp;*(\'&quot;&amp;lt;&amp;gt;?:;')&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181948.%E2%80%85%ED%8A%B9%EC%88%98%EB%AC%B8%EC%9E%90%E2%80%85%EC%B6%9C%EB%A0%A5%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181948.%E2%80%85%ED%8A%B9%EC%88%98%EB%AC%B8%EC%9E%90%E2%80%85%EC%B6%9C%EB%A0%A5%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;104. 배열&amp;nbsp;만들기&amp;nbsp;6&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;104-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;0과 1로만 이루어진 정수 배열 arr가 주어집니다. arr를 이용해 새로운 배열 stk을 만드려고 합니다.&lt;br /&gt;&lt;br /&gt;i의 초기값을 0으로 설정하고 i가 arr의 길이보다 작으면 다음을 반복합니다.&lt;br /&gt;&lt;br /&gt;만약 stk이 빈 배열이라면 arr[i]를 stk에 추가하고 i에 1을 더합니다.&lt;br /&gt;stk에 원소가 있고, stk의 마지막 원소가 arr[i]와 같으면 stk의 마지막 원소를 stk에서 제거하고 i에 1을 더합니다.&lt;br /&gt;stk에 원소가 있는데 stk의 마지막 원소가 arr[i]와 다르면 stk의 맨 마지막에 arr[i]를 추가하고 i에 1을 더합니다.&lt;br /&gt;&lt;br /&gt;위 작업을 마친 후 만들어진 stk을 return 하는 solution 함수를 완성해 주세요.&lt;br /&gt;&lt;br /&gt;단, 만약 빈 배열을 return 해야한다면 [-1]을 return 합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181859&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181859&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;104-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754025460476&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(arr):
    answer = []
    i = 0
    for idx in range(len(arr)):
        if answer == []:
            answer.append(arr[i])
            i += 1
        elif answer and answer[-1] == arr[i]:
            answer.pop()
            i += 1
        elif answer and answer[-1] != arr[i]:
            answer.append(arr[i])
            i += 1
    answer = answer if answer else [-1]
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181859.%E2%80%85%EB%B0%B0%EC%97%B4%E2%80%85%EB%A7%8C%EB%93%A4%EA%B8%B0%E2%80%856&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181859.%E2%80%85%EB%B0%B0%EC%97%B4%E2%80%85%EB%A7%8C%EB%93%A4%EA%B8%B0%E2%80%856&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;105. 왼쪽&amp;nbsp;오른쪽&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;105-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;문자열 리스트 str_list에는 &quot;u&quot;, &quot;d&quot;, &quot;l&quot;, &quot;r&quot; 네 개의 문자열이 여러 개 저장되어 있습니다. str_list에서 &quot;l&quot;과 &quot;r&quot; 중 먼저 나오는 문자열이 &quot;l&quot;이라면 해당 문자열을 기준으로 왼쪽에 있는 문자열들을 순서대로 담은 리스트를, 먼저 나오는 문자열이 &quot;r&quot;이라면 해당 문자열을 기준으로 오른쪽에 있는 문자열들을 순서대로 담은 리스트를 return하도록 solution 함수를 완성해주세요. &quot;l&quot;이나 &quot;r&quot;이 없다면 빈 리스트를 return합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181890&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181890&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;105-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754025495561&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(str_list):
    answer = []
    for idx, i in enumerate(str_list):
        if i == 'l':
            answer = str_list[:idx]
            break
        elif i == 'r':
            answer = str_list[idx + 1:]
            break
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181890.%E2%80%85%EC%99%BC%EC%AA%BD%E2%80%85%EC%98%A4%EB%A5%B8%EC%AA%BD&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181890.%E2%80%85%EC%99%BC%EC%AA%BD%E2%80%85%EC%98%A4%EB%A5%B8%EC%AA%BD&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;106. 문자&amp;nbsp;개수&amp;nbsp;세기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;106-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;알파벳 대소문자로만 이루어진 문자열 my_string이 주어질 때, my_string에서 'A'의 개수, my_string에서 'B'의 개수,..., my_string에서 'Z'의 개수, my_string에서 'a'의 개수, my_string에서 'b'의 개수,..., my_string에서 'z'의 개수를 순서대로 담은 길이 52의 정수 배열을 return 하는 solution 함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181902&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181902&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;106-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754025537673&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(my_string):
    answer = {chr(base + d): 0 for base in [65, 97] for d in range(26)}
    for i in my_string:
        answer[i] += 1
    answer = list(answer.values())
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181902.%E2%80%85%EB%AC%B8%EC%9E%90%E2%80%85%EA%B0%9C%EC%88%98%E2%80%85%EC%84%B8%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181902.%E2%80%85%EB%AC%B8%EC%9E%90%E2%80%85%EA%B0%9C%EC%88%98%E2%80%85%EC%84%B8%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;107. 배열&amp;nbsp;만들기&amp;nbsp;4&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;107-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수 배열 arr가 주어집니다. arr를 이용해 새로운 배열 stk를 만드려고 합니다. &lt;br /&gt;&lt;br /&gt;변수 i를 만들어 초기값을 0으로 설정한 후 i가 arr의 길이보다 작으면 다음 작업을 반복합니다. &lt;br /&gt;&lt;br /&gt;만약 stk가 빈 배열이라면 arr[i]를 stk에 추가하고 i에 1을 더합니다. &lt;br /&gt;stk에 원소가 있고, stk의 마지막 원소가 arr[i]보다 작으면 arr[i]를 stk의 뒤에 추가하고 i에 1을 더합니다. &lt;br /&gt;stk에 원소가 있는데 stk의 마지막 원소가 arr[i]보다 크거나 같으면 stk의 마지막 원소를 stk에서 제거합니다. &lt;br /&gt;&lt;br /&gt;위 작업을 마친 후 만들어진 stk를 return 하는 solution 함수를 완성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181918&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181918&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;107-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754025600739&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(arr):
    i = 0
    stk = []
    while i &amp;lt; len(arr):
        if stk == []:
            stk.append(arr[i])
            i += 1
        elif stk and stk[-1] &amp;lt; arr[i]:
            stk.append(arr[i])
            i += 1
        elif stk and stk[-1] &amp;gt;= arr[i]:
            stk.pop()
    answer = stk
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181918.%E2%80%85%EB%B0%B0%EC%97%B4%E2%80%85%EB%A7%8C%EB%93%A4%EA%B8%B0%E2%80%854&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181918.%E2%80%85%EB%B0%B0%EC%97%B4%E2%80%85%EB%A7%8C%EB%93%A4%EA%B8%B0%E2%80%854&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;108. 조건&amp;nbsp;문자열&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;108-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;문자열에 따라 다음과 같이 두 수의 크기를 비교하려고 합니다. &lt;br /&gt;&lt;br /&gt;두 수가 n과 m이라면 &lt;br /&gt;&quot;&amp;gt;&quot;, &quot;=&quot; : n &amp;gt;= m &lt;br /&gt;&quot;&amp;lt;&quot;, &quot;=&quot; : n &amp;lt;= m &lt;br /&gt;&quot;&amp;gt;&quot;, &quot;!&quot; : n &amp;gt; m &lt;br /&gt;&quot;&amp;lt;&quot;, &quot;!&quot; : n &amp;lt; m &lt;br /&gt;&lt;br /&gt;두 문자열 ineq와 eq가 주어집니다. ineq는 &quot;&amp;lt;&quot;와 &quot;&amp;gt;&quot;중 하나고, eq는 &quot;=&quot;와 &quot;!&quot;중 하나입니다. 그리고 두 정수 n과 m이 주어질 때, n과 m이 ineq와 eq의 조건에 맞으면 1을 아니면 0을 return하도록 solution 함수를 완성해주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181934&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181934&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;108-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754025668152&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(ineq, eq, n, m):
    answer = int(eval(f&quot;{n}{ineq + eq.replace('!', '')}{m}&quot;))
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181934.%E2%80%85%EC%A1%B0%EA%B1%B4%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181934.%E2%80%85%EC%A1%B0%EA%B1%B4%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;109. 문자열&amp;nbsp;여러&amp;nbsp;번&amp;nbsp;뒤집기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;109-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;문자열 my_string과 이차원 정수 배열 queries가 매개변수로 주어집니다. queries의 원소는 [s, e] 형태로, my_string의 인덱스 s부터 인덱스 e까지를 뒤집으라는 의미입니다. my_string에 queries의 명령을 순서대로 처리한 후의 문자열을 return 하는 solution 함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181913&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181913&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;109-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754025710500&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(my_string, queries):
    for s, e in queries:
        my_string = f&quot;{my_string[:s]}{my_string[s:e+1][::-1]}{my_string[e+1:]}&quot;
    answer = my_string
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181913.%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%E2%80%85%EC%97%AC%EB%9F%AC%E2%80%85%EB%B2%88%E2%80%85%EB%92%A4%EC%A7%91%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181913.%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%E2%80%85%EC%97%AC%EB%9F%AC%E2%80%85%EB%B2%88%E2%80%85%EB%92%A4%EC%A7%91%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;110. 두&amp;nbsp;수의&amp;nbsp;합&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;110-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;0 이상의 두 정수가 문자열 a, b로 주어질 때, a + b의 값을 문자열로 return 하는 solution 함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181846&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181846&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;110-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754025749710&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(a, b):
    answer = str(int(a) + int(b))
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181846.%E2%80%85%EB%91%90%E2%80%85%EC%88%98%EC%9D%98%E2%80%85%ED%95%A9&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181846.%E2%80%85%EB%91%90%E2%80%85%EC%88%98%EC%9D%98%E2%80%85%ED%95%A9&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;111. 수열과&amp;nbsp;구간&amp;nbsp;쿼리&amp;nbsp;2&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;111-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수 배열 arr와 2차원 정수 배열 queries이 주어집니다. queries의 원소는 각각 하나의 query를 나타내며, [s, e, k] 꼴입니다. &lt;br /&gt;&lt;br /&gt;각 query마다 순서대로 s &amp;le; i &amp;le; e인 모든 i에 대해 k보다 크면서 가장 작은 arr[i]를 찾습니다. &lt;br /&gt;&lt;br /&gt;각 쿼리의 순서에 맞게 답을 저장한 배열을 반환하는 solution 함수를 완성해 주세요. 단, 특정 쿼리의 답이 존재하지 않으면 -1을 저장합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181923&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181923&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;111-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754025800703&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(arr, queries):
    answer = [min(a) if a else -1 for a in [[arr[i] for i in range(s, e + 1) if arr[i] &amp;gt; k] for s, e, k in queries]]
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181923.%E2%80%85%EC%88%98%EC%97%B4%EA%B3%BC%E2%80%85%EA%B5%AC%EA%B0%84%E2%80%85%EC%BF%BC%EB%A6%AC%E2%80%852&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181923.%E2%80%85%EC%88%98%EC%97%B4%EA%B3%BC%E2%80%85%EA%B5%AC%EA%B0%84%E2%80%85%EC%BF%BC%EB%A6%AC%E2%80%852&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;112. 무작위로&amp;nbsp;K개의&amp;nbsp;수&amp;nbsp;뽑기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;112-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;랜덤으로 서로 다른 k개의 수를 저장한 배열을 만드려고 합니다. 적절한 방법이 떠오르지 않기 때문에 일정한 범위 내에서 무작위로 수를 뽑은 후, 지금까지 나온적이 없는 수이면 배열 맨 뒤에 추가하는 방식으로 만들기로 합니다.&lt;br /&gt;&lt;br /&gt;이미 어떤 수가 무작위로 주어질지 알고 있다고 가정하고, 실제 만들어질 길이 k의 배열을 예상해봅시다.&lt;br /&gt;&lt;br /&gt;정수 배열 arr가 주어집니다. 문제에서의 무작위의 수는 arr에 저장된 순서대로 주어질 예정이라고 했을 때, 완성될 배열을 return 하는 solution 함수를 완성해 주세요. &lt;br /&gt;&lt;br /&gt;단, 완성될 배열의 길이가 k보다 작으면 나머지 값을 전부 -1로 채워서 return 합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181858&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181858&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;112-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754025865672&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(arr, k):
    r = []
    for i in arr:
        if i not in r:
            r.append(i)
    answer = r + [-1 for _ in range(k - len(r))] if len(r) &amp;lt; k else r[:k]
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181858.%E2%80%85%EB%AC%B4%EC%9E%91%EC%9C%84%EB%A1%9C%E2%80%85K%EA%B0%9C%EC%9D%98%E2%80%85%EC%88%98%E2%80%85%EB%BD%91%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181858.%E2%80%85%EB%AC%B4%EC%9E%91%EC%9C%84%EB%A1%9C%E2%80%85K%EA%B0%9C%EC%9D%98%E2%80%85%EC%88%98%E2%80%85%EB%BD%91%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;113. 그림&amp;nbsp;확대&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;113-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;직사각형 형태의 그림 파일이 있고, 이 그림 파일은 1 &amp;times; 1 크기의 정사각형 크기의 픽셀로 이루어져 있습니다. 이 그림 파일을 나타낸 문자열 배열 picture과 정수 k가 매개변수로 주어질 때, 이 그림 파일을 가로 세로로 k배 늘린 그림 파일을 나타내도록 문자열 배열을 return 하는 solution 함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181836&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181836&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;113-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754025912289&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(picture, k):
    answer = [''.join([l * k for l in p]) for p in picture for _ in range(k)]
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181836.%E2%80%85%EA%B7%B8%EB%A6%BC%E2%80%85%ED%99%95%EB%8C%80&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181836.%E2%80%85%EA%B7%B8%EB%A6%BC%E2%80%85%ED%99%95%EB%8C%80&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;114. a와&amp;nbsp;b&amp;nbsp;출력하기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;114-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수 a와 b가 주어집니다. 각 수를 입력받아 입출력 예와 같은 형식으로 출력하는 코드를 작성해 보세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181951&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181951&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;114-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754025961806&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;a, b = map(int, input().strip().split(' '))
print(f&quot;a = {a}\nb = {b}&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181951.%E2%80%85a%EC%99%80%E2%80%85b%E2%80%85%EC%B6%9C%EB%A0%A5%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181951.%E2%80%85a%EC%99%80%E2%80%85b%E2%80%85%EC%B6%9C%EB%A0%A5%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;115. 문자열&amp;nbsp;겹쳐쓰기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;115-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;문자열 my_string, overwrite_string과 정수 s가 주어집니다. 문자열 my_string의 인덱스 s부터 overwrite_string의 길이만큼을 문자열 overwrite_string으로 바꾼 문자열을 return 하는 solution 함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181943&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181943&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;115-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754026007069&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(my_string, overwrite_string, s):
    answer = f&quot;{my_string[:s]}{overwrite_string}{my_string[s+len(overwrite_string):]}&quot;
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181943.%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%E2%80%85%EA%B2%B9%EC%B3%90%EC%93%B0%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181943.%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%E2%80%85%EA%B2%B9%EC%B3%90%EC%93%B0%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;116. 정사각형으로&amp;nbsp;만들기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;116-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;이차원 정수 배열 arr이 매개변수로 주어집니다. arr의 행의 수가 더 많다면 열의 수가 행의 수와 같아지도록 각 행의 끝에 0을 추가하고, 열의 수가 더 많다면 행의 수가 열의 수와 같아지도록 각 열의 끝에 0을 추가한 이차원 배열을 return 하는 solution 함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181830&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181830&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;116-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754026041705&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(arr):
    m = max(len(arr), len(arr[0]))
    answer = [[0 for _ in range(m)] for _ in range(m)]
    for i in range(len(arr)):
        for j in range(len(arr[0])):
            answer[i][j] = arr[i][j]
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181830.%E2%80%85%EC%A0%95%EC%82%AC%EA%B0%81%ED%98%95%EC%9C%BC%EB%A1%9C%E2%80%85%EB%A7%8C%EB%93%A4%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181830.%E2%80%85%EC%A0%95%EC%82%AC%EA%B0%81%ED%98%95%EC%9C%BC%EB%A1%9C%E2%80%85%EB%A7%8C%EB%93%A4%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;117. 전국&amp;nbsp;대회&amp;nbsp;선발&amp;nbsp;고사&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;117-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;0번부터 n - 1번까지 n명의 학생 중 3명을 선발하는 전국 대회 선발 고사를 보았습니다. 등수가 높은 3명을 선발해야 하지만, 개인 사정으로 전국 대회에 참여하지 못하는 학생들이 있어 참여가 가능한 학생 중 등수가 높은 3명을 선발하기로 했습니다.&lt;br /&gt;&lt;br /&gt;각 학생들의 선발 고사 등수를 담은 정수 배열 rank와 전국 대회 참여 가능 여부가 담긴 boolean 배열 attendance가 매개변수로 주어집니다. 전국 대회에 선발된 학생 번호들을 등수가 높은 순서대로 각각 a, b, c번이라고 할 때 10000 &amp;times; a + 100 &amp;times; b + c를 return 하는 solution 함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181851&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181851&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;117-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754026083691&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(rank, attendance):
    a, b, c = [rank.index(r) for r in sorted([i for idx, i in enumerate(rank) if attendance[idx]])][:3]
    answer = a * 10000 + b * 100 + c
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181851.%E2%80%85%EC%A0%84%EA%B5%AD%E2%80%85%EB%8C%80%ED%9A%8C%E2%80%85%EC%84%A0%EB%B0%9C%E2%80%85%EA%B3%A0%EC%82%AC&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181851.%E2%80%85%EC%A0%84%EA%B5%AD%E2%80%85%EB%8C%80%ED%9A%8C%E2%80%85%EC%84%A0%EB%B0%9C%E2%80%85%EA%B3%A0%EC%82%AC&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;118. 대소문자&amp;nbsp;바꿔서&amp;nbsp;출력하기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;118-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;영어 알파벳으로 이루어진 문자열 str이 주어집니다. 각 알파벳을 대문자는 소문자로 소문자는 대문자로 변환해서 출력하는 코드를 작성해 보세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181949&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181949&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;118-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754026118717&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;str = input()
print(''.join([i.lower() if ord(i) &amp;lt;= 90 else i.upper() for i in str]))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181949.%E2%80%85%EB%8C%80%EC%86%8C%EB%AC%B8%EC%9E%90%E2%80%85%EB%B0%94%EA%BF%94%EC%84%9C%E2%80%85%EC%B6%9C%EB%A0%A5%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181949.%E2%80%85%EB%8C%80%EC%86%8C%EB%AC%B8%EC%9E%90%E2%80%85%EB%B0%94%EA%BF%94%EC%84%9C%E2%80%85%EC%B6%9C%EB%A0%A5%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;119. 배열&amp;nbsp;만들기&amp;nbsp;2&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;119-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수 l과 r이 주어졌을 때, l 이상 r이하의 정수 중에서 숫자 &quot;0&quot;과 &quot;5&quot;로만 이루어진 모든 정수를 오름차순으로 저장한 배열을 return 하는 solution 함수를 완성해 주세요. &lt;br /&gt;&lt;br /&gt;만약 그러한 정수가 없다면, -1이 담긴 배열을 return 합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181921&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181921&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;119-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754026161459&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(l, r):
    answer = [i for i in range(l, r + 1) if set(str(i)) &amp;lt;= {'0', '5'}] or [-1]
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181921.%E2%80%85%EB%B0%B0%EC%97%B4%E2%80%85%EB%A7%8C%EB%93%A4%EA%B8%B0%E2%80%852&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181921.%E2%80%85%EB%B0%B0%EC%97%B4%E2%80%85%EB%A7%8C%EB%93%A4%EA%B8%B0%E2%80%852&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;120. 코드&amp;nbsp;처리하기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;120-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;문자열 code가 주어집니다.&lt;br /&gt;&lt;br /&gt;code를 앞에서부터 읽으면서 만약 문자가 &quot;1&quot;이면 mode를 바꿉니다. mode에 따라 code를 읽어가면서 문자열 ret을 만들어냅니다. &lt;br /&gt;&lt;br /&gt;mode는 0과 1이 있으며, idx를 0 부터 code의 길이 - 1 까지 1씩 키워나가면서 code[idx]의 값에 따라 다음과 같이 행동합니다. &lt;br /&gt;&lt;br /&gt;mode가 0일 때 &lt;br /&gt;code[idx]가 &quot;1&quot;이 아니면 idx가 짝수일 때만 ret의 맨 뒤에 code[idx]를 추가합니다. &lt;br /&gt;code[idx]가 &quot;1&quot;이면 mode를 0에서 1로 바꿉니다. &lt;br /&gt;&lt;br /&gt;mode가 1일 때 &lt;br /&gt;code[idx]가 &quot;1&quot;이 아니면 idx가 홀수일 때만 ret의 맨 뒤에 code[idx]를 추가합니다. &lt;br /&gt;code[idx]가 &quot;1&quot;이면 mode를 1에서 0으로 바꿉니다. &lt;br /&gt;&lt;br /&gt;문자열 code를 통해 만들어진 문자열 ret를 return 하는 solution 함수를 완성해 주세요. &lt;br /&gt;단, 시작할 때 mode는 0이며, return 하려는 ret가 만약 빈 문자열이라면 대신 &quot;EMPTY&quot;를 return 합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181932&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181932&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;120-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754026277462&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(code):
    mode = 0
    answer = ''
    for idx in range(len(code)):

        if mode == 0:

            if code[idx] != '1' and idx % 2 == 0:
                answer += code[idx]
            elif code[idx] == '1':
                mode = 1

        elif mode == 1:
            if code[idx] != '1' and idx % 2 == 1:
                answer += code[idx]
            elif code[idx] == '1':
                mode = 0
    answer = answer if answer else &quot;EMPTY&quot;
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181932.%E2%80%85%EC%BD%94%EB%93%9C%E2%80%85%EC%B2%98%EB%A6%AC%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181932.%E2%80%85%EC%BD%94%EB%93%9C%E2%80%85%EC%B2%98%EB%A6%AC%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;121. 배열&amp;nbsp;조각하기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;121-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;정수 배열 arr와 query가 주어집니다.&lt;br /&gt;&lt;br /&gt;query를 순회하면서 다음 작업을 반복합니다. &lt;br /&gt;짝수 인덱스에서는 arr에서 query[i]번 인덱스를 제외하고 배열의 query[i]번 인덱스 뒷부분을 잘라서 버립니다. &lt;br /&gt;홀수 인덱스에서는 arr에서 query[i]번 인덱스는 제외하고 배열의 query[i]번 인덱스 앞부분을 잘라서 버립니다.&lt;br /&gt;&lt;br /&gt;위 작업을 마친 후 남은 arr의 부분 배열을 return 하는 solution 함수를 완성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181893&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181893&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;121-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754026347290&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(arr, query):
    for idx, i in enumerate(query):
        if idx % 2 == 0:
            arr = arr[:i+1]
        else:
            arr = arr[i:]
    answer = arr
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181893.%E2%80%85%EB%B0%B0%EC%97%B4%E2%80%85%EC%A1%B0%EA%B0%81%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181893.%E2%80%85%EB%B0%B0%EC%97%B4%E2%80%85%EC%A1%B0%EA%B0%81%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;122. 문자열&amp;nbsp;출력하기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;122-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;문자열 str이 주어질 때, str을 출력하는 코드를 작성해 보세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181952&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181952&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;122-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754026387226&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;str = input()
print(str)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181952.%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%E2%80%85%EC%B6%9C%EB%A0%A5%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181952.%E2%80%85%EB%AC%B8%EC%9E%90%EC%97%B4%E2%80%85%EC%B6%9C%EB%A0%A5%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;123. 주사위&amp;nbsp;게임&amp;nbsp;3&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;123-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;1부터 6까지 숫자가 적힌 주사위가 네 개 있습니다. 네 주사위를 굴렸을 때 나온 숫자에 따라 다음과 같은 점수를 얻습니다.&lt;br /&gt;&lt;br /&gt;네 주사위에서 나온 숫자가 모두 p로 같다면 1111 &amp;times; p점을 얻습니다. &lt;br /&gt;세 주사위에서 나온 숫자가 p로 같고 나머지 다른 주사위에서 나온 숫자가 q(p &amp;ne; q)라면 (10 &amp;times; p + q)2 점을 얻습니다. &lt;br /&gt;주사위가 두 개씩 같은 값이 나오고, 나온 숫자를 각각 p, q(p &amp;ne; q)라고 한다면 (p + q) &amp;times; |p - q|점을 얻습니다. &lt;br /&gt;어느 두 주사위에서 나온 숫자가 p로 같고 나머지 두 주사위에서 나온 숫자가 각각 p와 다른 q, r(q &amp;ne; r)이라면 q &amp;times; r점을 얻습니다. &lt;br /&gt;네 주사위에 적힌 숫자가 모두 다르다면 나온 숫자 중 가장 작은 숫자 만큼의 점수를 얻습니다. &lt;br /&gt;&lt;br /&gt;네 주사위를 굴렸을 때 나온 숫자가 정수 매개변수 a, b, c, d로 주어질 때, 얻는 점수를 return 하는 solution 함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181916&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181916&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;123-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754026477091&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(a, b, c, d):
    answer = 0
    dice = {}
    for i in [a, b, c, d]:
        dice[i] = dice.get(i, 0) + 1
    l = len(dice.keys())
    if l == 1:
        p = dice.popitem()[0]
        answer = 1111 * p
    elif l == 2:
        if 3 in dice.values():
            r_dice = dict(map(reversed, dice.items()))
            p, q = r_dice[3], r_dice[1]
            answer = (10 * p + q) ** 2
        else:
            p, q = dice.popitem()[0], dice.popitem()[0]
            answer = (p + q) * abs(p - q)
    elif l == 3:
        q, r = [i[0] for i in dice.items() if i[1] == 1]
        answer = q * r
    elif l == 4:
        answer = min(dice.keys())

    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181916.%E2%80%85%EC%A3%BC%EC%82%AC%EC%9C%84%E2%80%85%EA%B2%8C%EC%9E%84%E2%80%853&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181916.%E2%80%85%EC%A3%BC%EC%82%AC%EC%9C%84%E2%80%85%EA%B2%8C%EC%9E%84%E2%80%853&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;124. 정수를&amp;nbsp;나선형으로&amp;nbsp;배치하기&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;124-1. 문제 설명&lt;/h3&gt;
&lt;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;양의 정수 n이 매개변수로 주어집니다. n &amp;times; n 배열에 1부터 n2 까지 정수를 인덱스 [0][0]부터 시계방향 나선형으로 배치한 이차원 배열을 return 하는 solution 함수를 작성해 주세요.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181832&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181832&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;124-2. 풀이 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1754026531566&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(n):
    answer = [[0 for _ in range(n)] for _ in range(n)]
    col, row = 0, 0
    arrow = [[0, 1], [1, 0], [0, -1], [-1, 0]]
    arr_idx = 0

    for i in range(1, n ** 2 + 1):

        answer[col][row] = i

        next_col = col + arrow[arr_idx][0]
        next_row = row + arrow[arr_idx][1]

        if 0 &amp;lt;= next_col &amp;lt; n and 0 &amp;lt;= next_row &amp;lt; n and answer[next_col][next_row] == 0:
            pass
        else:
            arr_idx = (arr_idx + 1) % 4

        col += arrow[arr_idx][0]
        row += arrow[arr_idx][1]
        
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181832.%E2%80%85%EC%A0%95%EC%88%98%EB%A5%BC%E2%80%85%EB%82%98%EC%84%A0%ED%98%95%EC%9C%BC%EB%A1%9C%E2%80%85%EB%B0%B0%EC%B9%98%ED%95%98%EA%B8%B0&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/kj0on/BaekjoonHub/tree/main/Python3/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4/0/181832.%E2%80%85%EC%A0%95%EC%88%98%EB%A5%BC%E2%80%85%EB%82%98%EC%84%A0%ED%98%95%EC%9C%BC%EB%A1%9C%E2%80%85%EB%B0%B0%EC%B9%98%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Python/Coding Test</category>
      <category>Programmers</category>
      <category>Python</category>
      <category>코딩 테스트 기초</category>
      <category>파이썬</category>
      <category>프로그래머스</category>
      <author>kj0on</author>
      <guid isPermaLink="true">https://kj0on.tistory.com/40</guid>
      <comments>https://kj0on.tistory.com/40#entry40comment</comments>
      <pubDate>Fri, 11 Jul 2025 19:20:48 +0900</pubDate>
    </item>
  </channel>
</rss>