간단 지식/System Programming

06. Arithmetic operation of register, 레지스터와 변수의 관계

납작한돌맹이 2020. 11. 19. 04:32
반응형

이제까지 movq와 leaq 연산에 대해 알아보았는데, 가장 기본적인 산술연산도 있음을 알아두자.

 

아래 표는 2개의 피연산자 구조(연산자 src, dest)를 갖는 연산자이다.

연산자 연산식
addq dest = dest + src
subq dest = dest - src
imulq dest = dest * src
salq dest = dest << src  (산술)
sarq dest = dest >> src  (산술)
shlq dest = dest << src  (논리)
shrq dest = dest >> src  (논리)
xorq dest = dest ^ src
andq dest = dest & src
orq dest = dest | src

괄호 안에 산술, 논리라고 적힌 연산자들은 연산식은 동일하지만 sign bit 처리에 대해서는 차이가 있다. 산술 연산자들은 shift 연산 후 빈 공간을 이전 수의 sign bit로 채우지만, 논리 연산자들은 0으로 채운다.

 

아래 표는 1개의 피연산자 구조를 갖는 산술 연산자이다.

연산자 연산식
incq dest = dest + 1
decq dest = dest - 1
negq dest = -dest
notq dest = ~dest

아래 예제를 보자.

long test(long x, long y, long z){
     long t1 = x+y;
     long t2 = z+t1;
     long t3 = x+4;
     long t4 = y*48;
     long t5 = t3+t4;      -------- x+4+48y
     long rval = t2*t5;    -------- (z+x+y)*(x+4+48y)
     return rval;
}


test: leaq (%rdi, %rsi), %rax       -------(1)
      addq %rdx, %rax               -------(2)
      leaq (%rsi, %rsi, 2), %rdx    -------(3)
      salq $4, %rdx                 -------(4)
      leaq 4(%rdi, %rdx), %rcx      -------(5)
      imulq %rcx, %rax              -------(6)
      ret

인자로 오는 변수 x, y, z는 각각 순서에 따라 레지스터에 할당된다. (%rdi = x, %rsi = y, %rdx = z)

코드라인 (1). %rax = %rdi + %rsi 에 따라 %rax = t1, %rax = x + y 이다.

코드라인 (2). %rax = %rax + %rdx 에 따라 , %rax = x + y + z 이다.

코드라인 (3). %rdx = %rsi + 2*%rsi 에 따라 %rdx = y + 2y = 3y 이다. 이 부분은 test함수 어디에도 해당하는 코드가 없다. 여긴 바로 컴파일러의 자체 판단을 알 수 있는 부분이다. 컴파일러는 어셈블리를 하는 과정에서 코드에 변수 z의 사용이 더 이상 없다는 사실을 이용해 원래 변수 z를 저장했던 %rdx를 후에 사용될 3y를 저장하게 했다.

코드라인 (4). shift 연산은 제곱과 곱셈을 이용해서 %rdx = %rdx * 2^4 이다. 그에 따라 %rdx = 3y * 16 = 48y이다.

코드라인 (5). %rcx = 4 + %rdi + %rdx 에 따라 %rcx = 4 + x + 48y 이다.

코드라인 (6). %rax = %rax * %rcx 에 따라 %rax = (x+y+z)*(4+x+48y) 이다.

코드 해석을 통한 이해도 중요하지만, 여기서 집중해야 할 것은 코드에서 9개의 변수를 사용했지만 실제로 사용되는 레지스터의 개수는 5개라는 사실이다. 즉, 레지스터와 변수는 1대 1 관계가 아니다. 레지스터는 한정된 하드웨어 자원이기 때문에 효율적이되 적은 개수로 사용하는 편이 좋다. 예를 들어 함수 A에서 사용한 로컬 변수 a와 함수 B에서 사용한 로컬변수 a는 서로 다른 변수로, 메모리 상에서 다른 위치에 존재한다. 그러나 이 변수를 저장하는 레지스터 %rdi는 동일한 레지스터라는 의미이다.

 

 

 

(이 글이 도움이 됐다면 광고 한번씩만 클릭 해주시면 감사드립니다, 더 좋은 정보글 작성하도록 노력하겠습니다 :) )

반응형