3.4 Accessing Information(정보 접근하기)
레지스터는 8개의 16-bit길이로 시작하여, x86-64로 확장하면서 16개의 64-bit길이까지 확장되었다.
그림에서 알 수 있듯, 16-bit연산은 최하위 2바이트에 대해 연산을 할 수 있고, 32-bit연산은 최하위 4바이트에 대해 연산을 할 수 있고, 64-bit 연산은 레지스터 전체에 접근할 수 있다.
3.4.1 Operand Specifiers
대부분의 명령어는 하나 이상의 오퍼랜드를 가진다. 또한 오퍼랜드는 연산을 수행하는 소스 값과 그 결과를 저장할 위치를 갖고 있다. 오퍼랜드는 세 가지 타입으로 구분할 수 있다.
- immediate - 상수값, [‘$’ + 정수] 형식으로 나타낸다. (ex) ‘$0x1F’ )
- register - 레지스터의 내용 [r_a] 형식으로 나타내며, 레지스터 식별자가 인덱스된 R[r_a] 배열을 레지스터 집합으로 간주한다.
- ***memory - ‘effective address(유효주소)’***에 의해 메모리에 접근 M_b[Addr] 형식으로 나타내며, 이는 메모리 주소 Addr부터 저장된 b바이트를 참조하는 것을 의미한다. 일반적으로 아래첨자 b는 생략한다. 메모리 참조를 위한 주소지정방식은 다양하지만, 가장 일반적인 형태는 Imm(r_b,r_i,s) 이다. 이때 유효주소는 Imm+R[r_b]+R[r_i] * s 이다.
- sol)
- 0x100
- 0xAB
- 0x108
- 0xFF
- 0xAB
- 0x11
- 0x13
- 0xFF
- 0x11
3.4.2 Data Movement Instructions
- MOV 클래스
- movb, movw, movl, movq, movabsq(64-bit 상수)
- 관습에 의해 movl은 상위 4바이트를 0으로 설정한다.
- 오퍼랜드
- 소스 오퍼랜드 - 상수, 레지스터(혹은 메모리) 저장 값
- 목적 오퍼랜드 - 레지스터(혹은 메모리)의 주소
- 명령어
- 소스 값을 레지스터에 적재하는 명령어
- 레지스터 값을 목적지에 쓰는 명령어
- MOVZ 클래스
→ zero extention을 사용
💡 movzlq가 없는 이유?
→ movl로 구현 가능하기 때문!
- MOVS 클래스
→ sign extention을 사용
위와 동일
- movslq %eax, %rax를 압축하여 인코딩한 cltq 명령어도 존재한다
3.4.3 Data Movement Example
순서
- xp / y → 레지스터 %rdi / %rsi 에 저장
- x를 메모리(%rdi)에서 읽어서 레지스터 %rax에 저장
- y를 메모리(%rdi)에 저장
주목할 점
- ‘포인터’는 단순히 주소이다.
- 지역변수는 메모리보다는 레지스터에 저장된다. 속도가 월등히 빨라진다.
3.4.4 Pushing and Popping Stack Data
- 쿼드 워드 값을 스택에 추가하려면, 스택 포인터를 8 감소시키고, 값을 스택의 새로운 top주소에 기록하는 것으로 구현된다. 즉, 아래 두 코드는 동일하다.
pushq %rbq
subq $8, %rsp
movq %rbp, (%rsp)
💡 스택 포인터가 ‘감소’하는 이유
위와 동일히게 popq 명령어 또한 다음 한 쌍의 명령어로 정의할 수 있다.
movq (%rsp), %rax
addq $8, %rsp
또한, 3번째 그림처럼 pushq 이후 popq를 했을 때, top위에 존재하는 값은 다시 덮어쓰거나 임의로 지우기 전까지는 남아있게 된다.
'Computer Science > 컴퓨터 구조' 카테고리의 다른 글
[CSAPP] 3.6 Controls(제어문) (0) | 2023.01.22 |
---|---|
[CSAPP] 3.5 Arithmetic and Logical Operations(산술연자와 논리연산) (1) | 2023.01.22 |
[CSAPP] 3.3 Data Formats(데이터의 형식) (1) | 2023.01.21 |
[CSAPP] 3.2 Program Encoding(프로그램의 인코딩) (0) | 2023.01.21 |
[CSAPP] 3.1 A Historical Perspective(역사적 관점) (0) | 2023.01.21 |