Fundamental of CS/: : CSAPP

[CSAPP] Ch 3. 프로그램의 기계수준 표현 : (5) 산술연산과 논리연산

Jay.P Morgan 2024. 3. 19. 23:23

  3.5  산술연산과 논리연산

 

※ 산술연산과 논리연산 명령

 

  3.5.1  유효주소 적재 (Load Effective Address)

 

 

  leaq movq 유사하나, leaq 포인터를 생성하기 위해 사용된다는 차이가 있다. 즉, leaq 실제 데이터를 읽어오는게 아니라, 메모리의 주소자체 혹은 주소계산값을 가져온다.

​  명령어는 가리키는 위치에서 읽기를 수행하는 대신 '유효주소' 목적지에 복사한다. 그래서 목적 오퍼랜드에는 반드시 레지스터만 있다.

 

 

  3.5.2  단항 및 이항 연산

 

 

여기서 단항연산은 c언어에서 i++ 같은 자기 혼자서도 연산이 가능한 연산, 이항연산은 a+=c 같은, 다른 항이 존재해야 하는 연산이다.

 

이항연산에서 두번째 오퍼랜드는 소스이면서 목적지로 사용된다.

 

소스에는 상수, 레지스터, 메모리 위치가 올수있고, 목적지에는 레지스터, 메모리가 있다소스와 목적지에 모두 메모리가 수는 없다.

 

 

  3.5.3  시프트 연산

 

  시프트 연산자는 말그대로 시프트 (옮기기) 수행한다. 2진수에서 값을 통째로 왼쪽으로 k칸만큼 옮겨주면 2^k 곱해준 값과 같을 것이다그러므로 Left shift 2^k 연산과 같다. 여기서 SAL SHL 똑같은 연산이다.

  Right shift에서는 Arithmetic shift Logical shift 나뉘게 된다. Logical shift 단순히 값들을 오른쪽으로 시프팅한다. 원래 있던 자리는 0으로 채운다. Arithmetic shift MSB(최상위비트) 복제하여 그대로 내려보내고, 나머지는 오른쪽으로 shift한다이러면 최상위 비트에 따라 Logical shift Arithmetic shift값이 같을수도 있고 아닐수도 있겠다.

 

※ Right Arithmetic shift

 

 

쉬프트 하는 크기를 src 주고 쉬프트 값을 dest 준다.

만약 16진수 값이 있다고 할때, 인스트럭션 salb 7바이트만큼 시프트, salw 15만큼 시프트, sall 31만큼, salq 63만큼 시프트한다. (접미사가 짧다면, 상위 비트들은 무시된다.)

 

 

  3.5.5  특수 산술연산

 

  두개의 64비트 부호형 또는 비부호형 정수들 간의 곱셈은 결과값을 표현하기 위해 128비트를 필요로 한다. 128비트(16바이트) 표현하는 워드를 옥트워드라고 명명한다.

곱셈 연산자

  곱셈연산자는 크게 두 가지로, mul (비부호연산) imul(부호연산)이 있다. 이들 모두 하나의 인자는 %rax 저장하고, 다른하나는 소스 오퍼랜드로 주어진다.

  곱은 128비트까지 지원해야 하므로, 상위64비트는 %rdx, 나머지 하위 64비트는 %rax 저장된다.

imul 오퍼랜드 수가 다양할 있다. 근데 이거는 어셈블러가 알아서 구별하는거니까 크게 상관 안해도 된다.

나누기 연산자

  나누기 연산도 살펴보자. 얘네들도 오퍼랜드로 제공된다.

  부호형 나눗셈 idivq 피제수(나눠지는 수) 128비트로 상위 64비트를 %rdx, 하위 64비트를 %rax 저장한다. 제수(나누는 ) 오퍼랜드로 주어지고, 몫은 %rax, 나머지는 %rdx 저장한다.

​  64비트 나눗셈이라면, 피제수를 64비트로만 표현하면 된다. 이때 상위 64비트는 없으므로 %rdx에는 부호를 나타내는 비트가 주어진다. %rax 64비트 값을 넣어준다. 그런 , cqto라는 연산을 통해 128비트의 %rdx: %rax 확장시켜준다.

 

※ signed 에서의 나눗셈 과정. (cqto가 사용된)