jun-wiki

View My GitHub Profile

Posts (Latest 10 updated) :
Read all
Contents:
  1. csapp 3.4
    1. csapp 3.4.1 피연산자 지정자
    2. csapp 3.4.2 데이터 이동 명령어
      1. mov 클래스 : 기본 데이터 복사
      2. movabsq: 64비트 즉시값 복사
      3. 확장 복사 명령어
      4. movz클래스 : 제로 확장 (Zero-extension)
      5. movs클래스 : 부호 확장 (Sign-extension)
    3. 3.4.3 데이터 이동 예제
    4. 3.4.4 스택 데이터 푸시(Push) 및 팝(Pop)
      1. pushq 명령어
      2. popq 명령어
      3. 요약

csapp다



csapp 3.3


오늘은 3.4랑 3.7가능하면 3.8을 할 예정이다

나머지보다 이것들이 이번 주차 주요 단원이라니

중요한것부터 끝내고 시간나면 나머지 보는 느낌으로 말이다


csapp 3.4

  1. 레지스터 구조와 이름 체계 이해가 중요하다

    • 예전 8086의 16비트 레지스터 → 32비트로 (%eax 등) → 64비트로 확장됨 (%rax 등)

    • 새로운 8개 레지스터는 %r8 ~ %r15

  2. 레지스터는 크기별로 나누어 접근 가능하다

    • 1바이트(%al), 2바이트(%ax), 4바이트(%eax), 8바이트(%rax) 등
  3. 레지스터 값을 덮어쓸 때의 규칙이 있다

    • 1, 2바이트 쓰기: 나머지 바이트는 그대로 둠

    • 4바이트 쓰기: 상위 4바이트는 0으로 자동 초기화

  4. 호출 규약(Calling Convention) 에 따라

    • 특정 레지스터는 함수 인자, 반환값, 스택 관리 등에 정해진 역할을 가진다



어셈블리 코드 분석이나 시스템 수준의 최적화, 디버깅을 위해 알아둬야 할 내용을 다루는 듯 하다



csapp 3.4.1 피연산자 지정자

대부분의 명령어는 소스 값과 목적지 값을 지정하는 하나 이상의 피연산자를 가진다

피연산자는 세 가지 유형으로 분류 된다

  • 즉시(Immediate):
    • 상수 값으로, AT&T 형식 어셈블리 코드에서는 ‘$’ 뒤에 정수가 붙는다 (예: $-577 또는 $0x1F)
  • 레지스터(Register):
    • 레지스터의 내용을 나타낸다
  • 메모리(Memory):
    • 메모리에서 값을 가져오거나 저장한다. 다양한 주소 지정 형식이 있다
    • (예: 절대 주소, 간접 주소, 베이스 + 변위, 인덱싱된 주소, 스케일된 인덱싱된 주소)


종류 문법 형식 의미 명칭
Immediate $Imm 상수 값 즉시 값
Register ra R[ra], 즉 레지스터 값 레지스터
Memory Imm M[Imm] 절대 주소 참조
Memory (ra) M[R[ra]] 간접 참조
Memory Imm(rb) M[Imm + R[rb]] 기준 + 오프셋
Memory (rb,ri) M[R[rb] + R[ri]] 인덱스 주소
Memory Imm(rb,ri) M[Imm + R[rb] + R[ri]] 인덱스 + 오프셋
Memory (,ri,s) M[R[ri] * s] 스케일 인덱스
Memory Imm(,ri,s) M[Imm + R[ri] * s] 스케일 + 오프셋
Memory (rb,ri,s) M[R[rb] + R[ri] * s] 스케일 인덱스
Memory Imm(rb,ri,s) M[Imm + R[rb] + R[ri] * s] 완전 일반형

여기서 s(스케일 값)는 반드시 1, 2, 4, 8 중 하나여야 하며, rb, ri는 모두 64비트 레지스터여야 한다.



csapp 3.4.2 데이터 이동 명령어

mov 클래스 : 기본 데이터 복사

변환 없이 소스 위치에서 목적지 위치로 데이터를 그대로 복사

mov 클래스 명령어

명령어 설명 동작
mov 일반 복사 D ← S
movb 1바이트(byte) 복사  
movw 2바이트(word) 복사  
movl 4바이트(double word) 복사  
movq 8바이트(quad word) 복사  
movabsq 64비트 즉시값 복사 R ← I




mov 명령어 조합 예시

예시 명령어 의미
movl $0x4050, %eax 즉시값 → 레지스터 (4바이트)
movw %bp, %sp 레지스터 → 레지스터 (2바이트)
movb (%rdi, %rcx), %al 메모리 → 레지스터 (1바이트)
movb $-17, (%esp) 즉시값 → 메모리 (1바이트)
movq %rax, -12(%rbp) 레지스터 → 메모리 (8바이트)




movabsq: 64비트 즉시값 복사

일반적으로 movq 명령어는 즉시값을 32비트의 2의 보수로 해석하고 이를 부호확장(sign-extend) 해서 64비트로 만든다

하지만 정확한 64비트 즉시값을 사용할 필요가 있을 때에는 movasbsq를 사용한다.

  • 특징
    • 즉시값은 64비트 전체를 사용 가능

    • 목적지는 반드시 레지스터만 가능



확장 복사 명령어

  • 2가지가 있다


movz클래스 : 제로 확장 (Zero-extension)

레지스터 또는 메모리에서 값을 읽고, 레지스터에 복사할 때 남은 상위 바이트를 0으로 채운다

명령어 설명
movzbw 바이트 → 워드 (1 → 2바이트)
movzbl 바이트 → 더블워드 (1 → 4바이트)
movzwl 워드 → 더블워드 (2 → 4바이트)
movzbq 바이트 → 쿼드워드 (1 → 8바이트)
movzwq 워드 → 쿼드워드 (2 → 8바이트)




movs클래스 : 부호 확장 (Sign-extension)

상위 비트는 소스의 최상위 비트(sign bit)를 복제하여 채운다

명령어 설명
movsbw 바이트 → 워드
movsbl 바이트 → 더블워드
movswl 워드 → 더블워드
movsbq 바이트 → 쿼드워드
movswq 워드 → 쿼드워드
movslq 더블워드 → 쿼드워드
cltq %eax%rax (부호 확장)

cltqmovslq %eax, %rax동일한 의미이지만, 더 짧은 인코딩을 가진다



3.4.3 데이터 이동 예제

C 코드와 어셈블리 코드로 데이터 이동 예제가 나온다

함수 인수는 레지스터를 통해 전달되며, 반환 값은 %rax 레지스터에 저장된다는 걸 확인 가능하다



3.4.4 스택 데이터 푸시(Push) 및 팝(Pop)

스택과 푸시, 팝이다

여기에 대강 정리해 놨으니 대충만 설명하겠다


pushq 명령어

  • 기능: 8바이트(quad word)를 스택에 추가

  • 동작:

    1. %rsp를 8만큼 감소

    2. 해당 위치에 값을 저장

예시

pushq %rbp

는 아래의 두 명령어와 동일

subq $8, %rsp         ; 스택 포인터 감소
movq %rbp, (%rsp)     ; 값을 스택에 저장

차이점이라면 puqsh1바이트 인코딩이고 위 두 명령어는 총 8바이트 인코딩이다




popq 명령어

  • 기능: 스택에서 8바이트 값을 꺼내어 레지스터에 저장

  • 동작:

    1. %rsp가 가리키는 위치에서 값을 읽어옴

    2. %rsp를 8만큼 증가

예시

popq %rax

는 아래와 같다

movq (%rsp), %rax     ; 스택에서 값 읽기
addq $8, %rsp         ; 스택 포인터 증가

요약

명령어 동작 요약
pushq S %rsp -= 8[rsp] = S
popq D D = [rsp]%rsp += 8


  • 스택은 아래 방향으로 증가 (주소 감소)

  • %rsp항상 현재 top을 가리킨다

  • 스택 접근은 메모리 참조 방식으로 직접 지정도 가능