<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>devbelly</title>
    <link>https://devbelly.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Tue, 7 Jul 2026 13:39:11 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>devbelly</managingEditor>
    <item>
      <title>블로그 이사합니다.</title>
      <link>https://devbelly.tistory.com/282</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://devbelly.github.io/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://devbelly.github.io/&lt;/a&gt;&lt;/p&gt;</description>
      <author>devbelly</author>
      <guid isPermaLink="true">https://devbelly.tistory.com/282</guid>
      <comments>https://devbelly.tistory.com/282#entry282comment</comments>
      <pubDate>Thu, 30 Dec 2021 15:25:58 +0900</pubDate>
    </item>
    <item>
      <title>컴퓨터구조 ANSWER1</title>
      <link>https://devbelly.tistory.com/281</link>
      <description>&lt;article class=&quot;markdown-body entry-content&quot; itemprop=&quot;text&quot;&gt; &lt;ol&gt;
&lt;li&gt;&lt;p&gt;answer: &lt;code&gt;mflo $t0&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;answer: 000000 01000 01001 00000 00000 011000&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;answer: 000000 00000 00000 01010 00000 010010&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;answer: 3&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;answer: 1&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;answer:000000 10001 10010 01000 00000 100000&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;answer: sub $6 $4 $5&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;answer: 000000 00000 10000 01010 00100 000000&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;answer: 001101 01001 01011 1000 0000 0000 0000&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;answer: 001100 00000 01100 1111 1111 1111 1111 1111&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;answer: 001000 00000 01101 1111 1111 1111 1111&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;answer: True&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;answer: ori $t1, $0, -32768, (상수 field를 10진수로 표현해야한다)&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;answer: True&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;answer: &lt;code&gt;lui $t1, -1&lt;/code&gt;,&lt;code&gt;ori $t1, $0, -32768&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;answer: True&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;answer: 0x56780000&lt;/em&gt; / &lt;em&gt;answer: 001111 00000 01000 1111 1111 1111 1111&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;answer: 101011 00101 00100 0000 0000 0000 1000&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;answer: 100011 00101 00110 0000 0000 0000 1000, &lt;code&gt;lw $6, 8($5)&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;answer:&lt;/em&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;assembly language-assembly&quot;&gt;lw $t0, 32($s3) #base register로부터 32비트 떨어져있으므로(4 byte x 8) 32라고 적어야 한다.
add $s1, $s2, $t0&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;answer: 000000 01001 00000 00000 00000 001000&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;answer: 000010 0000 0100 0000 0000 0000 0010 01 (상위 4비트는 PC의 4비트로 채우고 하위 2비트는 0으로 채운다)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;answer: 000101 00011 00100 0000 0000 0000 0011&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;code&gt;rs&lt;/code&gt;, &lt;code&gt;rt&lt;/code&gt;의 위치가 assemble후에 바뀌지 않음을 유의하자.&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;answer: false, (-131071~131071)&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;answer:&lt;/em&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;assembly language-assembly&quot;&gt;Loop:    
    sll $t1, $s3, 2
    add $t1, $s6, $t1
    lw $t1, 0($t1)
    bne $t1, $s5, Exit
    addi $s3, $s3, 1
    j Loop
Exit: 
    jr $ra&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;answer:&lt;/em&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;assembly language-assembly&quot;&gt;addi $a0, $0, 10
addi $v0, $0, 1
syscall&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;


&lt;li&gt;&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/67682840/137608195-051bbfe2-188a-450b-9273-b61d1eecf88b.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;28.&lt;/p&gt;
&lt;p&gt;29.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/67682840/137608917-bff77ed4-f1da-47b5-954f-cfe40d0e2ab9.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;30.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/67682840/137609428-33ad78e5-1ef5-4296-8a66-10000d8cbd94.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;31.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/67682840/137610892-b0d7995a-3762-4886-a343-c6e0526a7ef1.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;32.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/67682840/137611054-e16067f6-8bc3-4c3b-9a58-5646e6c17db2.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;33.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/67682840/137611562-7a234582-1c6f-47e9-8689-c1b7caf855ba.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;34.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/67682840/138021416-b384b1fa-fa23-48c6-8896-317cf5a35c3c.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt; &lt;/article&gt;</description>
      <category>학교</category>
      <author>devbelly</author>
      <guid isPermaLink="true">https://devbelly.tistory.com/281</guid>
      <comments>https://devbelly.tistory.com/281#entry281comment</comments>
      <pubDate>Sat, 30 Oct 2021 22:53:54 +0900</pubDate>
    </item>
    <item>
      <title>컴퓨터구조 TEST1</title>
      <link>https://devbelly.tistory.com/280</link>
      <description>&lt;article class=&quot;markdown-body entry-content&quot; itemprop=&quot;text&quot;&gt; &lt;p&gt;&lt;strong&gt;&lt;em&gt;1. 연산의 결과 (6)를 확인하기 위해 수행해야하는 명령어는?&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;2. &lt;code&gt;mult $t0 t1&lt;/code&gt;를 2진수로 표현하라(단, fucnt 값은 24)&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;3. &lt;code&gt;mflo $t2&lt;/code&gt;을 2진수로 표현하라(단, funct 값은 18)&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;h4 id=&quot;example&quot;&gt;Example&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;assembly language-assembly&quot;&gt;.text
.globl main
main:
    addi $t0, $0, 7
    addi $t1, $0, 2
    div $t0, $t1
    mflo $t2
    mfhi $t3&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;4. &lt;code&gt;$t2&lt;/code&gt;에 저장된 값은?&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;5. &lt;code&gt;$t3&lt;/code&gt;에 저장된 값은?&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;6. add $t0, $s1, $s2를 2진수로 표현하시오. (단, funct값은 32)&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;7. 다음 2진수를 어셈블리로 바꾸시오. 000000 00100 00101 00110 00000 100010(sub)&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;8. sll $10, $16, 4를 2진수로 표현하시오.(단, funct 값은 0)&lt;/em&gt;&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;9. ori $11, $9, 0x8000을 2진수로 표현하시오. (단, op 값은 13)&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;10. andi $12, $0, 0xffff를 2진수로 표현하시오.(단, op값은 12)&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;11. addi $13, $0, -1을 2진수로 표현하시오.(단, op값은 8)&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;addi $t1, $0, 0x8000&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;12. out-of-range error가 발생하는가 True/False로 대답하시오.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;13. SPIM에 load되는 명령어를 쓰시오&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ori $t1, $0, -32768&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;14. out-of-range error가 발생하는지 True/False로 대답하시오&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;15. SPIM에 load되는 명령어를 쓰시오.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;addiu $t1, $0, 32768&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;16. out-of-range error가 발생하는지 True/False로 대답하시오&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;17. &lt;code&gt;$t1&lt;/code&gt; 레지스터의 값이 &lt;code&gt;0x12345678&lt;/code&gt;일 때, &lt;code&gt;lui $t1 0x5678&lt;/code&gt;을 수행한 결과를 쓰시오.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;17-2) &lt;code&gt;lui $t0 0xffff&lt;/code&gt;를 2진수로 표현하시오. (op 값은 15)&lt;/em&gt;&lt;/strong&gt;❌&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;18. sw $4, 8($5)을 2진수로 변환하라.(단 op 값은 43)&lt;/em&gt;&lt;/strong&gt; ❌&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;19. 0x8ca60008을 disassemble 한 명령어를 적어라.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;c language-c&quot;&gt;int g,h,A[100];
g = h + A[8];&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;g in $s1, h in $s2, base address of A in $s3&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;20. 위 코드를 어셈블리로 나타내라&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;21. &lt;code&gt;jr $t1&lt;/code&gt;을 2진수로 나타내라.(단, funct 값은 8이다)&lt;/em&gt;&lt;/strong&gt; ❌&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;assembly language-assembly&quot;&gt;.text 0x00400024
.globl main
main:
    nop
    j main&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;22. &lt;code&gt;j main&lt;/code&gt;을 2진수로 변환하라. (단, op 값은 2)&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;assembly language-assembly&quot;&gt;    bne $3, $4, Else # 0x00400038
    add $s0, $s1, $s2
    j Exit
Else: sub $s0, $s1, $s2
Exit: add $s0, $s0, $s0&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;23. &lt;code&gt;bne $3, $4, Else&lt;/code&gt;를 2진수로 변환하라.(단, op값은 5이다)&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;24. &lt;code&gt;beq&lt;/code&gt;, &lt;code&gt;bne&lt;/code&gt;명령어의 &lt;code&gt;offset&lt;/code&gt;필드를 계산할 때 표현가능한 범위는 -32768~32767이다.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;25. 다음의 코드를 assembly로 변환하라.(단, i in $s3, k in $s5, address of arr in $s6, arr is int array)&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;c language-c&quot;&gt;i = 1;
while (arr[i]==k) ++i;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;26. Syscall을 이용하여 10을 출력하시오.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;27. 다음 표를 완성하시오&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th id=&quot;signal_name&quot;&gt;Signal name&lt;/th&gt;
&lt;th id=&quot;deasserted&quot;&gt;deasserted&lt;/th&gt;
&lt;th id=&quot;asserted&quot;&gt;asserted&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;RegDst&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RegWrite&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ALUSrc&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PCSrc&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MemRead&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MemWrite&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MemtoReg&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;28. 다음 표를 완성하시오&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th id=&quot;opcdoe&quot;&gt;opcdoe&lt;/th&gt;
&lt;th id=&quot;aluop&quot;&gt;ALUOp&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;lw&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;sw&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;beq&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;R-type&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;29. 다음 표를 완성하시오&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th id=&quot;alu_function&quot;&gt;ALU function&lt;/th&gt;
&lt;th id=&quot;alu_control&quot;&gt;ALU control&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;add&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;sub&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;and&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;or&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;slt&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;30. 빈 칸을  채우시오&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/67682840/137609358-c5f12ab3-e6aa-4f38-841d-dd486d2e539e.jpg&quot; alt=&quot;KakaoTalk_20211017_121019626&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;31. 빈 칸을 채우시오&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/67682840/137610869-0a0495f9-98b5-4459-8fc0-4a4b8aec6114.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;* 32. 빈 칸을 채우시오.&lt;/strong&gt;*&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/67682840/137611049-06551aca-6dd3-4333-82c4-7a415ea4b4d1.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;33. 철수가 clock cycle을 정하기 위해 기준으로 해야하는 명령어는?&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;34. 다음 표를 완성하시오&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/67682840/138021470-5498fb10-bfe1-4ffa-ad49-9e12cdaf2200.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt; &lt;/article&gt;</description>
      <category>학교</category>
      <author>devbelly</author>
      <guid isPermaLink="true">https://devbelly.tistory.com/280</guid>
      <comments>https://devbelly.tistory.com/280#entry280comment</comments>
      <pubDate>Sat, 30 Oct 2021 22:53:47 +0900</pubDate>
    </item>
    <item>
      <title>컴퓨터구조 중간고사범위</title>
      <link>https://devbelly.tistory.com/279</link>
      <description>&lt;article class=&quot;markdown-body entry-content&quot; itemprop=&quot;text&quot;&gt; &lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/67682840/136677940-48ac28a9-e02a-4e62-9a61-e4ce4f31f3cd.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/67682840/136678032-5a8056d7-628a-46c7-a20f-75f6574324d2.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;h3 id=&quot;mult-rs-rt--multu-rs-rt--mfhi-rd--mflo-rd&quot;&gt;mult rs, rt / multu rs, rt / mfhi rd / mflo rd&lt;/h3&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;code&gt;rs&lt;/code&gt; 레지스터와 &lt;code&gt;rt&lt;/code&gt; 레지스터의 곱셈을 수행한다. 연산의 결과 64비트를 저장하기 위해 &lt;code&gt;hi&lt;/code&gt;, &lt;code&gt;lo&lt;/code&gt; 레지스터를 사용하여 저장한다. &lt;code&gt;hi&lt;/code&gt;와 &lt;code&gt;lo&lt;/code&gt;의 값을 확인하기 위해 &lt;code&gt;mfhi rd&lt;/code&gt;, &lt;code&gt;mflo rd&lt;/code&gt;명령어를 사용한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;곱셈의 결과는 오버플로우 체크를 하지 않는다. (프로그램에서 확인 가능)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;div-rsrt--divu-rs-rt&quot;&gt;div rs,rt / divu rs, rt&lt;/h3&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;code&gt;rs&lt;/code&gt;레지스터를 &lt;code&gt;rt&lt;/code&gt;레지스터와 나눈다. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;overflow와 divide-by-zero checking을 자체적으로 수행하지 않는다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hi&lt;/code&gt;에는 remainder &lt;code&gt;lo&lt;/code&gt;에는 quotient가 저장된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;nor-rd-rs-rt&quot;&gt;nor rd, rs, rt&lt;/h3&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;code&gt;rs&lt;/code&gt; 레지스터와 &lt;code&gt;rt&lt;/code&gt; 레지스터를 or 한 후 not을 하여 &lt;code&gt;rd&lt;/code&gt; 레지스터에 저장한다.&lt;/p&gt;
&lt;h4 id=&quot;example&quot;&gt;Example&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;assembly language-assembly&quot;&gt;.text
.globl main
main:
    addi $t1, $0, 0x3C00
    addi $t2, $0, 0x0DC0

    nor $t6, $t1, $t2
    nor $t7, $t1, $t1&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th id=&quot;0x3c00&quot;&gt;0x3c00&lt;/th&gt;
&lt;th id=&quot;0000_0000_0000_0000_0011_1100_0000_0000&quot;&gt;0000 0000 0000 0000 0011 1100 0000 0000&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0x0dc0&lt;/td&gt;
&lt;td&gt;0000 0000 0000 0000 0000 1101 1100 0000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$t6&lt;/td&gt;
&lt;td&gt;1111 1111 1111 1111 1100 0010 0011 1111&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;이러한 성질로 인하여 어셈블리에서는 not 연산을 필요로 하지 않는다. 예를 들어 &lt;code&gt;$t1&lt;/code&gt;에 대해 not 연산이 필요하다면 아래와 같이 하면 된다.&lt;/p&gt;
&lt;p&gt;1) &lt;code&gt;nor $t6, $t1, $t1&lt;/code&gt;&lt;br /&gt;
2) &lt;code&gt;nor $t6, $t1, $0&lt;/code&gt;&lt;/p&gt;
&lt;h1 id=&quot;r-format&quot;&gt;R-format&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/67682840/136005951-0d63b000-9940-4d57-9fe7-f0940f4130a5.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;h3 id=&quot;add-rd-rs-rt--addu-rd-rs-rt&quot;&gt;add rd, rs, rt / addu rd, rs, rt&lt;/h3&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;code&gt;rs&lt;/code&gt; 레지스터와 &lt;code&gt;rt&lt;/code&gt; 레지스터를 더해 &lt;code&gt;rd&lt;/code&gt; 레지스터에 해당 값을 저장한다. 어셈블리에서는 destination 레지스터를 먼저 적었지만 기계어에서는 &lt;code&gt;0p rs rt rd shamt 32&lt;/code&gt;의 순서로 표현된다.&lt;/p&gt;
&lt;h3 id=&quot;sll--srl&quot;&gt;sll / srl&lt;/h3&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;code&gt;rt&lt;/code&gt; 레지스터의 값을 shamt만큼 shift를 하여 &lt;code&gt;rd&lt;/code&gt; 레지스터에 저장한다. rs 레지스터는 0임을 주의하자.&lt;/p&gt;
&lt;h1 id=&quot;i-format&quot;&gt;I-format&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/67682840/136010948-fea06066-c914-4d95-b3aa-91bfaa3021a5.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;h3 id=&quot;ori&quot;&gt;ori&lt;/h3&gt;
&lt;hr /&gt;
&lt;ul&gt;
&lt;li&gt;I-format&lt;/li&gt;
&lt;li&gt;R[rt] = R[rs] | ZeroExtImm&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;andi&quot;&gt;andi&lt;/h3&gt;
&lt;hr /&gt;
&lt;ul&gt;
&lt;li&gt;I-format&lt;/li&gt;
&lt;li&gt;R[rt] = R[rs] &amp;amp; ZeroExtImm&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;addi&quot;&gt;addi&lt;/h3&gt;
&lt;hr /&gt;
&lt;ul&gt;
&lt;li&gt;I-format&lt;/li&gt;
&lt;li&gt;R[rt] = R[rs] + SignExtImm&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;ori-andi--vs-addi&quot;&gt;ori, andi  VS addi&lt;/h3&gt;
&lt;hr /&gt;
&lt;p&gt;프로세서의 ALU는 2개의 32비트를 입력받아 1개의 32비트 출력을 만들어 내는 장치입니다. I-format의 공간적인 한계로 인해 &lt;code&gt;Imm&lt;/code&gt;필드는 16비트로 밖에 표현되지 못하여 ALU연산을 위해 Extension을 해야합니다. &lt;code&gt;ori&lt;/code&gt;, &lt;code&gt;andi&lt;/code&gt;와 같은 logical instruction은 ZeroExtension을 수행하고 &lt;code&gt;addi&lt;/code&gt;와 같은 arithmetic instruction은 SignExtension을 하게 됩니다.&lt;/p&gt;
&lt;h3 id=&quot;out-of-range-error&quot;&gt;out-of-range error&lt;/h3&gt;
&lt;hr /&gt;
&lt;p&gt;어셈블리를 기계어로 바꾸는 과정에서 out-of-range error가 발생할 수 있습니다. 이때 아래의 두 원칙이 적용됩니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. out-of-range error는 명령어의 종류에 따라 결정된다.&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;명령어의 종류가 arithmetic instruction(&lt;code&gt;addi&lt;/code&gt;,&lt;code&gt;addiu&lt;/code&gt;)일 때, 상수 operand에 signed number가 올것을 기대하여 &lt;code&gt;-32768~32767&lt;/code&gt;범위를 벗어나게 되면 out-of-range error가 발생&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;명령어의 종류가 logical instruction(&lt;code&gt;andi&lt;/code&gt;, &lt;code&gt;ori&lt;/code&gt;)일 때, 상수 operand에 unsigned number가 올 것을 기대하여 &lt;code&gt;0~65535&lt;/code&gt;범위를 벗어나게 되면 out-of-range error가 발생&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;2. 상수 operand는 10진수인지 16진수인지에 따라 signed, unsigned를 결정한다.&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;operand에 10진수를 적으면 signed number로 해석되고&lt;/li&gt;
&lt;li&gt;operand에 16진수를 적으면 unsigned로 해석된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;lui-rt-imm&quot;&gt;lui rt, imm&lt;/h3&gt;
&lt;hr /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;rt&lt;/code&gt;레지스터의 상위 16비트를 &lt;code&gt;imm&lt;/code&gt;로 초기화한다&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rt&lt;/code&gt;레지스터의 하위 16비트를 0으로 초기화한다&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;pseudoinstruction--li&quot;&gt;Pseudoinstruction , li&lt;/h3&gt;
&lt;hr /&gt;
&lt;p&gt;load immediate instruction, 기계어 명령은 아니지만 프로그래머의 편의를 위해 존재한다&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;li $10, 1&lt;/code&gt; : 10번 레지스터에 1을 저장한다&lt;/li&gt;
&lt;li&gt;위 명령어는 &lt;code&gt;ori $10, $0, 1&lt;/code&gt;로 SPIM에 load 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;sw-rt-offsetrs--lw-rt-offsetrs&quot;&gt;sw rt, offset(rs) / lw rt, offset(rs)&lt;/h3&gt;
&lt;hr /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;rt&lt;/code&gt;: destination (lw) or source (sw) register number&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rs&lt;/code&gt;: base register number&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;initializing-data-segment&quot;&gt;Initializing Data Segment&lt;/h3&gt;
&lt;hr /&gt;
&lt;h4 id=&quot;example-1&quot;&gt;Example 1&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;assembly language-assembly&quot;&gt;.data
.byte 1
.byte -2
.space 3
.byte 's'&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th id=&quot;address&quot;&gt;Address&lt;/th&gt;
&lt;th id=&quot;value&quot;&gt;value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0x1001000&lt;/td&gt;
&lt;td&gt;0x01&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0x1001001&lt;/td&gt;
&lt;td&gt;0xfe&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0x1001002&lt;/td&gt;
&lt;td&gt;0x00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0x1001003&lt;/td&gt;
&lt;td&gt;0x00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0x1001004&lt;/td&gt;
&lt;td&gt;0x00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0x1001005&lt;/td&gt;
&lt;td&gt;0x73&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;**in c **&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;c language-c&quot;&gt;char arr[]={1,-2,0,0,0,'s'};&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;example-2&quot;&gt;Example 2&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;assembly language-assembly&quot;&gt;.data 0x10020000
w1: .word 1
    .word -1
    .word 0xabcdef12
    .word 0xffff

.text
main: lui $5, 0x1002
      lui $4, 0x789a
      sw  $4, 8($5)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;in c&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;c language-c&quot;&gt;int w1[4]={1,-1,0xabcdef12,0xffff};
int main(){
    w1[2]=0x789a0000;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;ascii-vs-asciiz&quot;&gt;.ascii VS .asciiz&lt;/h3&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;code&gt;.ascii&lt;/code&gt;와는 다르게 &lt;code&gt;.asciiz&lt;/code&gt;는 추가적으로 맨 끝에 0을 저장한다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;assembly language-assembly&quot;&gt;str: .ascii &quot;star&quot;
str2: .asciiz &quot;star&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;in c&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;char str[]={'s','t','a','r'};
char str2[]={'s','t','a','r','\0'};&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;big-endian-vs-little-endian&quot;&gt;Big Endian vs Little Endian&lt;/h3&gt;
&lt;hr /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Big Endian&lt;/code&gt;: 주소가 큰(big)쪽에 수의 마지막 부분을 적는다&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Little Endian&lt;/code&gt;:주소가 작은(little)쪽에 수의 마지막 부분을 적는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;example-1&quot;&gt;Example&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;assembly language-assembly&quot;&gt;.data 0x10010000
.byte 1
.byte -2
.space 1
.byte 's'&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Big Endian?&lt;/strong&gt; &lt;em&gt;0x01fe0073&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Little Endian?&lt;/strong&gt; &lt;em&gt;0x7300fe01&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&quot;word-alignment&quot;&gt;word alignment&lt;/h3&gt;
&lt;hr /&gt;
&lt;p&gt;데이터를 저장하다가 4바이트에 해당하는 데이터를 저장할 때, 현재 비어있는 공간부터 데이터를 저장하는 것이 아니라 4의 배수에 해당하는 주소부터 새로이 데이터를 저장한다.&lt;/p&gt;
&lt;h4 id=&quot;example-2&quot;&gt;Example&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;assembly language-assembly&quot;&gt;.data 0x10010000
a:
    .byte 1
    .byte -2
w:
    .word 1

.text
.globl main
main:
    la $5, a
    la $6, w       &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;결과는 다음과 같이 &lt;code&gt;.word 1&lt;/code&gt;을 저장할 때 &lt;code&gt;0x10000002&lt;/code&gt;,&lt;code&gt;0x10000003&lt;/code&gt; 주소를 건너뛰고 &lt;code&gt;0x10000004&lt;/code&gt;부터 저장함을 알 수 있습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;$5&lt;/code&gt;: 0x10000000&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$6&lt;/code&gt;: 0x10000004&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;memory-operand&quot;&gt;Memory Operand&lt;/h3&gt;
&lt;hr /&gt;
&lt;h3 id=&quot;example-3&quot;&gt;Example&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;c language-c&quot;&gt;int g,h,A[100];
g = h + A[8];&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;g in $s1, h in $s2, base address of A in $s3&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;jr-r&quot;&gt;jr r&lt;/h3&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;code&gt;rs&lt;/code&gt; 레지스터에 적힌 주소로 branch를 한다. 다른 unconditional branch은 J-format인 반면 &lt;code&gt;jr&lt;/code&gt;은 R-format이다.&lt;/p&gt;
&lt;h4 id=&quot;example-4&quot;&gt;Example&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;assembly language-assembly&quot;&gt;.text 0x00400024
.globl main
main:
    nop
    la $t1, main
    jr $t1&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;j-l1--jal-l2&quot;&gt;j L1 / jal L2&lt;/h3&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;code&gt;L1&lt;/code&gt;에 해당하는 Label로 branch를 한다. J-format을 사용. &lt;code&gt;j&lt;/code&gt;와 &lt;code&gt;jal&lt;/code&gt;의 차이점은 &lt;code&gt;jal&lt;/code&gt;은 branch를 할 때, 추가적으로 현재 PC값의 다음 값을 &lt;code&gt;$31&lt;/code&gt;레지스터에 저장한다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/67682840/136481896-ef7341b4-252f-4933-8d60-dcb8698573d0.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;target&lt;/code&gt;은 assemble과정에서 branch할 주소를 적어야하는데 26비트 밖에 할당할 수가 없다. 따라서 BTA를 계산하기 위한 특별한 방법을 적용해 32비트로 변환을 해야한다.&lt;/p&gt;
&lt;h4 id=&quot;example-5&quot;&gt;Example&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;assembly language-assembly&quot;&gt;.text 0x00400024
.globl main
main:
    nop
    j main&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;beq-rs-rt-l1--bne-rs-rt-l1&quot;&gt;beq rs, rt, L1 / bne rs, rt, L1&lt;/h3&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;code&gt;rs&lt;/code&gt;레지스터와 &lt;code&gt;rt&lt;/code&gt;레지스터를 비교하여 같거나(&lt;code&gt;beq&lt;/code&gt;) 다르다면(&lt;code&gt;bne&lt;/code&gt;) L1에 해당하는 Label로 branch를 한다. 두 개의 레지스터와 branch를 위한 immediate field를 사용하므로 L-format이다.&lt;/p&gt;
&lt;h4 id=&quot;example-6&quot;&gt;Example&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;assembly language-assembly&quot;&gt;    bne $3, $4, Else # 0x00400038
    add $s0, $s1, $s2
    j Exit
Else: sub $s0, $s1, $s2
Exit: add $s0, $s0, $s0&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;branch할 주소를 16비트로 밖에 표현을 못하므로 BTA를 계산을 따로 해야한다. 16비트에 B가 적힌다면 BTA는 &lt;code&gt;B x 4 + PC&lt;/code&gt;가 된다.        &lt;code&gt;B x 4&lt;/code&gt;를 한 후 32비트인 &lt;code&gt;PC&lt;/code&gt;와 덧셈을 하기 위해 Sign Extension을 하게 된다. Example에서 현재 PC값이 0x00400038일 때, 현재 PC와 Else 명령어 사이는 3칸의 차이가 있으므로 3 x 4 + PC를 하면 Else의 주소를 얻을 수 있다. 이러한 계산이 가능한 이유는 PC와 BTA가 서로 local하기 때문이다. &lt;/p&gt;
&lt;h3 id=&quot;slt-rd-rs-rt--slti-rd-rs-constant&quot;&gt;slt rd, rs, rt / slti rd, rs, constant&lt;/h3&gt;
&lt;hr /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;slt rd, rs, rt&lt;/code&gt; : if(R[rs]&amp;lt;R[rt]) R[rd]=1 else R[rd]=0;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;slti rd, rs, constant&lt;/code&gt;: if(R[rs]&amp;lt;constant) R[rd]=1 else R[rd]=0;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;slt&lt;/code&gt; 는 &lt;code&gt;bne&lt;/code&gt;, &lt;code&gt;beq&lt;/code&gt;와 함께 사용하기 위해서 존재한다. &lt;code&gt;if (R[$s3]&amp;lt;R[$s4])&lt;/code&gt;와 같은 명령어는 아래와 같이 표현할 수 있다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;assembly language-assembly&quot;&gt;slt $1, $s3, $S4
bne $1, $0, Target&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;프로그래머의 편의를 위해 pseudo instruction인 &lt;code&gt;blt&lt;/code&gt;를 제공하기도 한다. 즉, &lt;code&gt;blt $s3, $s4, Target&lt;/code&gt;으로 표현 가능.&lt;/p&gt;
&lt;h3 id=&quot;addressing-mode-summary&quot;&gt;Addressing Mode Summary&lt;/h3&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/67682840/136493837-01dab39a-3cce-410e-ad64-3911cf3fdd70.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;h4 id=&quot;1-immediate-addressing&quot;&gt;1. Immediate addressing&lt;/h4&gt;
&lt;p&gt;instruction의 operand가 instruction에 직접 적혀 있는 것을 의미합니다. 예를 들어 &lt;code&gt;addi $t0, $t1, 1&lt;/code&gt;에서 &lt;code&gt;1&lt;/code&gt;은 Immediate addressing을 사용하고 있습니다.&lt;/p&gt;
&lt;h4 id=&quot;2-register-addressing&quot;&gt;2. Register addressing&lt;/h4&gt;
&lt;p&gt;operand가 register에 적혀 있는 것을 의미합니다. 예를 들어 &lt;code&gt;addi $t0, $t1, 1&lt;/code&gt;에서 &lt;code&gt;$t0&lt;/code&gt;은 register addressing을 사용하고 있습니다.&lt;/p&gt;
&lt;h4 id=&quot;3-base-addressing&quot;&gt;3. Base addressing&lt;/h4&gt;
&lt;p&gt;Target address가 Memory에 적혀 있는 것을 의미합니다. 해당 Memory의 주소를 계산하기 위해 base register이 가리키는 주소와 offset을 더해 Memory address를 구합니다. 예를 들어 &lt;code&gt;sw $t1, 0($t2)&lt;/code&gt;은 operand에 &lt;code&gt;t1&lt;/code&gt;값을 저장하기 위해 주소를 구해야 하는데, base register와 offset을 통해 해당 주소에 접근을 합니다.&lt;/p&gt;
&lt;h4 id=&quot;4-pc-relative-addressing&quot;&gt;4. PC-relative addressing&lt;/h4&gt;
&lt;p&gt;Target address가 Memory에 적혀 있는 것을 의미합니다. Base register을 직접 지정해준 &lt;strong&gt;base addressing&lt;/strong&gt; 와는 달리 &lt;code&gt;PC&lt;/code&gt;값을 통해 Target address에 접근합니다. &lt;code&gt;beq&lt;/code&gt;, &lt;code&gt;bne&lt;/code&gt; instruction이 이에 해당합니다.&lt;/p&gt;
&lt;h4 id=&quot;5-pseudodirect-addressing&quot;&gt;5. Pseudodirect addressing&lt;/h4&gt;
&lt;p&gt;Target address가 거의 instruction에 적혀 있는 것을 의미합니다. 32비트의 주소를 완성하기 위해 address에 x4를 한 후, 상위 4비트를 PC값의 상위 4비트로 초기화합니다. J-format instruction에서 주로 사용합니다.&lt;/p&gt;
&lt;h3 id=&quot;procedure-and-stack&quot;&gt;Procedure and Stack&lt;/h3&gt;
&lt;hr /&gt;
&lt;p&gt;Procedure은 함수를 의미합니다. 함수의 호출은 다음 단계를 따릅니다.&lt;/p&gt;
&lt;p&gt;1) Register에 Parameter을 세팅한다. 주로 &lt;code&gt;$a0-$a3&lt;/code&gt; 사용 (부족하면 Stack 사용)&lt;br /&gt;
2) Procedure로 Branch한다&lt;br /&gt;
3) Procedure을 위한 저장공간을 확보합니다.&lt;br /&gt;
4) Procedure 수행&lt;br /&gt;
5) 결과를 Register에 저장합니다. 주로 &lt;code&gt;$v0-$v1&lt;/code&gt; 사용&lt;br /&gt;
6) Caller로 Branch합니다&lt;/p&gt;
&lt;h4 id=&quot;system-call&quot;&gt;System Call&lt;/h4&gt;
&lt;p&gt;OS에 구현된 function을 호출하는 것을 의미합니다. 인자 전달을 위해 &lt;code&gt;$a0-$a3&lt;/code&gt;을 사용하고 함수의 행동을 정의하기 위해 &lt;code&gt;$v0&lt;/code&gt; 레지스터를 사용합니다. 아래는 &lt;code&gt;$v0&lt;/code&gt;에 따른 Syscall의 행동들을 정의한 것입니다. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/67682840/136637899-7b828330-3582-4d0e-95c5-8897838d72b6.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;h4 id=&quot;memory-layout&quot;&gt;Memory Layout&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/67682840/136638055-5cb5d445-6188-4a3a-9050-f9121980723f.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Reserved&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;0~0x0040 0000&lt;/code&gt;에 해당하는 영역. 비어있는 채로 둔다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Text&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Text Segment에 해당하는 부분을 의미한다. 프로그램 수행 코드가 담겨 있다&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. Static data&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Data Segment중 하나. global 변수들을 저장한다. 이를 위해 $gp를 사용&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. Dynamic data&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Data Segment중 하나. Heap이라고 부르며 새로 할당한 변수들을 저장하는 공간이다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5.  Stack&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Data Segment 중 하나. local variable을 저장한다. 이를 위해 $sp 사용.&lt;/p&gt;
&lt;p&gt;❗️ recursive procedure은 PDF 참고&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=OL3qD2c0Db4&quot;&gt;https://www.youtube.com/watch?v=OL3qD2c0Db4&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;translation-and-startup&quot;&gt;Translation and Startup&lt;/h3&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/67682840/136640126-b7880d39-379b-446e-8045-f6e6f97972a5.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;프로그램이 메모리에 로드되기 위해서는 아래의 과정을 따른다.&lt;/p&gt;
&lt;p&gt;1) compiler가 user code를 assembly로 바꾼다&lt;br /&gt;
2) assembler가 assembly를 object module로 바꾼다. machine language에 해당한다.&lt;br /&gt;
3) 여러 object module과 미리 컴파일된 library를 Linker을 통해 Executable로 바꾼다. 이때 Executable은 secondary storage에 저장된다.&lt;br /&gt;
4) secondary storage에 저장된 executable을 Loader을 통해 memory에 load하여 프로그램을 수행한다.&lt;/p&gt;
&lt;h4 id=&quot;object-module&quot;&gt;Object Module&lt;/h4&gt;
&lt;p&gt;Object Module이 제공하는 정보는 다음과 같다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Object file header: Object file의 다른 부분에 대한 정보(size, position)을 저장&lt;/li&gt;
&lt;li&gt;Text segment: user가 작성한 code에 대한 부분&lt;/li&gt;
&lt;li&gt;Static data segment: 프로그램이 수행되면서 계속 access 할수 있는 global variable을 저장한다.&lt;/li&gt;
&lt;li&gt;Relocation information: executable이 메모리에 로드되어 수행될 때, 실제로 어디에 로드 되는지 알 수 없으므로 해당 위치에 따라 달라지는 정보를 저장&lt;/li&gt;
&lt;li&gt;Symbol table: label의 주소를 저장&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;object-file-example&quot;&gt;Object file Example&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/67682840/136640440-689948f0-67c1-4727-b7d7-d90f27f31649.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;빨간색 네모는 object file header로 object file에 대한 정보들을 저장하고 있다. &lt;/li&gt;
&lt;li&gt;Relocation information은 Text Segment중 Relocation이 필요한 주소를 저장하게 된다. &lt;code&gt;lw&lt;/code&gt;은 &lt;code&gt;0($gp)&lt;/code&gt;가 실제로 가리키는 주소를 Link 과정에는 알 수 없으므로 Relocation information에 저장을 하고, &lt;code&gt;jal&lt;/code&gt; 또한 Text Segment의 &lt;code&gt;B&lt;/code&gt; 레이블로 branch를 해야하지만 실제로 가리키는 주소를 Link 과정에는 알 수 없으므로 Relocation information에 저장하게 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;executable-file-example&quot;&gt;Executable file Example&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/67682840/136640680-87479f8c-5568-40c7-9334-adf24bff5ed8.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Relocation information을 통해 주소들이 계산 되었음을 알 수 있습니다. (&lt;code&gt;lw&lt;/code&gt;, &lt;code&gt;jal&lt;/code&gt;)&lt;/p&gt;
&lt;h4 id=&quot;load-program&quot;&gt;Load Program&lt;/h4&gt;
&lt;p&gt;Executable file에는 memory address가 적혀있지만 실제 Loader가 메모리에 어느 부분에 로드할지는 알 수가 없다. 하지만 virtual memory를 사용하면 processor마다 각자의 address를 갖기 때문에 Executable에서 사용한 address를 그대로 사용할 수 있습니다. 즉 Relocation이 필요하지 않게 됩니다.&lt;/p&gt;
&lt;h4 id=&quot;static-link-vs-dynamic-link&quot;&gt;Static Link vs Dynamic Link&lt;/h4&gt;
&lt;p&gt;Static Link는 Executable에 Library Routine을 포함하는 것을 의미합니다. 이에 따라 단점이 존재하게 됩니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Executable의 size가 커질 수 있다.&lt;/li&gt;
&lt;li&gt;Library가 업데이트 되면 다시 Link하는 과정이 필요하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Dynamic Link를 사용하면 위 문제점들을 해결할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/67682840/136640949-8e33bbd2-8924-4906-b6e1-61ff3dfd6a83.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;h3 id=&quot;combinational-elements&quot;&gt;Combinational Elements&lt;/h3&gt;
&lt;hr /&gt;
&lt;p&gt;현재의 입력만으로 출력을 만들어 낸다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/67682840/137150541-042f9a8a-568e-44da-9bc8-6f14ae9bc8b5.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;ALU는 다양한 연산을 사용할 수 있다. 연산의 종류를 결정하기 위해 control input을 사용한다. &lt;/p&gt;
  &lt;p&gt;이와 비슷하게 MUX 또한 출력을 결정하기 위해 control input을 사용한다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;statesequential-elements&quot;&gt;State(Sequential) elements&lt;/h3&gt;
&lt;hr /&gt;
&lt;p&gt;현재의 입력과 이전의 입력으로 출력을 만들어 낸다&lt;/p&gt;
&lt;h4 id=&quot;register&quot;&gt;Register&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;clock signal&lt;/code&gt;에서 rising edge일때 input 데이터를 output에 저장한다. 걸리는 시간을 gate delay라고 한다. input이 변하더라도 &lt;code&gt;clock signal&lt;/code&gt;이 rising edge가 아니라면 출력에 기록하지 않는다. write control이 표시되어 있지 않으면 항상 1이다.&lt;/p&gt;
&lt;h4 id=&quot;register-with-write-control&quot;&gt;Register with write control&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;clock signal&lt;/code&gt;이 rising edge일때 write control을 확인하여 input 데이터를 output에 저장한다. write control이 1일때 데이터를 저장한다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/67682840/137152664-b6807acc-e90f-4d6b-816b-64560cab72a2.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;이를 확장해 32bit register을 만들 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/67682840/137153507-a1e23941-bf50-4285-a804-d168111d16c4.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;h4 id=&quot;instruction-memory&quot;&gt;Instruction memory&lt;/h4&gt;
&lt;p&gt;32비트의 주소를 읽어와 해당 주소에 적힌 instruction을 출력으로 보낸다. 매 cycle마다 출력으로 instruction을 보낸다. rising edge마다 값을 보내는 것이 아님에 유의하자.  &lt;code&gt;Control signal&lt;/code&gt;은 생략되어있다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/67682840/137154448-eb5e82c1-52f0-46b5-b494-05181012ca3f.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;h4 id=&quot;data-memory&quot;&gt;Data memory&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;Memwrite&lt;/code&gt;, &lt;code&gt;Memread&lt;/code&gt; 에 따라 메모리에 데이터를 쓰거나 출력을 하게 된다. 둘 다 동시에 1이 될 수 는 없으나 0은 가능하다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Memwrite&lt;/code&gt;가 1이라면 주소를 읽어와서 해당 주소에 Write data를 쓰게 된다. &lt;/li&gt;
&lt;li&gt;&lt;code&gt;Memread&lt;/code&gt;가 1이라면 읽어온 주소에 저장된 값을 출력으로 보낸다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/67682840/137154991-4a5fa555-c463-4236-932b-164976168afd.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;h4 id=&quot;register-file&quot;&gt;Register File&lt;/h4&gt;
&lt;p&gt;32비트 register가 32개 모여있는 것을 Register file이라고 한다. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Regwrite&lt;/code&gt;의 값이 1일 때만 레지스터에 값을 기록한다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Regread&lt;/code&gt;는 항상 1이여서 clock cycle마다 값을 읽어 출력한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/67682840/137576556-195da375-af7c-41e3-84df-9cc6f29d69d6.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;h3 id=&quot;control-signal&quot;&gt;Control signal&lt;/h3&gt;
&lt;hr /&gt;
&lt;p&gt;Control signal은 조합회로로 만들 수 있다. instruction의 특정 필드를 input으로 하면 output을 얻을 수 있다. &lt;code&gt;i-format&lt;/code&gt;, &lt;code&gt;j-format&lt;/code&gt;은 opcode만 전달하고 &lt;code&gt;r-format&lt;/code&gt;은 추가적으로 &lt;code&gt;funct&lt;/code&gt; 값도 input으로 전달한다.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/67682840/137584958-46599d86-d8b3-4108-932e-f3896630839b.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;h4 id=&quot;example-1-1&quot;&gt;Example 1&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/67682840/137585054-3e9c0c4e-b492-4fae-9752-6eaaff6b2dc9.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;p&gt;1) instruction memory에서 instruction을 읽어온다.&lt;br /&gt;
2) &lt;code&gt;$8&lt;/code&gt;, &lt;code&gt;$9&lt;/code&gt;가 Read register에 쓰인다.&lt;br /&gt;
3) &lt;code&gt;add&lt;/code&gt; 이므로 &lt;code&gt;rd&lt;/code&gt;에 값이 쓰여야한다. RegDst가 1이 된다.&lt;br /&gt;
4) &lt;code&gt;add&lt;/code&gt;이므로 두 개의 레지스터를 ALU에 전달해야한다. ALU의 두 번째 operand는 register의 두번째 read data이므로 ALUSrc는 0이 된다.&lt;br /&gt;
5) Register file의 Write data에 ALU result가 쓰여야 하므로 RegtoMem의 값이 0이된다.&lt;/p&gt;
&lt;h4 id=&quot;example-2-1&quot;&gt;Example 2&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/67682840/137585870-ed64e957-9ea6-4f42-a92d-00c88a5776d6.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Read register에 &lt;code&gt;rs&lt;/code&gt;필드를 읽어온다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rt&lt;/code&gt;필드에 저장이 되어야하므로 RegDst 값은 0이 된다.&lt;/li&gt;
&lt;li&gt;주소를 계산해야하므로 ALU의 두 번째 operand는 &lt;code&gt;imm&lt;/code&gt; 필드가 되어야한다. ALUSrc는 1이 된다.&lt;/li&gt;
&lt;li&gt;Memory에서 읽어온 값을 Register file의 Write data에 기록해야하므로 MemtoReg는 1이 된다.&lt;/li&gt;
&lt;li&gt;주소계산을 위해 &lt;code&gt;add&lt;/code&gt;를 사용해야므로 ALU control는 &lt;code&gt;add&lt;/code&gt;를 의미하는 &lt;code&gt;0010&lt;/code&gt;을 출력해야한다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;lw&lt;/code&gt;에서 ALUop값으로 &lt;code&gt;00&lt;/code&gt;을 전달하고 이를 통해 &lt;code&gt;0010&lt;/code&gt;을 만들어 낸다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&quot;example-3&quot;&gt;Example 3&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/67682840/137585967-b4c904bb-2ad8-423b-9bd0-2792ef2a3f53.png&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;두 개의 레지스터 값을 비교해야하므로 Read register 1,2 값을 읽는다.&lt;/li&gt;
&lt;li&gt;ALU의 두 번째 operand는 레지스터로부터 오기 때문에 ALUSrc의 값은 0이 된다.&lt;/li&gt;
&lt;li&gt;출력되는 Zero control signal에 따라 PC값을 결정한다.&lt;/li&gt;
&lt;li&gt;branch instruction을 보고 적절한 ALUop값을 전달한다.&lt;/li&gt;
&lt;/ol&gt; &lt;/article&gt;</description>
      <category>학교</category>
      <author>devbelly</author>
      <guid isPermaLink="true">https://devbelly.tistory.com/279</guid>
      <comments>https://devbelly.tistory.com/279#entry279comment</comments>
      <pubDate>Sat, 30 Oct 2021 22:53:35 +0900</pubDate>
    </item>
    <item>
      <title>[디자인패턴] 인터페이스 분리 원칙(ISP)</title>
      <link>https://devbelly.tistory.com/273</link>
      <description>&lt;div class=&quot;markdown-body&quot;&gt;
  &lt;!doctype html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset='UTF-8'&gt;&lt;meta name='viewport' content='width=device-width initial-scale=1'&gt;
&lt;title&gt;인터페이스 분리 원칙(ISP)&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;&lt;h1 id='인터페이스-분리-원칙isp'&gt;인터페이스 분리 원칙(ISP)&lt;/h1&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;클라이언트는 자신이 이용하지 않는 메서드에 의존하지 않아야 한다는 원칙이다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;클라이언트는 자신이 사용하지 않는 메소드에 의존하도록 강제될 때, 인터페이스가 변경되면 클라이언트 또한 영향을 받기 마련이다. 이러한 결합을 낮추기 위해 거대한 인터페이스를 분리해서 사용할 수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/67682840/138555511-d51a43c8-0bce-4898-91bb-5f4581fcba7c.png&quot; referrerpolicy=&quot;no-referrer&quot; alt=&quot;Untitled Diagram drawio&quot;&gt;&lt;/p&gt;
&lt;p&gt;세 개의 클라이언트에서 &lt;code&gt;employee&lt;/code&gt; 를 사용하고 있는 모습입니다. 앞선 원칙들에 따라 &lt;code&gt;employee&lt;/code&gt;에서의 변경이 모든 클라이언트들에게 영향을 미치므로 DIP원칙에 따라 인터페이스를 생성합니다. 즉 컴파일 의존성은 클라이언트들은 인터페이스로 이동하지만 런타임 의존성은 여전히 &lt;code&gt;employee&lt;/code&gt;에 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/67682840/138555770-6155bdcf-3fdb-479a-ab22-9cc9e5f27c19.png&quot; referrerpolicy=&quot;no-referrer&quot; alt=&quot;Untitled Diagram drawio (1)&quot;&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;employee&lt;/code&gt; 의 변경이 클라이언트에 영향을 미치지 않지만 인터페이스가 변경이 된다면 클라이언트들은 여전히 영향을 받게 됩니다. 만일 &lt;code&gt;methodForA()&lt;/code&gt; 에서 파라미터를 변경했다면 해당 메서드를 사용하지 않는 &lt;code&gt;B&lt;/code&gt;와 &lt;code&gt;C&lt;/code&gt; 또한 영향을 받게 됩니다. 이러한 상황에서 ISP를 통해 문제를 해결합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/67682840/138555957-591d1a16-3572-4636-8919-8eff7c3d2d65.png&quot; referrerpolicy=&quot;no-referrer&quot; alt=&quot;Untitled Diagram drawio (2)&quot;&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;클래스가 모든 클라이언트 고유의 인터페이스를 상속하고 그것을 구현함으로써 클라이언트간의 불필요한 의존성을 끊고 독립적으로 만들 수 있다. 인터페이스가 불가피하게 변경되어야한다면 직접 인터페이스를 변경하는 대신 새로운 인터페이스를 생성하도록 해 재컴파일과 재배포를 피할 수도 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;
&lt;/div&gt;</description>
      <category>Design Patterns</category>
      <author>devbelly</author>
      <guid isPermaLink="true">https://devbelly.tistory.com/273</guid>
      <comments>https://devbelly.tistory.com/273#entry273comment</comments>
      <pubDate>Wed, 27 Oct 2021 14:36:24 +0900</pubDate>
    </item>
    <item>
      <title>[디자인패턴] 의존 관계 역전 원칙(DIP)</title>
      <link>https://devbelly.tistory.com/272</link>
      <description>&lt;div class=&quot;markdown-body&quot;&gt;
  &lt;!doctype html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset='UTF-8'&gt;&lt;meta name='viewport' content='width=device-width initial-scale=1'&gt;
&lt;title&gt;의존 관계 역전 원칙(DIP)&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;&lt;h1 id='의존-관계-역전-원칙dip'&gt;의존 관계 역전 원칙(DIP)&lt;/h1&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;상위 수준의 모듈은 하위 수준의 모듈에 의존해서는 안된다. 둘 모두 추상화에 의존해야한다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;기존 절차지향적 프로그래밍에서는 상위수준의 모듈이 하위수준의 모듈에 의존하는 경향이 있었다. 이러한 의존성을 역전시켜 상위수준의 모듈이 하위수준의 모듈에 의존하지 않도록 하는 원칙이다. 의존성을 역전시키는 방법은 상위 모듈과 하위 모듈 둘 다 추상화에 의존하게 하는 것이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Abstraction vs Encapsulation&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Abstraction과 Encapsulation의 관계는 상호보완적이라 볼 수 있다. Abstraction은 객체의 행동에 초점을 맞추어 공통적인 부분을 묶어낸 것이라면 Encapsulation은 이러한 행동을 뒷받침해주는 Implementation에 초점을 맞춘 것이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이에 따라 클래스를 구현할 때는 아래의 원칙을 지켜야 한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;어떤 변수도 구체 클래스에 대한 포인터나 참조값을 가져선 안 된다.&lt;/li&gt;
&lt;li&gt;어떤 클래스도 구체 클래스에서 파생되어서는 안 된다.&lt;/li&gt;
&lt;li&gt;어떤 메소드도 그 기반 클래스에서 구현된 메소드를 오버라이드해서는 안된다.&lt;/li&gt;

&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id='example'&gt;Example&lt;/h3&gt;
&lt;pre&gt;&lt;code class='language-c++' lang='c++'&gt;class Switch{
	private Light light;
    void activate(){
		light.turnOn();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;Switch&lt;/code&gt; 클래스를 통해 &lt;code&gt;Light&lt;/code&gt; 클래스를 켜는 코드입니다. &lt;code&gt;Switch&lt;/code&gt;와 &lt;code&gt;Light&lt;/code&gt; 클래스만을 사용하는 경우를 한정하여서 코드의 재사용이 가능합니다. 결국 재사용이 불가능한 상태입니다. 문제가 발생한 원인은 상위 클래스가 직접적으로 &lt;code&gt;Light&lt;/code&gt;라는 타입을 변수로 갖기 때문입니다. 이를 해결하기 위해 &lt;code&gt;turnOn()&lt;/code&gt;이 가능한 것들을 추상화하여 사용해야합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre&gt;&lt;code class='language-c++' lang='c++'&gt;class Switch{
	Lightable light;
	void activate(){
		light.turnOn();
	}
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;직접적인 &lt;code&gt;Light&lt;/code&gt;클래스에 의존하는 대신 &lt;code&gt;Lightable&lt;/code&gt;이라는 추상화된 인터페이스에 의존하도록 변경했습니다. 상위 모듈이 하위모듈에 직접 의존하지 않으므로 DIP가 실현되었습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;
&lt;/div&gt;</description>
      <category>Design Patterns</category>
      <author>devbelly</author>
      <guid isPermaLink="true">https://devbelly.tistory.com/272</guid>
      <comments>https://devbelly.tistory.com/272#entry272comment</comments>
      <pubDate>Wed, 27 Oct 2021 14:35:33 +0900</pubDate>
    </item>
    <item>
      <title>[디자인패턴] 리스코프 치환 원칙(LSP)</title>
      <link>https://devbelly.tistory.com/271</link>
      <description>&lt;div class=&quot;markdown-body&quot;&gt;
&lt;!doctype html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset='UTF-8'&gt;&lt;meta name='viewport' content='width=device-width initial-scale=1'&gt;
&lt;title&gt;리스코프 치환 원칙(LSP)&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;&lt;h1 id='리스코프-치환-원칙lsp'&gt;리스코프 치환 원칙(LSP)&lt;/h1&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;서브타입은 그것의 기반타입으로 치환가능해야한다.&lt;/p&gt;
&lt;p&gt;타입 S의 객체 o1과 타입 T의 객체 o2가 있을 때, T로 프로그램 P를 정의했음에도 불구하고 o2를 o1으로 치환할 때 P의 행위가 변하지 않으면, S는 T의 서브타입이다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;리스코프 치환 원칙(LSP)는 개발자가 서브 클래스를 작성하기 위한 원칙을 제공합니다. 아래 LSP를 위반한 원칙들을 통해 자세히 알아봅시다.&lt;/p&gt;
&lt;h3 id='example-1'&gt;Example 1.&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/67682840/138415488-9689ac05-0fa5-463d-a62f-8b5a4e55c789.png&quot; referrerpolicy=&quot;no-referrer&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;DrawShape()&lt;/code&gt; 함수를 살펴보면 OCP를 위반하고 있다는 것을 알 수 있다. &lt;code&gt;DrawShape()&lt;/code&gt;는 메서드에서 사용할 모든 &lt;code&gt;Shape&lt;/code&gt;의 서브 타입에 대해 알고 있어야 하기 때문이다. 만일 &lt;code&gt;Triangle&lt;/code&gt;  타입을 추가하고 싶다면 소스코드의 변경없이는 확장이 불가능하다.&lt;/p&gt;
&lt;p&gt;이는 &lt;code&gt;Circle&lt;/code&gt;와 &lt;code&gt;Square&lt;/code&gt;이 &lt;code&gt;Shape&lt;/code&gt;를 상속하기는 하지만 &lt;code&gt;Draw()&lt;/code&gt;함수를 오버라이드하지 않아 발생한 문제이다. 즉, &lt;code&gt;Shape&lt;/code&gt;의 서브 타입을 일일이 검사하여 각 클래스가 무엇인지 파악한 후 그에 맞는 함수를 호출한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id='example-2'&gt;Example 2.&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/67682840/138541292-29413450-3fab-4aa9-9277-561270564d5c.png&quot; referrerpolicy=&quot;no-referrer&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;정사각형과 직사각형은 &lt;code&gt;is-a&lt;/code&gt;관계로 표현될 수 있다. 정사각형은 직사각형이기 때문이다. 그래서 &lt;code&gt;Rectangle&lt;/code&gt; 클래스를 상속하여 &lt;code&gt;Square&lt;/code&gt; 클래스를 만드는 것은 문제가 되지 않을 것이라고 생각이 된다. &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;문제점 1&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;상속을 하고 보니 &lt;code&gt;Square&lt;/code&gt;클래스에서는 사용하지 않는 함수들이 존재함을 알 수 있다. 예를 들어 &lt;code&gt;SetHeight()&lt;/code&gt;나 &lt;code&gt;SetWidth()&lt;/code&gt;를 둘 다 사용할 필요는 없다. 즉 퇴화함수가 발생하는데 이는 잠정적인 LSP 위반이다. 일단 이 문제를 메서드 오버라이딩을 사용하여 해결했다고 치자.&lt;/p&gt;
&lt;pre&gt;&lt;code class='language-c++' lang='c++'&gt;void Square :: setWidth(double w){
	Rectangle :: SetWidth(w);
	Rectangle :: SetHeight(w);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;문제점 2&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;이제 프로그래머는 상속의 장점중 하나인 다형성을 활용하기 위해 다음의 함수를 작성했다.&lt;/p&gt;
&lt;pre&gt;&lt;code class='language-c++' lang='c++'&gt;void f(Rectangle&amp;amp; r){
	r.setWidth(32);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;setWidth()&lt;/code&gt;가 virtual로 선언이 되어있지 않아 함수가 정적 바인딩이 된 상태이다. 이 상태에서는 &lt;code&gt;Rectangle :: setWidth()&lt;/code&gt; 가 호출이 되므로 다형성을 제대로 실현하지 못하게 된다. 결국 부모 클래스의 코드를 직접 수정하는 상황이 발생하므로 OCP를 위반하는 상황이다. 이 문제 또한 코드를 수정하여 해결했다고 치자.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;문제점 3&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;이제 &lt;code&gt;Rectangle&lt;/code&gt; 클래스를 클라이언트에서 사용을 해보자. 해당 클래스를 가져와 다음 함수를 작성했다고 해보자.&lt;/p&gt;
&lt;pre&gt;&lt;code class='language-c++' lang='c++'&gt;void g(Rectangle&amp;amp; r){
	r.setWidth(10);
	r.setHeight(5);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;클라이언트는 &lt;code&gt;r&lt;/code&gt;의 넓이가 50이 될 것을 기대하지만 이는 &lt;code&gt;r&lt;/code&gt;이 &lt;code&gt;Square&lt;/code&gt;이라면 제대로 작동하지 않을 것이다. 왜 이러한 문제가 발생한걸까?&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id='계약에-의한-설계'&gt;계약에 의한 설계&lt;/h3&gt;
&lt;p&gt;Design by Contract은 메소드의 사전조건과 사후조건을 선언하는 것으로 구체화된다. 사전조건과 사후조건에 대한 규칙은 다음과 같다.&lt;/p&gt;
&lt;ol start='' &gt;
&lt;li&gt;하위형에서 선행조건은 강화될 수 없다.&lt;/li&gt;
&lt;li&gt;하위형에서 후행조건은 약화될 수 없다.&lt;/li&gt;

&lt;/ol&gt;
&lt;p&gt;위 사례에서는 후행조건이 약화되었다고 볼 수 있다. &lt;code&gt;Rectangle :: setWidth(input)&lt;/code&gt;에서의 후행조건은 &lt;code&gt;itsWidth==input &amp;amp;&amp;amp; itsHeight==prevHeight&lt;/code&gt; 이지만 &lt;code&gt;Square :: setWidth(input)&lt;/code&gt;에서는 &lt;code&gt;itsHeight==prevHeight&lt;/code&gt;의 조건을 충족하지못하므로 후행조건이 약화되었다.&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;
&lt;/div&gt;</description>
      <category>Design Patterns</category>
      <author>devbelly</author>
      <guid isPermaLink="true">https://devbelly.tistory.com/271</guid>
      <comments>https://devbelly.tistory.com/271#entry271comment</comments>
      <pubDate>Wed, 27 Oct 2021 14:12:10 +0900</pubDate>
    </item>
    <item>
      <title>[디자인패턴] 개방 폐쇄 원칙(OCP)</title>
      <link>https://devbelly.tistory.com/270</link>
      <description>&lt;div class=&quot;markdown-body&quot;&gt;
&lt;!doctype html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset='UTF-8'&gt;&lt;meta name='viewport' content='width=device-width initial-scale=1'&gt;
&lt;title&gt;개방 폐쇄 원칙(OCP)&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;&lt;h1 id='개방-폐쇄-원칙ocp'&gt;개방 폐쇄 원칙(OCP)&lt;/h1&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;소프트웨어 개체(클래스, 모듈, 함수)는 확장에 대해 열려 있어야 하고, 수정에 대해서는 닫혀 있어야한다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;개방 폐쇄 원칙을 따르는 모듈은 다음과 같은 두 가지 속성을 갖는다.&lt;/p&gt;
&lt;h4 id='1-확장에-대해-열려-있다'&gt;1. 확장에 대해 열려 있다.&lt;/h4&gt;
&lt;p&gt;이것은 모듈의 행위가 확장될 수 있음을 의미한다. 요구사항이 변경될 때, 이 변경에 맞춰 새로운 행위를 추가해 모듈을 확장할 수 있다. 새로운 타입을 추가함으로써 새로운 기능을 추가하는 것과 같다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 id='2-수정에-대해-닫혀-있다'&gt;2. 수정에 대해 닫혀 있다.&lt;/h4&gt;
&lt;p&gt;어떤 모듈을 확장하는 것은 소스코드나 바이너리 코드의 변경을 초래하지 않는다. 이는 확장이 일어날 때 상위 레벨이 영향을 받지 말아야 한다는 것이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;HOW?&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;이는 모순된 것처럼 보인다. 어떻게 소스 코드를 변경하지 않고도 그 모듈의 행위를 바꾸는 일이 가능한걸까? 정답은 &lt;em&gt;Abstraction을 통한 inversion&lt;/em&gt;에 있다. &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Abstraction?&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Abstraction is the &lt;strong&gt;process by which data and programs are defined&lt;/strong&gt; with a representation similar in form to its meaning, while hiding away the implementation details.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;추상화는 추상 기반 클래스이자, 모든 가능한 파생 클래스를 대표하는 가능한 행위의 묶음이기도 하다.상위 모듈을 고정된 추상화에 의존하면 상위 모듈은 수정에 대해 닫혀 있는 것이 가능하게 된다. 그리고 그 모듈의 행위는 추상화의 새 파생 클래스를 만듦으로써 확장에 대해서는 열려 있게 된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/67682840/138405203-5c975680-d6a7-43d1-9348-768dfd5be3bf.png&quot; referrerpolicy=&quot;no-referrer&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;위 그림은 OCP를 위반한 예시이다. 만일 &lt;code&gt;Client&lt;/code&gt;객체가 새로운 &lt;code&gt;Server&lt;/code&gt;객체를 사용하도록 바꾸고 싶다면 &lt;code&gt;Client&lt;/code&gt; 클래스를 수정하여 다른 &lt;code&gt;Server&lt;/code&gt;클래스를 사용하도록 바꿔야하므로 수정에 대해 닫혀있지 않게 된다. 즉 OCP를 위반하게 된다. &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/67682840/138405490-2874542f-b23e-4229-8da7-3663977b225c.png&quot; referrerpolicy=&quot;no-referrer&quot; alt=&quot;image&quot;&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;위에서 제시된 문제점을  스트레티지 패턴을 사용함으로써 해결했다. 확장이 필요한 부분에 Abstraction을 적용하여 상위모듈이 고정된 추상화에 의존하도록 했다. 만일 새로운 &lt;code&gt;server&lt;/code&gt;객체를 사용하고 싶다면 &lt;code&gt;Client Interface&lt;/code&gt;를 구현한 새로운 클래스를 추가하도록 하면 된다. &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;장점?&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;이렇게 수정하면 &lt;strong&gt;경직성&lt;/strong&gt;의 문제가 사라진다. 경직성이란 단순한 방법으로도 소프트웨어를 변경하기 어려운 것을 의미한다. 한 군데의 변경이 다른 의존적인 모듈의 변경을 일으킬 때 경직성의 문제가 있다고 한다. &lt;code&gt;Client&lt;/code&gt;가 고정된 추상화에 의존하므로 하위 모듈의 변경이 상위 모듈에 영향을 미치지 않는다. &lt;/p&gt;
&lt;p&gt;또한 &lt;strong&gt;부동성&lt;/strong&gt;이 없다. 부동성이란 원하는 부분을 모듈로부터 분리해내어 다른 곳에서 사용할수 있는 것을 의미한다. 추상화를 구현한 서브 클래스는 재활용이 가능하므로 부동성 문제도 해결할 수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;단점?&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;그렇다면 우리는 변경될 부분을 미리 예측하여 추상화를 해놓아야 하는걸까? 변경될 부분이 무엇인지 미리 안다면 우리는 해당 부분을 추상화 하면 되지만 실제로 서비스하기 전까지는 어느 부분에 변경이 필요한지 예측하기 어렵다. 또한 미리 추상화를 다 했다 하더라도 이는 불필요한 복잡성만 증가할 뿐이다. &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id='solution'&gt;Solution&lt;/h3&gt;
&lt;p&gt;Agile Design에서는 아래와 같은 해결책을 제시한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;아주 짧은 주기로 개발한다.&lt;/li&gt;
&lt;li&gt;소프트웨어를 빨리 그리고 자주 릴리즈한다.&lt;/li&gt;

&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;지레 겁 먹고 모든 부분을 추상화하는 대신, 빠르게 개발하여 변화가 필요한 부분을 체감한 뒤 해당 부분을 추상화하도록 하면 필요한 부분에 대해 추상화를 할 수 있다.&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;
&lt;/div&gt;</description>
      <category>Design Patterns</category>
      <author>devbelly</author>
      <guid isPermaLink="true">https://devbelly.tistory.com/270</guid>
      <comments>https://devbelly.tistory.com/270#entry270comment</comments>
      <pubDate>Wed, 27 Oct 2021 14:08:44 +0900</pubDate>
    </item>
    <item>
      <title>[백준 1028] 다이아몬드 광산</title>
      <link>https://devbelly.tistory.com/266</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;문제&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/1028&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/1028&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;알고리즘&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;DP&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;풀이&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;2차원 광산이 주어질 때, 광산의 최대 크기를 구하는 문제입니다.&lt;/span&gt;&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;&lt;span style=&quot;color: #333333;&quot;&gt;단순하게 브루트포스로 접근한다면 임의의 점을 광산의 최상단으로 잡은 후 네 변이 만들어 질 수 있나 검사를 해보면 됩니다. 모든 점을 최상단으로 검사하기 위해서는 $O(RC)$ 의 시간복잡도가 필요하고 추가적으로 네 변을 검사하기 위해서 선형시간만큼의 복잡도가 더 필요합니다.&amp;nbsp;&lt;/span&gt;&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;&lt;span style=&quot;color: #333333;&quot;&gt;위 계산법에서 낭비되는 부분을 줄여야합니다. 최상단 점 (i, j)에서 len 길이를 만들 때 오른쪽 상단변을 계산하는 과정은 (i+1,j+1)에서 len-1 길이를 만들 때 오른쪽 상단변을 계산하는 과정과 겹치게 됩니다. 즉 DP를 이용합시다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;$lcache[i][j]$ : i, j에서 왼쪽으로 만들 수 있는 최대 길이&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;$rcache[i][j]$: i, j에서 오른쪽으로 만들 수 있는 최대 길이&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;이 배열을 선언하면 광산의 만들어지는 네 점을 빠르게 검사할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;코드&lt;/span&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1633142668402&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;bits/stdc++.h&amp;gt;
#define rep(i, n) for (int i = 0; i &amp;lt; n; ++i)
#define REP(i, n) for (int i = 1; i &amp;lt;= n; ++i)
using namespace std;

const int MAXR = 750 + 5;

int R, C, ans, arr[MAXR][MAXR], rcache[MAXR][MAXR], lcache[MAXR][MAXR];

int main() {
#ifndef ONLINE_JUDGE
    freopen(&quot;in&quot;, &quot;r&quot;, stdin);
    freopen(&quot;out&quot;, &quot;w&quot;, stdout);
#endif
    cin.tie(NULL);
    cout.tie(NULL);
    ios::sync_with_stdio(false);

    cin &amp;gt;&amp;gt; R &amp;gt;&amp;gt; C;
    REP(i, R)
    REP(j, C) {
        char x;
        cin &amp;gt;&amp;gt; x;
        arr[i][j] = (x == '1' ? 1 : 0);
    }
    for (int i = R; i &amp;gt;= 1; --i)
        for (int j = C; j &amp;gt;= 1; --j) {
            if (!arr[i][j]) continue;
            rcache[i][j] = rcache[i + 1][j + 1] + arr[i][j];
        }

    for (int i = R; i &amp;gt;= 1; --i)
        for (int j = C; j &amp;gt;= 1; --j) {
            if (!arr[i][j]) continue;
            lcache[i][j] = lcache[i + 1][j - 1] + arr[i][j];
        }

    for (int len = 375; ~len; --len) {
        REP(i, R) {
            if (i + 2 * len - 2 &amp;lt;= R) {
                REP(j, C) {
                    if (j - len + 1 &amp;gt;= 1 &amp;amp;&amp;amp; j + len - 1 &amp;lt;= C) {
                        if (rcache[i][j] &amp;gt;= len &amp;amp;&amp;amp; lcache[i + len - 1][j + len - 1] &amp;gt;= len &amp;amp;&amp;amp; lcache[i][j] &amp;gt;= len &amp;amp;&amp;amp; rcache[i + len - 1][j - len + 1] &amp;gt;= len) {
                            cout &amp;lt;&amp;lt; len;
                            return 0;
                        }
                    }
                }
            }
        }
    }
    cout &amp;lt;&amp;lt; ans;
    return 0;
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Algorithm</category>
      <category>DP</category>
      <author>devbelly</author>
      <guid isPermaLink="true">https://devbelly.tistory.com/266</guid>
      <comments>https://devbelly.tistory.com/266#entry266comment</comments>
      <pubDate>Sat, 2 Oct 2021 11:45:34 +0900</pubDate>
    </item>
    <item>
      <title>[백준 3078] 좋은 친구</title>
      <link>https://devbelly.tistory.com/265</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;문제&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/3078&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/3078&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;알고리즘&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;h2 data-ke-size=&quot;size26&quot;&gt;풀이&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위치가 K+1이상 벗어나지 않으면서 이름의 길이가 같은 쌍의 갯수를 찾는 문제입니다.&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;$N$제한이 30만이므로 $O(N^2)$을 사용해서 순서쌍을 찾기는 어렵습니다. 스택과 비슷한 느낌으로 현재 자신과 같은 길이가 이전에 몇개 있었는지를 기록하여 $O(N)$에 풀도록 합시다. 단 이것을 기록한 배열은 유효한(서로 친구)값만을 유지하기 위해서 위치 차이가 K가 넘어가면 해당 정보를 지우는 업데이트를 하면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;코드&lt;/h2&gt;
&lt;pre id=&quot;code_1632984279569&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;bits/stdc++.h&amp;gt;
#define rep(i, n) for (int i = 0; i &amp;lt; n; ++i)
#define REP(i, n) for (int i = 1; i &amp;lt;= n; ++i)
using namespace std;

const int MAXN = 3e5 + 5;

int N, K;
int c[21], nm[MAXN];
long long ans;
int main() {
#ifndef ONLINE_JUDGE
    freopen(&quot;in&quot;, &quot;r&quot;, stdin);
    freopen(&quot;out&quot;, &quot;w&quot;, stdout);
#endif
    cin.tie(NULL);
    cout.tie(NULL);
    ios::sync_with_stdio(false);

    cin &amp;gt;&amp;gt; N &amp;gt;&amp;gt; K;
    rep(i, N) {
        string s;
        cin &amp;gt;&amp;gt; s;
        nm[i] = s.length();
    }
    rep(i, N) {
        if (i &amp;gt;= K + 1) c[nm[i - K - 1]] -= 1;
        ans += c[nm[i]];
        c[nm[i]] += 1;
    }
    cout &amp;lt;&amp;lt; ans;
    return 0;
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Algorithm</category>
      <category>implementation</category>
      <author>devbelly</author>
      <guid isPermaLink="true">https://devbelly.tistory.com/265</guid>
      <comments>https://devbelly.tistory.com/265#entry265comment</comments>
      <pubDate>Thu, 30 Sep 2021 15:45:44 +0900</pubDate>
    </item>
  </channel>
</rss>