gdb란?실행 중인 C 프로그램을 원하는 지점에서 멈추고, 그 순간의 변수 값, 메모리, 호출 스택을 들여다보는 도구이다. 사용방법gcc 로 컴파일gcc 는 디버그 정보를 실행 파일에 넣는다. C 언어 - GCC 정리gcc란gcc는 .c 파일을 CPU가 실행할 수 있는 파일로 번역하는 프로그램이다. gcc -Wall -g hello.c -o hello # 컴파일./hello # 실행 gcc 는 전처리 → 컴파일 → 어셈블 → 링크를 한 번에 해준다. 에러 종류를skylarcoding.tistory.comgcc -g -O0 -Wall main.c -o main 나는 보통 run → bt → b (에러난 줄) → r (재실행) → n & info locals 로 문제 확인 흐름으로 진행한다. 핵심 ..
문제어셈블리 코드를 C 코드로 복원한 결과, 빈칸 채우기# 어셈블리코드cmpl $0, %edijle .L1movl $1, %edxjmp .L2.L1:movl $0, %edx.L2:movl %edx, %eaxret# C 코드int function(int x) {int y;if ( ____(1) )_____(2);elsey = 0;return ____(3);} 문제풀이%edi : 첫 번째 인자 x (%rdi의 하위 32비트, int 라서 e)%edx : 지역 변수 y 보관용%eax : 반환값 (%rax의 하위 32비트) cmpl $0, %edicmpl : 비교만 하고 결과는 플래그에 남긴다 cmp 는 두 값을 빼보기만 하고 결과는 버리는 명령어이다. 여기서는 x- 0 을 계산한다.결과의 정보 (0인지,..
함수 포인터란?함수 포인터는 함수의 코드가 시작되는 메모리 주소를 저장하는 변수이다.일반 포인터가 변수 데이터의 주소를 담는다면, 함수 포인터는 코드의 주소를 담는다. 프로그램이 실행되면 함수의 기계어 코드도 메모리의 코드 영역에 올라가기 때문에, 함수도 주소를 가지게 된다. int x = 10;int *p = &x; int add(int a, int b){ return a + b; }int (*fp)(int, int) = add; // 함수 포인터 선언 읽는 법int (*fp)(int x, int *p);// (*fp) : fp 는 포인터다// (int x, int *p) : 그 포인터는 int 와 int *를 받는 함수를 가리킨다// 맨 앞 int : 그 함수는 int 를 반환한다. 안쪽에서 바..
데이터가 언제까지 살아있어야 하는지를 생각해봐야 한다. 지역 변수를 스택에 두는 이유함수 호출에는 규칙적인 순서가 있다. main 에서 A 를 호출하고, A 가 B, B가 C 를 호출하면 C → B → A → main 순서로 끝난다. 끝나는 순서는 반드시 LIFO 구조이다. 이 규칙이 스택 자료구조와 정확히 일치한다. 함수가 호출될 때 그 함수에 들어온 공간(스택 프레임)을 스택 맨 위에 쌓고, 함수가 끝나면 맨 위부터 차례로 제거한다.이 방법의 장점은 두 가지이다.빠르고 단순하다.공간을 잡는 건 스택 포인터를 내리는 것이고, 반납하는 건 다시 올리는 것뿐이다. 어디가 비었는지 찾을 필요가 없다.자동으로 정리된다. 함수가 끝나면 그 함수의 지역 변수는 필요 없으니, 프레임을 걷어내는 순간 같이 반납해도 ..
다른 CSAPP 글 보러가기 'CS/CSAPP 컴퓨터 시스템' 카테고리의 글 목록Hello Worldskylarcoding.tistory.com 3.8 배열배열 원소를 가리키는 포인터를 만들고 그 포인터로 산술 연산을 할 수 있다는 점이 특이하고, 전부 주소 계산으로 번역된다. 기본 원리T A[N]; 은 연속된 메모리 덩어리를 잡고, A 는 시작 주소를 값으로 갖는 포인터가 된다.A[i] 의 주소 = 시작주소 + (원소크기 x i)배열 접근이 빠른 이유는, 어디 있는지 찾아다닐 필요 없이 계산 한 번으로 주소가 나온다. 포인터 연산포인터 연산은 자동으로 스케일 된다. int *p 에서 p + 1 은 주소가 1 늘어나는게 아니라 4 늘어난다. 타입 크기만큼 자동으로 곱해진다.C 에서 A[i]..