[W05] 퀴즈 정리

silver ·4일 전

크래프톤 정글

목록 보기
20/22

1. 컴퓨터시스템에서의 버스(Bus)의 개념을 기술하시오.

제출한 답

: 컴포넌트들 간에 바이트 정보들을 전송하는 시스템 내를 관통하는 전기적 배선군

2. 다음과 같이 선언된 함수 포인터 fp를 사용하여 함수를 호출하는 C 코드를 작성하시오. 또한, 함수 포인터의 개념과 특징에 대해 본인이 이해한 내용을 설명하시오.

    int (*fp)(int x, int *p);

제출한 답

함수를 가리키는 포인터.
함수 포인터를 통해 메모리를 할당하거나 회수하는 것이 불가능하기 때문에 함수 포인터를 대상으로 malloc()과 free()를 사용하지 못한다.

추가하면 더 좋을 부분

  • 함수 포인터의 타입은 매개변수 타입 + 반환 타입까지 포함해서 결정됨 (int(*)(int, int*)처럼)
  • 콜백 함수, 함수를 배열/구조체에 담아 switch 대신 분기 테이블처럼 쓰는 용도 등 런타임에 실행할 코드를 바꿀 수 있다는 게 핵심 활용 포인트
  • 값 자체는 그 함수의 코드가 시작되는 메모리 주소

코드 답 예시

int func(int x, int *p)
{
    return x + *p;
}

int main(void) {
    int n = 10;
    int (*fp)(int x, int *p) = myfunc;   // fp에 실제 함수 주소가 들어 있어야 함
    
    fp(3, &n);              // 또는 (*fp)(3, &n);
}

3. X86-64에서 함수가 호출될 때 레지스터로 전달 될 수 있는 인자의 수와 해당 레지스터에 대해 설명하시오. 또한, 해당 레지스터 수를 초과하는 인자는 어디에 저장되는지도 설명하시오.

제출한 답

%rdi, %rsi, %rdx, %rcx, %r8, %r9` 최대 6개의 정수형 인자가 레지스터로 전달될 수 있다.
6개보다 많은  integral argument는 스택으로 내려가게 된다.

추가하면 좋을 부분

정수형(integral)/포인터형 인자에 한해서"라는 조건을 명시.
부동소수점 인자는 별도로 %xmm0~%xmm7을 씀

4.x86-64에서 %rax, %eax, %ax, %al 레지스터의 차이점을 설명하시오. 또한, x86 아키텍처의 발전 과정에서 이러한 형태의 레지스터 구조가 만들어진 이유를 설명하시오.

제출한 답

원조인 8086에서 레지스터들은  %ax~%sp까지의 16비트 레지스터를 가졌음
IA32로 확장하면서 이 레시스터들이 32비트로 확장되어 %eax~%esp까지 이름을 붙임
x86-64로 확장하면서 본래의 8개의 레지스터들이 %rax~%rsp까지 64비트로 확장되었고, 8개의 새로운 레지스터들이 추가됨

인스트럭션 집합의 역사적인 진화 과정으로 인해 여러 명명법을 따르게 되었고, 
인스트럭션들과 각  하위 바이트들에 대한 호환성을 위해서.

추가하면 좋을 부분

  • %rax = 64비트 전체
  • %eax = %rax의 하위 32비트
  • %ax = %rax의 하위 16비트
  • %al = %rax의 하위 8비트
    각 이름이 같은 레지스터의 서로 다른 크기 "조각"을 가리킨다는 점 명시

x86 아키텍처가 16비트에서 32비트, 64비트로 발전하면서 기존 프로그램 및 명령어와의 하위 호환성을 유지하기 위해 기존 레지스터를 확장하는 방식으로 설계되었다. 따라서 %rax, %eax, %ax, %al 은 하나의 레지스터에서 각각 64비트, 32비트, 16비트, 8비트 부분을 나타내는 구조를 갖게 되었다.

5. 다음은 어셈블리 코드를 C 코드로 복원한 결과이다. 빈칸을 채워라.

cmpl $0, %edi     
jle .L1            
movl $1, %edx      
jmp .L2
.L1:
movl $0, %edx      
.L2:
movl %edx, %eax  
ret
int function(int x) {

    int y;

    if ( ____(1) )

        _____(2);

    else

        y = 0;

     return ____(3);

}

어셈블리 해석

cmpl $0, %edi      ; edi - 0 계산 (x와 0 비교)
jle .L1            ; x <= 0 이면 L1로 점프
movl $1, %edx      ; (점프 안 했으면, 즉 x > 0 이면) → y = 1
jmp .L2
.L1:
movl $0, %edx      ; (x <= 0) → y = 0
.L2:
movl %edx, %eax    ; %edx의 값을 %eax로 옮기고 반환. 즉 return y;
ret
  • jle는 less than or equal
    "x <= 0이면 .L1 else(y=0)로 간다"는 뜻

  • cmpl $0, %edi
    jle .L1

    → x <= 0이면 .L1로 감
    → .L1이 y=0이므로
    → 반대로 x > 0이면 y=1

⇒ 인자 x를 조건 검사에만 쓰고, 실제로 값을 대입·반환하는 변수는 전부 y

정답

int function(int x) {
    int y;
    if (x > 0)
        y = 1;
    else
        y = 0;
    return y;
}

0개의 댓글