<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>CSAPP Chapter 3 on Jiho Kim</title><link>https://blog.wlgh7407.com/posts/books/csapp/chapter-03-machine-level-representation/</link><description>Recent content in CSAPP Chapter 3 on Jiho Kim</description><generator>Hugo -- gohugo.io</generator><language>en</language><copyright>© 2026 Jiho Kim</copyright><lastBuildDate>Sat, 24 Jan 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.wlgh7407.com/posts/books/csapp/chapter-03-machine-level-representation/index.xml" rel="self" type="application/rss+xml"/><item><title>CSAPP 3.12 Summary</title><link>https://blog.wlgh7407.com/posts/books/csapp/chapter-03-machine-level-representation/260124_til_csapp-3.12/</link><pubDate>Sat, 24 Jan 2026 00:00:00 +0000</pubDate><guid>https://blog.wlgh7407.com/posts/books/csapp/chapter-03-machine-level-representation/260124_til_csapp-3.12/</guid><description>&lt;h2 class="relative group"&gt;📝 상세 정리
 &lt;div id="-상세-정리" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#-%ec%83%81%ec%84%b8-%ec%a0%95%eb%a6%ac" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;그동안 C언어의 추상화 층을 살펴봤다!
&lt;ul&gt;
&lt;li&gt;5장에서 컴파일러의 특성을 알면, 효율적인 코드에 대해 더 잘 이해하게 될 것이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;프로그램이 다른 메모리 영역에 데이터를 저장하는 방법을 알게 되었다.
&lt;ul&gt;
&lt;li&gt;12장에서 런타임 스택에 프로그램 변수가 있는지, 동적 할당된 데이터 구조에 있는지, 글로벌 프로그램 데이터 일부에있는지 더 공부할 것이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;프로그램은 명령어들의 시퀀스로 표현되며, 명령어 각각은 단일 동작을 수행한다.&lt;/li&gt;
&lt;li&gt;컴파일러는 상이한 데이터 구조를 생성/동작/제어 등 여러가지를 위해 다수의 명령어를 사용한다.&lt;/li&gt;
&lt;li&gt;C에서는 경계 검사가 부족하기 때문에 버퍼 오버플로우를 조심해야 한다.&lt;/li&gt;
&lt;li&gt;C++은 C와 유사하게 컴파일되지만, 자바는 완전히 다른 방식으로 작동한다.
&lt;ul&gt;
&lt;li&gt;자바 바이트코드라고 불리는 특별한 바이너리 코드가 된다.&lt;/li&gt;
&lt;li&gt;이는 가상 머신을 위한 머신 레벨의 프로그램이지만, 하드웨어에서 직접 구현되지 않는다.
&lt;ul&gt;
&lt;li&gt;인터프리터가 이를 시뮬레이션하여 바이트 코드를 처리한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;이는 같은 코드가 여러 기계에서 실행될 수 있지만, 우리가 고려한 C같은 경우는 x86-64 기계에서만 실행된다는 단점이 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 class="relative group"&gt;❔질문 사항
 &lt;div id="질문-사항" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%a7%88%eb%ac%b8-%ec%82%ac%ed%95%ad" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 class="relative group"&gt;🔗 참고 자료
 &lt;div id="-참고-자료" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#-%ec%b0%b8%ea%b3%a0-%ec%9e%90%eb%a3%8c" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>CSAPP Attack Lab</title><link>https://blog.wlgh7407.com/posts/books/csapp/chapter-03-machine-level-representation/260124_til_csapp-attack-lab/</link><pubDate>Sat, 24 Jan 2026 00:00:00 +0000</pubDate><guid>https://blog.wlgh7407.com/posts/books/csapp/chapter-03-machine-level-representation/260124_til_csapp-attack-lab/</guid><description>&lt;h2 class="relative group"&gt;📝 상세 정리
 &lt;div id="-상세-정리" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#-%ec%83%81%ec%84%b8-%ec%a0%95%eb%a6%ac" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;

&lt;h3 class="relative group"&gt;Part I: Code Injection Attacks
 &lt;div id="part-i-code-injection-attacks" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#part-i-code-injection-attacks" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;새로운 코드를 인젝션하지는 않고, string을 직접 박아넣어서 존재하는 프로시져로 꽂을것이다.
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;test&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; val;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	val &lt;span style="color:#f92672"&gt;=&lt;/span&gt; getbuf();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	printf(&lt;span style="color:#e6db74"&gt;&amp;#34;No exploit. Getbuf returned 0x%x&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\n&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;, val);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;위와 같은 코드에 직접 넣을 예정&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 class="relative group"&gt;Level 1
 &lt;div id="level-1" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#level-1" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;void touch1() 함수로 가게 만들자.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 00000000004017a8 &amp;lt;getbuf&amp;gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 4017a8:	48 83 ec 28 	sub $0x28,%rsp
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 4017ac:	48 89 e7 	mov %rsp,%rdi
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 4017af:	e8 8c 02 00 00 	call 401a40 &amp;lt;Gets&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 4017b4:	b8 01 00 00 00 	mov $0x1,%eax
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 4017b9:	48 83 c4 28 	add $0x28,%rsp
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 4017bd:	c3 	ret
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 4017be:	90 	nop
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 4017bf:	90 	nop&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;getbuf 함수를 보니, 0x28 = 40바이트를 스택메모리에 할당하고, get함수를 부른다.&lt;/p&gt;</description></item><item><title>CSAPP 3.10 Combining Control and Data in Machine-Level Programs</title><link>https://blog.wlgh7407.com/posts/books/csapp/chapter-03-machine-level-representation/260123_til_csapp-3.10/</link><pubDate>Fri, 23 Jan 2026 00:00:00 +0000</pubDate><guid>https://blog.wlgh7407.com/posts/books/csapp/chapter-03-machine-level-representation/260123_til_csapp-3.10/</guid><description>&lt;h2 class="relative group"&gt;📝 상세 정리
 &lt;div id="-상세-정리" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#-%ec%83%81%ec%84%b8-%ec%a0%95%eb%a6%ac" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;데이터와 머신레벨 코드를 지금까지 따로 살펴보았다
&lt;ul&gt;
&lt;li&gt;이제부터는 합쳐서 확인해보자&lt;/li&gt;
&lt;li&gt;이건 포인터 단위로 공부할 것이다.&lt;/li&gt;
&lt;li&gt;버퍼 오버플로우도 연구해보자&lt;/li&gt;
&lt;li&gt;스택 저장량이 실행마다 다를 수 있는 경우? 를 확인해보자&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3.10.1 Understanding Pointers
&lt;ul&gt;
&lt;li&gt;모든 포인터는 associated type이 있다.
&lt;ul&gt;
&lt;li&gt;어떤 object를 가리키는지 나타내는 것&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;객체가 타입 T를 갖는 경우, T의 포인터는 타입 *T를 갖는다.
&lt;ul&gt;
&lt;li&gt;타입 *T의 포인터는 **T이다.&lt;/li&gt;
&lt;li&gt;그냥 * 라고 쓰면 일반 포인터를 반환한다.&lt;/li&gt;
&lt;li&gt;이 포인터 유형은 기계코드의 일부는 아니지만, 오류를 방지하기 위해 C가 제공하는 추상화임&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;모든 포인터의 값은 일부 객체의 주소를 가리킨다
&lt;ul&gt;
&lt;li&gt;NULL(0)일때 빼고 (아무데도 가리키지 않음)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;포인터는 &amp;amp;연산으로 생성된다
&lt;ul&gt;
&lt;li&gt;기계코드에서는 주로 leaq로 나타내지더라&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;포인터는 *연산으로 역참조된다.
&lt;ul&gt;
&lt;li&gt;지정된 주소로 저장하거나 지정된 주소로부터 검색한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;배열과 포인터는 밀접한 관련이 있다.
&lt;ul&gt;
&lt;li&gt;배열의 이름은 마치 포인터 변수인 것처럼 참조된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;포인터를 캐스팅할 때, 그 유형은 바뀌지만 그값은 바뀌지 않는다.
&lt;ul&gt;
&lt;li&gt;하지만 스케일링을 바꿀 순 있다&lt;/li&gt;
&lt;li&gt;EX) p가 char * 유형의 포인터인 경우
&lt;ul&gt;
&lt;li&gt;(int *) p+7은 p+28을 계산하고, (int *) (p+7)은 p+7을 계산한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;포인터는 함수를 가리킬 수도 있다.
&lt;ul&gt;
&lt;li&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fun&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; x, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;p);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; (&lt;span style="color:#f92672"&gt;*&lt;/span&gt;fp)(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;); fp &lt;span style="color:#f92672"&gt;=&lt;/span&gt; fun;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; y &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; result &lt;span style="color:#f92672"&gt;=&lt;/span&gt; fp(&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;, &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;y);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;함수 포인터의 값은 함수의 기계코드 표현에서 첫번째 명령어의 주소이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3.10.2 Life in the Real World: Using the GDB Debugger
&lt;ul&gt;
&lt;li&gt;gdb는 GNU 디버거&lt;/li&gt;
&lt;li&gt;ㅋㅋ bomb lab 풀면서 이미 써봤지롱&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3.10.3 Out-of-Bounds Memory References and Buffer Overflow
&lt;ul&gt;
&lt;li&gt;C는 배열 참조에 대한 임의의 경계 검사를 수행하지 않는다
&lt;ul&gt;
&lt;li&gt;저장된 레지스터값&lt;/li&gt;
&lt;li&gt;반환 주소와 같은 상태 정보&lt;/li&gt;
&lt;li&gt;로컬 변수&lt;/li&gt;
&lt;li&gt;이 모든것들이 스택에 저장된다&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;근데 이건 심각한 프로그램 오류를 초래할 수도 있다!!
&lt;ul&gt;
&lt;li&gt;Out of bound 배열 요소에 작성하는것으로!&lt;/li&gt;
&lt;li&gt;그리고 이상태로 레지스터를 다시 가져오거나 ret 명령어를 하려고 하면 터질 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;이런걸 Buffer Overflow라고 한다.
&lt;ul&gt;
&lt;li&gt;문자열을 유지하기 위해 스택 상에 일부 문자 배열에이 할당되지만, 그 크기가 넘어간 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;char&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;gets&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;char&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;s){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; c;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;char&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;dest &lt;span style="color:#f92672"&gt;=&lt;/span&gt; s;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt;((c &lt;span style="color:#f92672"&gt;=&lt;/span&gt; getchar()) &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;\n&amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; c &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; EOF) &lt;span style="color:#f92672"&gt;*&lt;/span&gt;dest&lt;span style="color:#f92672"&gt;++&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; c;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(c &lt;span style="color:#f92672"&gt;==&lt;/span&gt; EOF &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; dest &lt;span style="color:#f92672"&gt;==&lt;/span&gt; s) &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; NULL;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;dest&lt;span style="color:#f92672"&gt;++&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;\0&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; s;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;echo&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;char&lt;/span&gt; buf[&lt;span style="color:#ae81ff"&gt;8&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; gets(buf);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; puts(buf);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;이런 코드가 있다고 하자! 그런데 이 코드는 입력이 크기인 8을 넘는지 안넘는지 알 수 있는 방법이 없다&amp;hellip;.&lt;/li&gt;
&lt;li&gt;어셈블리로도 봐볼까?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; void echo()&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
1	echo:
2	subq	$24, %rsp	Allocate 24 bytes on stack
	3	movq	%rsp, %rdi	Compute buf as %rsp
	4	call	gets		Call gets
	5	movq	%rsp, %rdi	Compute buf as %rsp
	6	call	puts		Call puts
	7	addq	$24, %rsp	Deallocate stack space
8	ret			Return
```
- 스택 포인터에서 24를 빼서 할당하고, 맨위에 저장하고..
- rsp를 rdi에 적어놔서 gets / puts 둘다에도 쓸 수 있게 하고
- buf가 그러면 8바이트를 쓰니까, 뒤에 16바이트는 안쓴다.
- 사용자가 7개 문자 입력 (종료문자열까지 8개) 까지는 문제가 없겠지만&amp;hellip; 이를 넘어가면?
- 0-7: buf에 잘 들어감
- 9-23: 비어있는 스택공간
- 24-31: Return address
- 32+: caller에 저장된 값들
&lt;ul&gt;
&lt;li&gt;버퍼 오버플로우는 버그가 터지는것도 문제지만..
&lt;ul&gt;
&lt;li&gt;원하지 않는 행동을 마음대로 할 수 있다면?&lt;/li&gt;
&lt;li&gt;이것이 컴퓨터 네트워크를 통해 시스템의 보안을 공격하는 가장 일반적인 방법&lt;/li&gt;
&lt;li&gt;이를 Exploit code라고 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;뭐 암튼 보안을 잘해야한다는 이야기&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3.10.4 Thwarting Buffer Overflow Attacks
&lt;ul&gt;
&lt;li&gt;버퍼 오버플로우가 문제가 되니까 현대 컴파일러와 운영체제는 이를 막는 메커니즘을 구현하기 시작했다&lt;/li&gt;
&lt;li&gt;Stack Randomization
&lt;ul&gt;
&lt;li&gt;시스템 내에 익스플로잇 코드를 삽입하기 위해서 공격자는 코드에 대한 포인터뿐만 아니라 코드 모두를 주입해야함.&lt;/li&gt;
&lt;li&gt;또한, 해당 문자열이 들어갈 스택/메모리 주소도 알아야된다!!
&lt;ul&gt;
&lt;li&gt;역사적으로, 이는 예측 가능성이 높았다.&lt;/li&gt;
&lt;li&gt;공격자가 공통 웹서버에서 사용하는 스택 주소를 찾았다면?
&lt;ul&gt;
&lt;li&gt;많은 머신에서 작동하는 공격을 만들 수 있었다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;그러니까, 스택의 위치를 각 프로그램의 실행마다 다르게 하자.
&lt;ul&gt;
&lt;li&gt;많은 머신이 같은 코드를 실행하더라도, 모두 상이한 스택 주소를 사용할 것이다.&lt;/li&gt;
&lt;li&gt;alloca함수같은걸 이용해서 프로그램 시작시 스택상에 랜덤한 값을 할당한다
&lt;ul&gt;
&lt;li&gt;이 값은 충분한 변동을 얻을수 있을정도로 커야하지만, 낭비하지 않을만큼 작아야하는.. 당연한말&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;간단하게는 이렇게 확인 가능하다&lt;/li&gt;
&lt;li&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;long&lt;/span&gt; local;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; printf(&lt;span style="color:#e6db74"&gt;&amp;#34;local at %p&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\n&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;, &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;local);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}		 
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;이렇게 하면 언제나 같은 값을 가지지 않음을 확인할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;이는 현재 리눅스 시스템에서 표준 관행이다.&lt;/li&gt;
&lt;li&gt;하지만 이는 어느정도의 공격을 막을 수는 있지만
&lt;ul&gt;
&lt;li&gt;공격자가 정말 힘내면 다른 주소를 가진 공격을 반복적으로 시도해서 브루트포스로 극복 가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Stack Corruption Detection
&lt;ul&gt;
&lt;li&gt;스택이 손상되었을 때를 감지하면 되지 않을까?
&lt;ul&gt;
&lt;li&gt;echo함수는 local buffer의 경계를 초과할 때 터졌었다&lt;/li&gt;
&lt;li&gt;C에서는 배열의 경계를 넘어서 쓰기를 방지할 수 있는 좋은 방법이 없다.&lt;/li&gt;
&lt;li&gt;대신 프로그램은 그러한 쓰기가 어떠한 해로운 영향을 미치기 전에 뭔가가 발생한적 있는지를 검사할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;이는 버퍼 오버런을 검출하기 위해 생성된 코드에 스택 보호자로 알려진 메커니즘을 통합한다 (?)
&lt;ul&gt;
&lt;li&gt;임의의 로컬 버퍼와 나머지 스택들 사이에 특별한 canary 값을 지정하는 것
&lt;ul&gt;
&lt;li&gt;이는 guard값이라고도 하며, 프로그램이 실행될 때마다 무작위라서 공격자가 그것이 무엇인지 쉽게 결정할 수 없다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;레지스터를 복원하고 돌아가기 전에, 프로그램은 이 canary가 변경되었는지 안됐는지 확인한다.
&lt;ul&gt;
&lt;li&gt;아하, 예전에 bomb lab에서 봤던 %fs:40이 이거였구나!!!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Limiting Executable Code Regions
&lt;ul&gt;
&lt;li&gt;공격자가 실행 가능한 코드를 시스템에 삽입하는 능력을 제거하는 것
&lt;ul&gt;
&lt;li&gt;그중 한가지 방법은 실행 가능한 코드를 메모리 영역에 저장하는것을 제한하는 것
&lt;ul&gt;
&lt;li&gt;예를 들어, 컴파일러에 의해 생성된 코드가 있는 부분만 실행 가능하게 하고, 나머지 부분은 읽기 및 쓰기만 허용하도록 제한할 수 있겠다.&lt;/li&gt;
&lt;li&gt;가상 메모리공간은 페이지당 2048 / 4096바이트임. (9장에서 배울 것)&lt;/li&gt;
&lt;li&gt;하드웨어는 프로그램 / 운영체제 등한테 액세스 형태를 지정하는 메모리 보호를 지원함&lt;/li&gt;
&lt;li&gt;많은 시스템들은 읽기 / 쓰기 / 실행에 대한 제어를 허용한다.
&lt;ul&gt;
&lt;li&gt;역사적으로 x86은 읽기 및 실행을 1비트 플래그로 병합하여, 읽기가 가능하면 실행도 가능했다.
&lt;ul&gt;
&lt;li&gt;스택쪽도 읽어야하기때문에 스택의 바이트도 실행이 가능했다&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;하지만 이제 64비트 프로세서에서는 AMD도 인텔도 이를 분리하기 시작햇다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;이 세가지 기술들은 프로그래머의 노력도, 수행 오버헤드도 적다.&lt;/li&gt;
&lt;li&gt;개별적으로 취약성 수준을 낮추고, 조합해서 더 좋기도 하다.&lt;/li&gt;
&lt;li&gt;하지만 불행히도 컴퓨터를 공격하는 방법들은 여전히 존재하고, worm과 바이러스들은 계속 공격해나간다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3.10.5 Supporting Variable-Size Stack Frames
&lt;ul&gt;
&lt;li&gt;지금까지는 컴파일러가 스택에 얼만큼을 할당해야하는지 미리 결정할 수 있었다.
&lt;ul&gt;
&lt;li&gt;하지만 일부 기능은 요구하는 스택 메모리의 양이 달라질 수 있다!
&lt;ul&gt;
&lt;li&gt;예를들어, alooca 등의 임의 크기의 바이트를 스택에 할당하는 거라던지,&lt;/li&gt;
&lt;li&gt;가변 크기의 로컬 어레이를 선언하던지&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;따라서, 나중에 함수로 돌아갈때 스택 포인터의 위치가 어디였는지를 기억하기 위해, 이를 프레임 포인터마냥 %rbp에 저장해두자!!
&lt;ul&gt;
&lt;li&gt;그러면 %rsp가 얼마나 크더라도 함수 return시 어디로 돌아가야하는지는 확실하다.&lt;/li&gt;
&lt;li&gt;이건 기계코드에 leave라고 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 class="relative group"&gt;❔질문 사항
 &lt;div id="질문-사항" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%a7%88%eb%ac%b8-%ec%82%ac%ed%95%ad" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;왜 8바이트가 아닌 24바이트를 땡겼지?
&lt;ul&gt;
&lt;li&gt;-&amp;gt; 16바이트 단위로 rsp를 맞추기 위해&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Stack Randomization, Stack Canary 모두 컴파일 시간에 결정된거 아닌가? 랜덤값이?
&lt;ul&gt;
&lt;li&gt;같은 컴파일된 바이너리파일을 실행하면 결국 일어나는일은 언제나 같은건가?
&lt;ul&gt;
&lt;li&gt;-&amp;gt; ㄴ.ㄴ fs:40같은데 들어이있는 값은 맨날 다르다&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;그래도 RNG같은 코드가 박혀있는거 아닌가?
&lt;ul&gt;
&lt;li&gt;-&amp;gt; 맞긴 한데, 간단한 rand()급이 아니고 마우스 움직임 / 하드웨어 인터럽트등 다양한 불규칙적 신호들을 모아서 무작위화한다.&lt;/li&gt;
&lt;li&gt;스택에서 printf같은걸로도 못읽게 첫번째 바이트를 0x00(NULL)로 설정해서 문자열 함수 등도 방어한다!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 class="relative group"&gt;🔗 참고 자료
 &lt;div id="-참고-자료" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#-%ec%b0%b8%ea%b3%a0-%ec%9e%90%eb%a3%8c" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;CSAPP&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>CSAPP 3.11 Floating-Point Code</title><link>https://blog.wlgh7407.com/posts/books/csapp/chapter-03-machine-level-representation/260123_til_csapp-3.11/</link><pubDate>Fri, 23 Jan 2026 00:00:00 +0000</pubDate><guid>https://blog.wlgh7407.com/posts/books/csapp/chapter-03-machine-level-representation/260123_til_csapp-3.11/</guid><description>&lt;h2 class="relative group"&gt;📝 상세 정리
 &lt;div id="-상세-정리" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#-%ec%83%81%ec%84%b8-%ec%a0%95%eb%a6%ac" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Floating-Point Code
&lt;ul&gt;
&lt;li&gt;부동소수점 아키텍쳐는 어케 동작할라나
&lt;ul&gt;
&lt;li&gt;부동소수점 값이 저장되고 엑세스되는 방법&lt;/li&gt;
&lt;li&gt;부동소숫점 데이터에서 작동하는 명령어&lt;/li&gt;
&lt;li&gt;부동소수점 값을 함수에 전달하고 반환하는데 사용되는 컨벤션/관례&lt;/li&gt;
&lt;li&gt;함수 호출 중 레지스터가 보존되는 방법에 대한 규약&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;SSE는 128비트, AVX는 256비트, AVX-512는 512비트..&lt;/li&gt;
&lt;li&gt;%xmm0, %xmm1등의 어셈블리 코드가 나오면 현대적인 레지스터다!
&lt;ul&gt;
&lt;li&gt;%rax, %rbx, %rsp, &amp;hellip; %r15랑은 아예 별개. 위치도 다른듯?&lt;/li&gt;
&lt;li&gt;연산 방식 자체가 보수방식 / 지수가수 방식으로 다르니까 다른 장치에서
&lt;ul&gt;
&lt;li&gt;SIMD도 가능하다!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3.11.1 Floating-Point Movement and Conversion Operations
&lt;ul&gt;
&lt;li&gt;vmovss / vmovsd / vmovaps / vmovapd 같은 명령어들이 있다&lt;/li&gt;
&lt;li&gt;코드 최적화 지침은 32비트 데이터는 4바이트 정렬을, 64비트 데이터는 8바이트 정렬을 만족하도록 권장하지만 안그래도 동작은 한다&lt;/li&gt;
&lt;li&gt;정수 mov과 같은 방식으로 웬만하면 동작한다!&lt;/li&gt;
&lt;li&gt;GCC는 스칼라 이동 연산을 xmm 레지스터 - 메모리 사이에서만 수행한다.
&lt;ul&gt;
&lt;li&gt;xmm 레지스터 사이에서 전송하기 위해선 vmovaps나 vmoapd&lt;/li&gt;
&lt;li&gt;안에있는 a는 aligned, 정렬을 의미한다&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;float&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;float_mov&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;float&lt;/span&gt; v1, &lt;span style="color:#66d9ef"&gt;float&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;src, &lt;span style="color:#66d9ef"&gt;float&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;dst){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;float&lt;/span&gt; v2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;src;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;dst &lt;span style="color:#f92672"&gt;=&lt;/span&gt; v1;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; v2;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;위 코드는 다음과 같이 번역된다.&lt;/li&gt;
&lt;li&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; v1 in %xmm0, src in %rdi, dst in %rsi&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
1	float_mov:
2	vmovaps	%xmm0, %xmm1	Copy v1
3	vmovss	(%rdi), %xmm0	Read v2 from src
4	vmovss	%xmm1, (%rsi)	Write v1 to dst
5	ret			 Return v2 in %xmm0
```
&lt;ul&gt;
&lt;li&gt;vmovaps, vmovss를 둘다 확인할 수 있다!&lt;/li&gt;
&lt;li&gt;float -&amp;gt; 정수에서는 잘 반올림해서 들어감&lt;/li&gt;
&lt;li&gt;정수 -&amp;gt; float에서는 신기하게도 뒤에 피연산자가 3개 들어간다
&lt;ul&gt;
&lt;li&gt;이때 두번째 피연산자는 상위 바이트에만 영향을 미쳐서 무시해도 된다
&lt;ul&gt;
&lt;li&gt;일단 두번째 연산자는 결과가 들어갈 레지스터의기 기존 값을 의미한다.&lt;/li&gt;
&lt;li&gt;웬만한 연산에서 두번째 피연산자와 세번째 목적지 피연산자는 같다&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;float -&amp;gt; float에서
&lt;ul&gt;
&lt;li&gt;조금 이상한 코드가 생성된다&lt;/li&gt;
&lt;li&gt;상위비트를 다시 활용하지 못하게 하기 위함
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;가짜 의존성&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;이전의 상위 비트값을 써야될때 값을 기다리게 하지 않기 위해, 그냥 덮어버린다&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;single -&amp;gt; double, double -&amp;gt; single 둘다 마찬가지&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3.11.2 Floating-Point Code in Procedures
&lt;ul&gt;
&lt;li&gt;크아악 프로시져다
&lt;ul&gt;
&lt;li&gt;언제나 그랬듯 XMM 레지스터를 이용해서 float 인수들을 함수로 전달하고 반환받고 한다&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;x86-64에서는 다음과 같은 관습이 관찰된다
&lt;ul&gt;
&lt;li&gt;최대 8개의 float arg가 xmm0~7로 전달되고, 더 필요하면 스택 사용&lt;/li&gt;
&lt;li&gt;float 반환은 xm0에서&lt;/li&gt;
&lt;li&gt;모든 XMM 레지스터는 caller-saved. 이후에 호출된놈이 맘대로 바꿔도 됨&lt;/li&gt;
&lt;li&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;double&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;f1&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; x, &lt;span style="color:#66d9ef"&gt;double&lt;/span&gt; y, &lt;span style="color:#66d9ef"&gt;long&lt;/span&gt; z);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;위의 예에서, %edi에 x, %xmm0에 y, %rsi에 z&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3.11.3 Floating-Point Arithmetic Operations
&lt;ul&gt;
&lt;li&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;double&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;funct&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;double&lt;/span&gt; a, &lt;span style="color:#66d9ef"&gt;float&lt;/span&gt; x, &lt;span style="color:#66d9ef"&gt;double&lt;/span&gt; b, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; a&lt;span style="color:#f92672"&gt;*&lt;/span&gt;x &lt;span style="color:#f92672"&gt;-&lt;/span&gt; b&lt;span style="color:#f92672"&gt;/&lt;/span&gt;i;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;위 코드는 다음과같이 번역된다.&lt;/li&gt;
&lt;li&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	a in %xmm0, x in %xmm1, b in %xmm2, i in %edi&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
1	funct:
The following two instructions convert x to double
2	vunpcklps	%xmm1, %xmm1, %xmm1
3	vcvtps2pd	%xmm1, %xmm1
4	vmulsd	%xmm0, %xmm1, %xmm0		Multiply a by x
5	vcvtsi2sd	%edi, %xmm1, %xmm1	Convert i to double
6	vdivsd	%xmm1, %xmm2, %xmm2		Compute b/i
7	vsubsd	%xmm2, %xmm0, %xmm0	Subtract from a*x
8	ret				Return
```&lt;/li&gt;
&lt;li&gt;3.11.4 Defining and Using Floating-Point Constants
&lt;ul&gt;
&lt;li&gt;정수 연산과 달리 AVX float 연산은 immediate value로 연산할 수 없다.
&lt;ul&gt;
&lt;li&gt;대신 컴파일러는 임의값에 대해 스토리지를 할당하고 초기화하고, 메모리로부터 값을 읽는다.&lt;/li&gt;
&lt;li&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;double&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;cel2fahr&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;double&lt;/span&gt; temp){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1.8&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; temp &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;32.0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;과 같은 함수가 있다면, 이는 다음과 같이 바뀐다.&lt;/li&gt;
&lt;li&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;	double cel2fahr(double temp) temp in %xmm0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
1	cel2fahr:
2	 vmulsd	.LC2(%rip), %xmm0, %xmm0	Multiply by 1.8
3	 vaddsd	.LC3(%rip), %xmm0, %xmm0	Add 32.0
4	 ret
5	.LC2:
6	 .long	3435973837				Low-order 4 bytes of 1.8
7	 .long	1073532108				High-order 4 bytes of 1.8
8	.LC3:
9	 .long	0					Low-order 4 bytes of 32.0
10	 .long	1077936128				High-order 4 bytes of 32.0
```
&lt;ul&gt;
&lt;li&gt;.LC2의 위치로부터 1.8을 가져오고, .LC3에서 32.0을 판독해오는 것으로 보인다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3.11.5 Using Bitwise Operations in Floating-Point Code
&lt;ul&gt;
&lt;li&gt;비트연산을 float에서도 사용할 수 있다!
&lt;ul&gt;
&lt;li&gt;vxorps, vxorpd, vandps, vandpd&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;근데 float에서 비트연산은 진짜 왜하지?
&lt;ul&gt;
&lt;li&gt;레지스터를 0으로 초기화하고 싶을 때
&lt;ul&gt;
&lt;li&gt;자기 자신을 xor하기&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;부호 반전 / 절댓값화
&lt;ul&gt;
&lt;li&gt;맨앞 MSB 만지기&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;(x&amp;lt;0 ? 0:x)과 같은 경우 (RELU)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3.11.6 Floating Point Comparison Operations
&lt;ul&gt;
&lt;li&gt;아무래도 수를 비교는 해야겠지
&lt;ul&gt;
&lt;li&gt;ucomiss / ucomisd&lt;/li&gt;
&lt;li&gt;S1와 S2 비교&lt;/li&gt;
&lt;li&gt;늘 그랬듯 ZF, CF, PF를 설정한다&lt;/li&gt;
&lt;li&gt;하나라도 NaN이면, 세 플래그를 다 킨다!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3.11.7 Observations about Floating-Point Code
&lt;ul&gt;
&lt;li&gt;AVX2가 float에 대해 정수랑 비슷하지만, 훨씬더 다양한 명령어와 형식을 포함하는걸 알 수 있었다.&lt;/li&gt;
&lt;li&gt;또한 패킹된 데이터에 병렬연산을 수행해서 더 빠르게 실행시킬수도 있다.
&lt;ul&gt;
&lt;li&gt;요새 gcc가 해주더라&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 class="relative group"&gt;❔질문 사항
 &lt;div id="질문-사항" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%a7%88%eb%ac%b8-%ec%82%ac%ed%95%ad" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 class="relative group"&gt;🔗 참고 자료
 &lt;div id="-참고-자료" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#-%ec%b0%b8%ea%b3%a0-%ec%9e%90%eb%a3%8c" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>CSAPP 3.9 Heterogeneous Data Structures</title><link>https://blog.wlgh7407.com/posts/books/csapp/chapter-03-machine-level-representation/260121_til_csapp-3.9/</link><pubDate>Wed, 21 Jan 2026 00:00:00 +0000</pubDate><guid>https://blog.wlgh7407.com/posts/books/csapp/chapter-03-machine-level-representation/260121_til_csapp-3.9/</guid><description>&lt;h2 class="relative group"&gt;📝 상세 정리
 &lt;div id="-상세-정리" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#-%ec%83%81%ec%84%b8-%ec%a0%95%eb%a6%ac" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;C는 서로 다른 유형의 객체를 결합해서 데이터 유형을 생성하기 위한 두가지 어쩌구..
&lt;ul&gt;
&lt;li&gt;struct, union&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3.9.1 Structures
&lt;ul&gt;
&lt;li&gt;다른 유형의 객체를 단일 객체로 그룹화하는 데이터 유형&lt;/li&gt;
&lt;li&gt;structure 내의 다른 컴포넌트는 이름으로 참조됨&lt;/li&gt;
&lt;li&gt;모든 구성요소가 메모리의 연속 영역에 저장되고, structure에 대한 포인터가 첫번째 바이트의 주소
&lt;ul&gt;
&lt;li&gt;Array랑 비슷하다!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;컴파일러는 각 필드의 바이트 오프셋을 들고있고.. 그걸로 잘 왔다갔다 참조&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3.9.2 Unions
&lt;ul&gt;
&lt;li&gt;단일 객체를 여러 유형에 따라 참조할 수 있도록 함
&lt;ul&gt;
&lt;li&gt;이게 무슨소리지?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;struct에서 char, int[2], double이 있다면
&lt;ul&gt;
&lt;li&gt;char: 0&lt;del&gt;1, int: 4&lt;/del&gt;12, double: 16~24바이트로 총 24바이트 메모리 사용
&lt;ul&gt;
&lt;li&gt;사이공간은 패딩&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Union이었다면 가장 큰것에 맞춰서 그저 8바이트 사용
&lt;ul&gt;
&lt;li&gt;그때그때 char / int / double로 읽는 것
&lt;ul&gt;
&lt;li&gt;근데 그럼 이걸 왜쓰냐?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;한번에 char / int / double 중 여러 값을 동시에 가지지 않을떄!
&lt;ul&gt;
&lt;li&gt;책에 나온 예제는 리프노드에만 값이 있는 이진 트리 구조체
&lt;ul&gt;
&lt;li&gt;왼쪽노드 포인터, 오른쪽노드 포인터, double 2개를 가진다고 해보자
&lt;ul&gt;
&lt;li&gt;struct는 32바이트, Union이라면 잘 묶어서 16바이트로 처리 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;다음 예시를 보자.
&lt;ul&gt;
&lt;li&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;double&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;uu2double&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;unsigned&lt;/span&gt; word0, &lt;span style="color:#66d9ef"&gt;unsigned&lt;/span&gt; word1)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 	&lt;span style="color:#66d9ef"&gt;union&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 	 &lt;span style="color:#66d9ef"&gt;double&lt;/span&gt; d;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 	 &lt;span style="color:#66d9ef"&gt;unsigned&lt;/span&gt; u[&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 	} temp;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 	temp.u[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; word0;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 	temp.u[&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; word1;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 	&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; temp.d;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;이때 word0 = 0x12345678, word1 = 0x9abcdef0 이라고 하면&lt;/li&gt;
&lt;li&gt;temp에는
&lt;ul&gt;
&lt;li&gt;Little Endian일때 78 56 34 12 f0 de bc 9a&lt;/li&gt;
&lt;li&gt;Big Endian일땐 12 34 56 78 9a bc de f0&lt;/li&gt;
&lt;li&gt;가 저장된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;이를 d로 읽을 때
&lt;ul&gt;
&lt;li&gt;Little Endian에서는 0x9abcdef012345678&lt;/li&gt;
&lt;li&gt;Big Endian에서는 0x123456789abcdef0&lt;/li&gt;
&lt;li&gt;으로 해석하게 된다. (d를 읽을때도 endian 신경썽하니까!!)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3.9.3 Data Alignment
&lt;ul&gt;
&lt;li&gt;일부 객체들에 대한 주소는 2, 4, 8등의 배수여야함을 요구하는 애들이 있다
&lt;ul&gt;
&lt;li&gt;이래야 하드웨어 설계가 단순화된다&lt;/li&gt;
&lt;li&gt;8의 배수로 정렬되어있으면 메모리 한번만 참조하면 되지만, 아니라면 앞뒤로 분할되어 있는곳에 두번 참조해야할 수도 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;x86-64는 데이터의 정렬에 관계없이 올바르게 작동하지만, 인텔은 메모리 시스템 성능 향상을 위해 정렬할것을 권고하고 있음&lt;/li&gt;
&lt;li&gt;정렬 권장사항은 다음과 같다
&lt;ul&gt;
&lt;li&gt;K = 1 : char&lt;/li&gt;
&lt;li&gt;K = 2 : short&lt;/li&gt;
&lt;li&gt;K = 4 : int, float&lt;/li&gt;
&lt;li&gt;K = 8 : long, double, char *&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;아하, 이게 bool 정적 배열보다 bitset이 빠른 이유구나!! 알아서 SIMD를 지원하면서 채워주는거구나!!
&lt;ul&gt;
&lt;li&gt;그리고 이걸 패딩이라고 하겠구나!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.align 8&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;어셈블리에서 다음과 같은 코드가 있으면, 그 뒤따르는 데이터가 8의 배수읜 주소로 시작될 것을 보장한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div class="highlight-wrapper"&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;S1&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;char&lt;/span&gt; c;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; j;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;가 있다고 가정하면, 4 / 1 / 4 바이트를 쓰는게 아니라 4 / 1 + 3(패딩) / 4 바이트를 쓴다.
&lt;ul&gt;
&lt;li&gt;결과적으로 j는 오프셋 8을 가지며 전체 구조 크기는 12바이트이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;또한, 컴파일러는 S1 유형의 포인터 p가 4바이트 정렬을 만족하는지 확인해야한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 class="relative group"&gt;❔질문 사항
 &lt;div id="질문-사항" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#%ec%a7%88%eb%ac%b8-%ec%82%ac%ed%95%ad" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;일부 객체들에 대한 주소는 2, 4, 8등의 배수여야함을 요구하는 애들이 있고, 이래야 하드웨어 설계가 단순화된다
&lt;ul&gt;
&lt;li&gt;하드웨어 설계가 단순화된다는건 뭘까?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;또한, 컴파일러는 S1 유형의 포인터 p가 4바이트 정렬을 만족하는지 확인해야한다.
&lt;ul&gt;
&lt;li&gt;안에 있는 원소들 중 K의 최댓값을 기준으로 하나?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 class="relative group"&gt;🔗 참고 자료
 &lt;div id="-참고-자료" class="anchor"&gt;&lt;/div&gt;
 
 &lt;span
 class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none"&gt;
 &lt;a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#-%ec%b0%b8%ea%b3%a0-%ec%9e%90%eb%a3%8c" aria-label="Anchor"&gt;#&lt;/a&gt;
 &lt;/span&gt;
 
&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;CSAPP&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>