728x90
CSAPP 3.4
3.4 정보 접근하기
- x86-64 주처리 장치 CPU는 64비트를 저장할 수 있는 범용 레지스터 16개를 보유한다
- 레지스터는 정수 데이터와 포인터를 저장하는데 사용한다.
- 인스트럭션들은 16개의 레지스터 하위 바이트들에 저장된 다양한 크기의 데이터에 대해 연산 할 수 있다.
- 바이트 수준 연산은 가장 덜 중요한 바이트에 대해 연산, 16비트 연산은 덜 중요한 2바이트, 32비트는 4바이트 , 64비트 연산은 레지스터 전체에 접근한다.
- 일반적인 프로그램에서 서로 다른 레지스터들은 서로 다른 목적으로 이용한다. 스택 포인터 %rsp는 런타임 스택 끝 부분을 가리키기 위해 사용된다. 일부 인스트럭션들은 특별히 이 레지스터를 읽고 쓴다. 다른 15개의 레지스터는 사용이 저금 더 자유롭다.
3.4.1 오퍼랜드 식별자(Specifier)
- 대부분 인스트럭션은 하나 이상의 오퍼랜드를 가진다.
- 오퍼랜드 - 연산에 사용될 데이터 혹은 데이터가 저장된 위치
- 오퍼랜드 연산을 수행할 소스(Source)값과 그 결과를 저장할 목적지(Destination)의 위치를 명시한다. x86-64는 여러가지 오퍼랜드 형식을 지원한다. 소스값을 상수로 주어지거나 레저스터나 메모리로부터 읽을 수 있다. 결과 값은 메모리나 레지스터에 저장된다.
- 오퍼랜드의 종류는 세가지 타입으로 구분할 수 있다.
- 상수 값 즉시 값(Immediate)
- ATT 형식의 어셈블리 코드에서, 상수는 $ 기호 다음에 C 표준 서식을 사용하는 정수로 $577, $0xAF 같이 나타낸다. 서로 다른 인스트럭션들은 다양한 범위의 상수값을 사용할 수 있다.
- Register 레지스터에 내용을 나타낸다.
- 각각 16개 64비트, 32비트, 16비트 레지스터들의 하위 일부분인 8,4,2,1바이트 중 하나의 레지스터를 가리킨다. Ra는 임의의 레지스터를 나타내며 해당 값을 R[ra]을 참조하여 지정되며, 레지스터 집합을 배열R과 레지스터 식별자를 인덱스로 사용하는 형태로 나타낸다.
- Memory 메모리 참조
- 유효주소(Effective address) 라고 부르는 계산된 주소에 의해 메모리에 접근한다.
- 유효주소 : 주소지정 방식에 의해 결정되는 오퍼랜드 주소
- 메모리는 거대한 바이트 배열로 생각할 수 있으므로 Mb[Addr] 와 같이 표시하며 메모리주소 Addr부터 저장된 b바이트를 참조하는것을 나타낸다. 단순화를 위해 b는 생략할 수 있다.
- 여러 주소지정 방식이 존재하는데, 가장 일반적인 형태는 lmm(rb,ri,s)다. 상수 오프셋 lmm, 베이스 레지스터 rb, 인덱스 레지스터 ri, 배율 s. s는 1, 2, 4, 8의 값. 베이스 레지스터와 인덱스레지스터는 64비트 레지스터다
- 유효주소는 lmm+ R[rb] + R[ri] * s로 계산한다.
- 유효주소(Effective address) 라고 부르는 계산된 주소에 의해 메모리에 접근한다.
- 가장 많이 사용되는 인스트럭션은 데이터를 한 위치에서 다른 위치로 복사하는 명령이다.
- MOV클래스 이 인스트럭션들은 소스 위치에서 데이터를 목적지 위치로 어떤 변환도 하지 않고 복사한다. movb, movw, movl, movq 1, 2, 4, 8byte 대해 계산
- 소스 오퍼랜드는 상수, 레지스터 저장 값, 메모리 저장 값을 표시한다.
- 목적 오퍼랜드는 레지스터 또는 메모리 주소 위치를 저장 한다.
- x86-64는 데이터 이동 인스트럭션에서 두 개의 오퍼랜드 모두가 메모리 위치에 올 수 없도록 제한하고 있다. 하나의 메모리 위치에서 다른 위치로 어떤 값을 복사하기 위해서는 두개의 인스트럭션이 필요하다.
- 첫 번째는 소스 값을 레지스터에 적재하는 인스트럭션.
- 두 번째는 이 레지스터 값을 목적지에 쓰기 위한 인스트럭션이 필요하다.
- 인스트럭션들의 레지스터의 크기는 인스트럭션의 마지막 문자(’b’, ‘w’, ‘l’, ‘q’)가 나타내는 크기와 일치 해야한다. 대부분의 경우 MOV 인스트럭션들은 특정 레지스터 바이트들이나 대상 오퍼랜드에 의해 지정된 메모리 위치만을 업데이트 할 것이다. 유일한 예외는 movl이 레지스터를 목적지로 가지는 것으로 이 경우 레지스터의 상위 4바이트를 0으로 설정한다.
- 명령어 소스오퍼랜드 목적오퍼랜드
- movabsq는 64비트 상수를 다루기 위한 것이다. movq는 32비트 2의 보수 숫자로 나타낼 수 있는 상수 소스 오퍼랜드 만을 갖는다. 이 값은 그 후 부호 확장되어 목적지를 위해 64비트 값을 생성한다. movabsq는 임의의 64비트 상수값을 소스 오퍼랜드로 가질 수 있으며, 목적지로는 레지스터만을 가질 수 있다.
- MOVZ 클래스의 인스트럭션은 목적지의 남은 바이트를 모두 0으로 채워주며 MOVS클래스는 소스오퍼랜드의 가장 중요한 비트를 반복해서 복사하는 부호 확장으로 채운다. 이 명령들의 이름에는 마지막 두개의 문자가 크기를 나타내는 지시자를 갖는다. 첫 번째는 소스의 크기, 두 번째는 목적지의 크기
- cltq 인스트럭션 : 오퍼랜드가 없다. 언제나 레지스터 %eax를 소스로 ,%rax를 목적지로 사용해서 부호 확장 결과를 만든다. movslq %eax %rax와 정확히 동일한 효과지만 조금 더 압축적인 인코딩을 갖는다.
- 데이터 이동(mov), 함수가 호출 된 위치로 리턴(ret)
- C언어에서 ‘포인터’라고 부르는 것이 어셈블리 어에서는 단순히 주소다. 포인터를 역참조하는 것은 포인터를 레지스터에 복사하고, 이 레지스터를 메모리 참조에 사용하는 과정으로 이루어진다.
- 역참조(Dereferencing) : 프로그래밍에서 데이터가 저장된 주소로 가서, 그 주소가 해당하는 데이터 값에 접근하는 것을 말한다.
- 지역변수들은 메모리에 저장되기 보다는 종종 레지스터에 저장된다. 레지스터 접근은 메모리 보다 속도가 훨씬 더 빠르다.
- 스택은 프로시저 호출을 처리하는데 중요한 역할을 한다.
- Top에서 제거하거나 추가한다.
- x86-64에서 프로그램 스택은 메모리의 특정 영역에 위치한다. 스택의 top원소는 모든 스택 원소중에서 가장 낮은 주소를 갖는 형태로 스택은 아래 방향으로 성장한다. 스택 포인터 %rsp는 스택 맨 위 원소의 주소를 저장한다.
- popq, pushq는 한개의 오퍼랜드를 사용한다. 추가할 소스 데이터와, 추출을 위한 데이터 목적지. 쿼드워드 값을 스택에 추가하려면 먼저 스택포인터를 8감소시키고, 그 값을 스택 주소의 새로운 탑top에 기록 하는 것으로 구현한다.
- 스택이 프로그램 코드와 다른 형태의 프로그램 데이터와 동일한 메모리에 접근 되기 때문에 프로그램들은 표준 메모리 주소지정방법을 사용해서 스택 내 임의의 데이터에 접근할 수 있다.
- 상수 값 즉시 값(Immediate)
728x90
'책 > CSAPP' 카테고리의 다른 글
CSAPP 3.6.5 - 3.7 (1) | 2024.01.22 |
---|---|
CSAPP 3.5 - 3.6.4 (0) | 2024.01.20 |
CSAPP 3.1 - 3.3 (0) | 2024.01.20 |
CSAPP 1.7 - 1완 (0) | 2024.01.20 |
CSAPP 1.1 - 1.6 (0) | 2024.01.20 |