Full beginner lecture
C Bits Number Representation
Intuition
컴퓨터 안에는 decimal 숫자나 minus sign이 그대로 들어가지 않습니다. register와 memory에는 정해진 폭의 bit pattern만 들어갑니다. 같은 11111111도 8-bit unsigned로 읽으면 255이고, 8-bit Zweierkomplement signed로 읽으면 -1입니다. 그래서 RO에서 가장 먼저 할 일은 값과 표현을 분리하는 것입니다.
Rule
항상 세 질문을 먼저 씁니다. 몇 bit인가. signed인가 unsigned인가. memory 문제인가 register 값 문제인가. n-bit unsigned range는 0..2^n-1입니다. n-bit Zweierkomplement range는 -2^(n-1)..2^(n-1)-1입니다. negative value는 같은 width 안에서 invert plus one으로 만들고, 더 큰 width로 옮길 때 signed value는 sign extension을 합니다.
Pointer arithmetic은 byte arithmetic이 아니라 element arithmetic입니다. int *p에서 p + 1은 보통 address + 4입니다. RISC-V memory는 byte-addressed이므로 실제 memory dump는 byte 단위로 봅니다. Little-Endian은 least significant byte를 가장 낮은 address에 저장한다는 규칙입니다.
Visual Block
8-bit Zweierkomplement weights
bit: 7 6 5 4 3 2 1 0
weight -128 64 32 16 8 4 2 1
pattern 1111 1011
signed = -128 + 64 + 32 + 16 + 8 + 2 + 1 = -5
unsigned = 128 + 64 + 32 + 16 + 8 + 2 + 1 = 251
Little-Endian store of 0x12345678 at base 0x1000
address byte
0x1000 0x78
0x1001 0x56
0x1002 0x34
0x1003 0x12
Register value is still 0x12345678.
Only the memory byte order changed.
Worked Example 1
Problem. Represent -37 as 8-bit Zweierkomplement and read the same pattern as unsigned.
- Write +37 as 8-bit binary.
37 = 32 + 4 + 1, so 0010 0101. - Invert all bits.
1101 1010. - Add one.
1101 1011. - Check as signed.
-128 + 64 + 16 + 8 + 2 + 1 = -37. - Read the same pattern as unsigned.
128 + 64 + 16 + 8 + 2 + 1 = 219.
Answer. signed value -37 is 11011011 = 0xDB. The same 8 bits as unsigned mean 219.
Worked Example 2
Problem. int a[] starts at 0x1000, sizeof(int)=4. Find a[3] and store 0x12345678 there in Little-Endian order.
- Array address uses
base + index * sizeof(element). a[3] = 0x1000 + 3*4 = 0x100C.- Split the value into bytes from most significant to least significant.
12 34 56 78. - Little-Endian puts least significant byte first.
- Memory becomes
0x100C:78, 0x100D:56, 0x100E:34, 0x100F:12.
Boolesche Logik와 Halb-/Volladdierer
입문자 연결
Bit 하나는 0 또는 1이고, logic gate는 입력 bit로 출력 bit를 만드는 작은 규칙입니다. Boolesche Logik를 계산할 때는 숫자의 크기보다 각 gate의 truth condition을 먼저 봅니다.
| Gate / German term | 기호 | 출력이 1인 조건 |
|---|
| NOT / Negation | ¬A 또는 !A | A가 0 |
| AND / Konjunktion | A ∧ B | A와 B가 모두 1 |
| OR / Disjunktion | A ∨ B | 둘 중 하나 이상이 1 |
| XOR / Exklusiv-ODER | A ⊕ B | 두 입력이 서로 다름 |
XOR는 “둘 중 정확히 하나가 1”이라는 점이 addition과 연결됩니다. 두 1을 더하면 현재 bit의 Summe는 0이고 다음 자리로 carry 1이 나가기 때문입니다.
A B | A AND B | A OR B | A XOR B
0 0 | 0 | 0 | 0
0 1 | 0 | 1 | 1
1 0 | 0 | 1 | 1
1 1 | 1 | 1 | 0
Halbaddierer와 Volladdierer
Halbaddierer(Half Adder)는 두 bit A, B만 더합니다.
S = A XOR B
C = A AND B
S는 현재 자리 Summe, C는 다음 자리 Übertrag(carry)입니다. 이전 자리에서 들어오는 carry input이 없어서 “half”입니다.
Volladdierer(Full Adder)는 A, B, 이전 자리의 Cin 세 bit를 더합니다. Übung 0 Musterlösung의 최소 gate 구조처럼 중간값 P=A XOR B를 재사용하면:
P = A XOR B
S = P XOR Cin
Cout = (A AND B) OR (P AND Cin)
| A | B | Cin | S | Cout |
|---|
| 0 | 0 | 0 | 0 | 0 |
| 0 | 0 | 1 | 1 | 0 |
| 0 | 1 | 0 | 1 | 0 |
| 0 | 1 | 1 | 0 | 1 |
| 1 | 0 | 0 | 1 | 0 |
| 1 | 0 | 1 | 0 | 1 |
| 1 | 1 | 0 | 0 | 1 |
| 1 | 1 | 1 | 1 | 1 |
빠른 검산은 A+B+Cin = S + 2*Cout입니다. 예를 들어 1+1+1=3이고 출력 S=1, Cout=1이면 1+2=3이라 맞습니다.
Worked Trace: 4-bit ripple addition
0101₂ + 0011₂를 LSB(bit 0)부터 Volladdierer로 계산합니다. 첫 Cin=0입니다.
| bit | A | B | Cin | S | Cout |
|---|
| 0 | 1 | 1 | 0 | 0 | 1 |
| 1 | 0 | 1 | 1 | 0 | 1 |
| 2 | 1 | 0 | 1 | 0 | 1 |
| 3 | 0 | 0 | 1 | 1 | 0 |
아래 bit의 Cout가 바로 위 bit의 Cin이 됩니다. 결과 bit를 bit 3부터 읽으면 1000₂=8입니다. decimal 검산도 5+3=8입니다.
변형 문제
0111₂ + 0001₂를 같은 방식으로 더하고 각 carry를 쓰세요.
정답·검산 확인
bit 0: 1+1+0 -> S0=0, C1=1
bit 1: 1+0+1 -> S1=0, C2=1
bit 2: 1+0+1 -> S2=0, C3=1
bit 3: 0+0+1 -> S3=1, C4=0
result = 1000₂
검산: 7+1=8. Carry가 bit 0에서 생겨 bit 3까지 연쇄되는 것이 ripple carry입니다.
Active Recall
Q1. A=1, B=1인 Halbaddierer의 S와 C는 무엇인가요?
정답 확인
S=0, C=1입니다.
Q2. Volladdierer에 세 번째 입력 Cin이 필요한 이유는 무엇인가요?
정답 확인
낮은 자리 addition에서 나온 carry를 현재 자리에 더해야 하기 때문입니다.
Q3. Cout=(A AND B) OR ((A XOR B) AND Cin)을 말로 설명해 보세요.
정답 확인
A와 B가 둘 다 1이거나, A/B 중 하나만 1인 상태에서 Cin도 1이면 다음 자리 carry가 생긴다는 뜻입니다.
Q4. A+B+Cin = S+2*Cout 검산에서 오른쪽의 2가 필요한 이유는 무엇인가요?
정답 확인
Cout은 현재 자리보다 한 자리 높은 bit라서 현재 자리 값의 두 배 무게를 가지기 때문입니다.
근거: current:Uebung\Übung 0.pdf, pages 1-3의 Boolesche Logik와 Volladdierer 과제; current:Uebung\Übung 0 Musterlösung.pdf, pages 1-4의 truth table, XOR/AND/OR gate Volladdierer Lösung.
Common Mistakes
- Treating
0xFF as always 255 or always -1. Width and signedness decide the interpretation. - Using
pointer + 1 = address + 1 byte for every pointer type. The element size matters. - Saying Little-Endian reverses the numeric value. It only chooses the memory byte order.
- Checking signed overflow with carry out only. For signed addition, same signs producing the opposite sign is the fast warning.
- OR와 XOR를 같은 것으로 계산합니다. 입력이
1,1일 때 OR은 1이지만 XOR는 0입니다. - Full Adder에서
Cin을 빼먹습니다. bit 0을 제외한 높은 자리는 바로 아래 자리의 Cout을 받아야 합니다.
Active Recall
- What is the range of 8-bit unsigned and 8-bit signed Zweierkomplement.
- Read
1000 0000 as unsigned and as signed. - If
char *p=0x2000, what is p+3. If int *p=0x2000, what is p+3. - Where is byte
0xEF stored for Little-Endian value 0xDEADBEEF at base 0x3000.
Source Grounding
current:Uebung\Übung C.pdf, pages 1-7와 current:Uebung\Übung C Musterlösung.pdf, pages 1-9: C types, pointers, memory layout, bit operations.current:Uebung\Übung 0.pdf, pages 1-3: Boolesche Logik, Zweierkomplement와 Volladdierer 과제.current:Uebung\Übung 0 Musterlösung.pdf, pages 1-4: Boolean truth table, number representation와 XOR/AND/OR 기반 Volladdierer.current:Uebung\RISC-V Reference.pdf, pages 1-2: register width, load/store context, sign and zero extension vocabulary.