크래프톤 정글 17DAY 연결리스트와 연습문제풀이
n년만에 쓰는 이중포인터
#include <stdio.h>
int main() {
int i = 42;
int *p = &i;
int **pp = &p;
printf("i의 값: %d\n", **pp); // 이중 포인터를 통해 i의 값을 출력
return 0;
}
너무 오랜만에 쓰는 것이어서 긴가민가 했는데, 다행히 예상대로 출력이 되었다.
이 코드를 짤막하게 설명하자면 i라는 변수(그릇)안에 42라는 초기화값을 넣은 뒤 i의 주소를 가리키는 포인터 변수를 선언한다.
그 이후 포인터 변수 p를 참조하게 된다면,주소를 참조하는 것이므로 내부에 있는 i의 값이 출력되는 것이다.
처음에는 그렇다면 참조는 무엇을 하는것인가 싶을 수 있는데, 간단하게 설명하자면 내부를 읽어온다고 생각하면 된다.
그래서 주소를 참조하면 내부의 내용물을 가져오고, 내용물을 참조하면 주소값 즉 그 그릇의 위치를 알려주는 것이다.
포인터를 사용하여 구현하는 링크드 리스트
구조체를 사용하여 구현한 코드이다.
코드는 너무 길어서 네이버 블로그에 따로 올려두었다.
- 링크드 리스트 코드 게시물
연습문제 풀기(3.1)
우선 3.1을 풀면 한가지 재미있는 사실을 알 수 있는데, 마치 (%레지스터명)은 일종의 포인터 기능을 하며 괄호가 없는 경우 단순참조와 유사하게 작동한다는 것이다.
즉%rax
는 단순한 레지스터 참조 즉 value는 단순참조인 0x100이 담긴다.
그에 비해 괄호를 씌운다면 주소값에 대한 참조(0x100)이므로 0xff가 value가 되는 것이다.extends zero
좀 더 큰 자료형으로 확장 시 앞에 0을 붙이게 되는데, 이는 프로그램의 안정성 유지와 깊은 관계가 있다.
예를 들어 8비트에서 16비트로 변환시 0x96을 0x0096으로 바꾸면(부호가 없음)오버플로우를 방지할 수 있다.
반대로 부호가 없는 unsigned형의 경우 언더플로우에 대한 방지 역시 가능한데, 위에서 말한 예시는 크기가 작아 상관이 없으나 크기가 커질수록 데이터 확장시 일관성을 지키는 것이 중요하다.연습문제 풀기(3.4)
- char to int
movesbl(%rdi),%eax
위의 경우 char을 int에 확장하여 %eax레지스터에 저장하는 것이다.
이 과정에서 bl을 사용한 것은 0을 붙이는 확장을 통하여 바이트를 더블워드인 int로 표현하기 위해서이다.
movl %eax,($rsi)
eax에 적재된 내용물을 rsi의 주소에 옮긴다.
이때 rsi는 두번째 arg로 1st가 사용중이어서 rsi를 사용한 것이다.
또한 int형이기 때문에 rsi를 사용한 것이다. - unsigned char to long
movzbl(%rdi),%eax
위와 동일하게 작은 곳에서 큰 곳으로 옮기는 과정이므로 extends zero명령어 내에서 선택을 해야한다.
(+ 부호가 없는 곳에서 부호가 있는 곳으로 가는 거기 때문에 우선적으로 movzbl을 사용하여 크기를 맞추어준다.) 또한 retrun val에 담겨있던 것을 %rdi즉, 좀 더 큰 것을 저장할 수 있는 1st arg의 레지스터 주소를 찾아 적재시키는 것이다.
movq %rax,(%rsi)
위에서 저장한 rsi의 값을 불러온 뒤 return val을 하기 위해 rax에 적재한다.
또한 long의 경우 위에서 movq를 사용하였으니 동일하게 movq를 해주고,그에 맞는 return크기인 rax를 2st인 rsi에 담는다.
(다만 의아한 것은 long을 왜 movq로 분리하였는가이지만…)연습문제 풀기(3.6)-3.5는 흐름 따라가면 돼서 생략
- leaq 9(%rdx),%rax
이건 rdx에 저장된 데이터인 q에 9만큼 더하는 간단한 코드이다.
괄호가 들어가면 내용물을 불러온다라고 이해하면 편하다. - leaq (%rdx,$rbx),%rax
위와 마찬가지이나, 두 개의 메모리로부터 내용물을 불러오는 지점만 차이가 가 있다.
p와 q를 가져온 뒤 더해서 rax에 적재시키면 된다. - leaq 0xE(,%rdx,3),%rax
우선 진법을 맞추어 주려면 0xE를 10진법 14로 반환한다.
이후%rax = 14 + 3 * %rdx
를 치환하는 원리로 계산하면14+3q
라는 답을 도출해잴 수 있다. - leaq 6(%rbx,%rdx,7),%rdx
이 경우 rbx에 담긴 값인 p는 그냥 산술적인 덧셈을 실행하고 7의 경우 rdx와 치환을 시켜6+p+7q
가 정답이 된다.
댓글남기기