2편에서는 어셈블리어를 해석? 하는 걸 중점으로 포스팅 하려고 합니다.
- mov 명령어 예제
코드를 짤 때 흔히 사용하는 swap함수를 예로 들어 보겠습니다.
함수에서 받아오는 인자 *x, *y같은 경우는 보통 레지스터 rdi나 rsi에 있습니다.
long t0 = *x는 어셈블리어로 mov ($rdi), $rax로 표현되어 있습니다. 즉 $rdi(x가 저장된 레지스터)를 $rax에 복사하는 것인데 괄호가 있는 이유는 포인터로 메모리를 참조하기 때문에 ($rdi)로 표현합니다.
마찬가지로 long t0 = *y도 move ($rsi), $rdx로 표현 됩니다.
그다음 swap부분인 *x = t1은 $rdx레지스터에 저장되어 있는 값 (value = *y)를 x의 주소인 ($rdi)에 mov합니다.
마찬가지로 *y = t0도 $rax레지스터에 저장되어 있는 값 (value = *x)를 y에 mov합니다.
- 산술 연산 예제
연산 예제입니다.
lea 명령어는 주소 연산을 할 때 사용되는 명령어입니다.
각각 x, y, z인자들은 레지스터 rdi, rsi, rdx에 저장됩니다.
long t1 = x + y 는 lea(%rdi, %rsi), %rax로 (%rdi, %rsi)는 %rdi + %rsi를 의미합니다. 인자 x, y를 더해서 %rax에 mov합니다.
long t2 = z + t1는 add %rdx, %rax로 %rdx(value = z)를 이전에 연산한 %rax (t1)을 더해서 %rax에 저장합니다.
long t3 = y * 48는 shift연산과 lea연산을 결합해서 합니다. lea(%rsi, %rsi, 2) 는 %rsi + 2*%rsi 즉 3%rsi입니다.
이후에 shift left연산으로 3*%rsi*16으로 48*%rsi가 됩니다.
- if / else 문 예제
조건문 코드의 어셈블리어 변환 예제입니다. 먼저 C코드를 보면 x > y이면 x-y를, 그 외에는 y-x 연산 이후에 result를 리턴하도록 되어있습니다. 이번에도 마찬가지로 인자 x y는 각각 %rdi, %rsi레지스터에 저장되어 있습니다.
첫 번째 줄의 어셈블리어 부터 살펴보면 mov %rdi, %rax로 %rdi (value = x)를 %rax레지스터에 복사합니다.
두 번째 줄의 sub 명령어로 %rax = %rax - %rsi를 수행합니다. 여기서 %rax는 이전의 복사되었던 x의 값으로 x-y연산을 하는 것을 알 수 있습니다.
세 번째 줄의 어셈블리어 mov %rsi, %rdx는 y 값을 %rdx에 복사합니다. 그리고 윗 줄과 마찬가지로 %rdx = %rdx - %rdi로 y-x연산을 수행합니다.
이제 %rax, %rdx 에 각각 x-y와 y-x의 값들이 저장되어 있는 것을 알 수 있습니다.
그리고 cmp명령어로 %rsi와 %rdi를 비교합니다. 여기서 수행되는 연산은 %rdi - %rsi를 수행하고 flag가 일어나는지 일어나지 않는지를 통해 비교하는 것 입니다.
cmovle 로 less or equal 이면 result = %rdx, 그렇지 않으면 result = %rax가 됩니다.
- 반복문 예제 (goto Loop)
반복문 중 하나인 goto문으로 예시를 들었습니다. 사실 반복문은 쓰는 형식만 다를 뿐 기능은 비슷하기 때문에 하나만 알아도 다 적용시킬 수 있을 것 같습니다.
c코드는 입력받은 숫자 x에 대하여 1의 개수를 카운트 하는 코드입니다.
어셈블리어를 보면 처음에 result = 0을 mov $0, %eax로 합니다. 어셈블리어에서 숫자는 '$'표시를 붙입니다.
그다음에 인자값 %rdi( value = x)를 %rdx에 복사합니다. 복사한 값을 1과 and연산 시킨 후에 %rax ( value = result)와 add 합니다.
그리고 %rdi (value = x)를 shift right 로 한칸 움직인 다음에 jump not equal ( = not Zero)일 시에 L2로 점프 합니다.
'System ' 카테고리의 다른 글
[시스템] 프로세스 (0) | 2018.01.21 |
---|---|
[프로세스] 예외적인 제어흐름 (0) | 2018.01.18 |
어셈블리어 (assembly) -1- (개념, 명령어) (0) | 2018.01.16 |
IEEE 754 floating point(부동 소수점) (0) | 2017.10.16 |