목록전체 글 (30)
헤맨 만큼 내 땅이다
비유: 디스크는 지하 창고, RAM은 열람실 책상이에요. 책 한 권이 페이지이고, 책이 어디 있는지 적어 둔 목록표가 페이지 테이블이에요.1. 페이지 (9.3)가상메모리를 같은 크기의 덩어리로 자른 게 가상페이지(VP), RAM을 같은 크기로 자른 게 **물리페이지(PP)**예요.전체 데이터는 디스크에 있고, 지금 쓰는 페이지만 RAM에 올려 둬요.2. 페이지 테이블 (9.3.2)가상페이지마다 칸이 하나씩 있고, 그 칸을 PTE라고 해요. PTE에는 두 가지가 적혀 있어요.유효비트: 1이면 지금 RAM에 있다는 뜻이고, 0이면 RAM에 없다는 뜻이에요.주소: 1이면 RAM의 어느 물리페이지인지, 0이면 디스크 어디인지 적혀 있어요.페이지 테이블은 RAM에 있고, 번역할 때마다 MMU가 이걸 읽어요.3. ..
안녕하세요 ㅇㅇㅇ입니다.지난 퀴즈 5번, 어셈블리를 C 코드로 복원하는 문제를 풀면서 막혔던 지점들을 정리해왔습니다.우선 어셈블리를 읽을 때는 레지스터가 어떤 C 변수에 대응하는지부터 먼저 표시해두고 시작해야 합니다.여기서는 %edi는 x, %edx는 y가 됩니다.추가로 복기를하며 `sub`가 아닌 `cmp`를 쓴 이유를 확인해봤습니다.- `sub`는 계산 결과로 레지스터를 덮어써버려서 원래 값을 잃어버리지만- `cmp`는 계산만 하고 결과는 버린 채, 부호 정보만 플래그에 기록합니다. 여기선 x - 0이었죠. 다음으로 `jle`는 jump if less or equal, 계산한 x-0이 0 이하면 점프하라는 뜻이었습니다.그래서 조건부 점프를 만나면 "어디로, 무슨 조건으로 가는지"가 핵심이었습니다.마지..
문제 상황파스칼의 삼각형을 1차원 배열에 삼각 인덱싱으로 채우는 코드다. 실행하면 정상적으로 14개 행을 다 출력한 뒤, 마지막에 갑자기 다음 에러와 함께 종료된다.*** stack smashing detected ***: terminated출력은 끝까지 정상인데 프로그램만 비정상 종료되는 것이 특징이다.원인 코드static void build_pascal(int *tri, int rows) { for (int i = 0; i ROWS가 14일 때, 유효한 행은 0번부터 13번까지 총 14개다. 그런데 i 배열 밖을 넘어 쓰는 지점인덱스 계산 함수는 다음과 같다.static int tri_index(int i, int j) { return i * (i + 1) / 2 + j;}i = 14, j..
cmpl / jle 조건부 분기를 읽다가 막혔던 지점들 정리문제 상황cmpl $0, %edijle .L1movl $1, %edxjmp .L2.L1:movl $0, %edx.L2:movl %edx, %eaxretint function(int x) { int y; if ( ____(1) ) _____(2); else y = 0; return ____(3);}트러블 1 — %edi가 갑자기 왜 나오지? x는 어디 있는 거야?증상: 코드 어디에도 x라는 글자가 없는데 갑자기 %edi가 등장해서 당황함.원인: 함수 인자는 코드에 명시적으로 "담기는" 과정이 안 보여요. 함수가 시작되는 순간, 이미 첫 번째 인자가 %edi(4바이트 정수 인자 규칙)에 담긴 채로 시..
도입 (30초)이번 발표는 **"컴파일러가 다차원 배열 인덱싱을 어떻게 최적화하는가"**에 대한 내용입니다. 핵심 질문은 하나예요 — 배열 원소에 접근할 때마다 매번 곱셈을 해야 할까? 결론부터 말하면, 컴파일러는 최대한 이 곱셈을 피하려고 합니다.1. 고정크기 배열 (3.8.4절) — 2분예제 설정#define N 16typedef int fix_matrix[N][N];int fix_prod_ele(fix_matrix A, fix_matrix B, long i, long k) { long j; int result = 0; for (j = 0; j → 두 16×16 행렬을 곱했을 때, 결과의 (i,k) 위치 값을 구하는 함수입니다. 행렬 곱셈의 정의 그대로, A의 i행과 B의 k열을 내적..
3.6 ~ 3.6.2 정리3.6 도입부 — 왜 이 챕터가 필요한가지금까지의 코드는 전부 순서대로 실행되는 straight-line code였음하지만 if/while/for/switch는 조건에 따라 실행 순서 자체가 달라져야 함기계어가 조건부 동작을 구현하는 두 가지 방법:control flow를 바꾸는 방법 → jump 명령어 사용 (더 일반적, 더 흔함 → 먼저 다룸)data flow를 바꾸는 방법 → 실행 순서는 그대로, 계산되는 값 자체가 달라짐컴파일러의 역할: CPU가 이해하는 건 "조건에 따라 점프해라"라는 저수준 기능뿐이라, 이걸 조합해서 if/while 같은 고수준 문법을 흉내 냄3.6.1 Condition Codes — 조건을 검사하는 하드웨어 메커니즘핵심 개념CPU에는 CF/ZF/SF/..
안녕하세요 000입니다. 연결 리스트 3번의 트러블 슈팅 과정을 공유하겠습니다. 이 문제는 원래 순서를 유지하면서 짝수는 리스트 앞에, 홀수는 뒤로 이동시키는 문제였습니다. 그런데 실행해보니 원하는 결과가 나오지 않았어요. 원인 정리해보면,홀수를 지웠을 때는 뒤 원소가 shif되니 인덱스는 그대로 두고 같은 자리를 다시 확인해야 하고,짝수일 때는 다음 자리로 넘어가야 하니 인덱스를 늘려야 합니다. 그런데 두 경우 모두 "하나를 확인했다"는 사실은 같기 때문에,반복 횟수를 세는 변수는 항상 늘어나야 합니다. 즉 인덱스 증가와 반복 횟수 증가는서로 다른 조건으로 움직이는 별개의 값이었던 거죠. 그래서 for문의 증가식을 비우고,위치를 나타내는 i와 반복 횟수를 세는 count를 분리해서각자 다른 조건으로 ..
문제 개요단일 연결리스트를 앞부분(front)과 뒷부분(back), 두 개의 서브리스트로 나누는 함수를 작성하는 문제. void frontBackSplitLL(LinkedList *ll, LinkedList *resultFrontList, LinkedList *resultBackList);규칙원소 개수가 홀수면, 남는 원소 1개는 front로 간다.예시: 2, 3, 5, 6, 7 (5개) → frontList: 2, 3, 5 / backList: 6, 7최종 코드 void frontBackSplitLinkedList(LinkedList *ll, LinkedList *resultFrontList, LinkedList *resultBackList){ int len = ll->size % 2 == 0 ?..
문제 코드 int insertSortedLL(LinkedList *ll, int item){ int i = 0; for(i = 0; i size; i++){ int val = findNode(ll, i) -> item; if (val == item) { return -1; } else if (val > item) { insertNode(ll,i,item); return i; } } insertNode(ll,i,item); return i;}📌 핵심 개념: 포인터(*)로 넘긴다는 것LinkedList *ll의 의미ll은 LinkedList 구조체 몸통 자체가 아니라, 그 몸통이 저장된 주소값을 담는 포인터 변수다.main()에서 호출할 때 insertSortedLL(&ll, i)처럼..
typedef란?typedef는 긴 타입 이름에 짧은 별명을 붙여주는 키워드다.문제 상황typedef 없이 구조체를 선언하면, 이 구조체를 쓸 때마다 매번 struct 키워드를 붙여서 길게 써야 한다.struct _listnode { int item; struct _listnode *next;};struct _listnode myNode; // 매번 이렇게 길게 써야 함typedef로 해결typedef struct _listnode { int item; struct _listnode *next;} ListNode;이렇게 선언해두면, 이제부터 struct _listnode 대신 ListNode라는 짧은 별명으로 쓸 수 있다. ListNode myNode; // 짧게 쓸 수 있음핵심..