지난 글에서는 SPARC 언어에서 사용하는 메모리의 종류 Static, Heap, Stack 에 대하여 알아보았다.
전역 변수의 값은 Static 영역, 지역 변수의 값은 Stack 영역, 동적 할당 시에는 Heap 메모리 영역에 데이터가 저장되었다.
그 중 Stack을 자세하게 알아보았는데, Stack은 높은 메모리주소부터 감소하면서 할당되었다. (어셈블리 기준 직접 할당)
할당 명령어는 save, 반환 명령어는 restore 이었고, save 명령어를 통해 stack 과 32byte register 공간도 같이 할당 받았다.
스택의 할당시에는 스택 포인터를 이용해 할당 위치를 알 수 있었다.
이번 글에서는 산술 연산과 Condition Code에 대해 간단하게 살펴보고자 한다.
산술연산
C언어에서 사용하는 연산은 다양하게 있다.
+, -, *, /, % 같은 산술 연산도 있고, &&, || 같은 논리 연산, &, ^, << 와 같은 비트 연산도 있다.
이 중 이번 포스팅에서는 '산술 연산' 을 수행하는 명령어에 대해 살펴본다.
산술연산의 경우, 컴퓨터가 수행하는 것은 오직 '덧셈' 하나이다.
뺄셈은 빼는 수의 부호를 바꿔 더하는 것과 같고, 곱셈과 나눗셈은 서브루틴을 호출하여 계산된다고 한다.
이 중 '명령어'로서 구현된 것은 덧셈과 뺄셈인데, 크게 add 명령어와 sub 명령어로 나뉜다.
각 명령어에는 cc, x 옵션을 각각 골라 붙일 수 있다.
그래서 아래와 같이 총 8가지의 명령어 형태가 나온다.
add
addcc
addx
addxcc
sub
subcc
subx
subxcc
cc 옵션은 Condition Code 의 생성 여부를 결정한다.
cc 옵션이 없으면 Condition Code를 생성하지 않는다.
x 옵션은 덧셈 연산시 이전 자릿수에서 넘어온 Carry 를 받을지 여부를 결정한다.
x 옵션이 없다면 Carry 를 받지 않는다.
보통 큰 수를 연산할 때 쓰인다.
각 명령어는 3개의 피연산자를 받는다.
명령어의 피연산자 개수에 따른 분류를 정리하였을 때, 피연산자가 3개 있는 경우 아래와 같은 형태가 되었다.
op R, A, S
R 은 첫번째 source 로, 레지스터 주소만 받는다.
A 는 두번째 source 로, 레지스터 주소와 상수값을 모두 받는다.
S 는 연산 결과를 저장할 target 으로, 레지스터 주소만 받는다.
Condition Code
이제 아까 산술 연산 명령어에서 cc 옵션이 붙었을 때 생성한다는 Condition Code 에 정리해보자.
컨디션 코드는 말 그대로 Condition (조건) 에 사용되는 코드이다.
bge, be, bne 와 같은 conditional branch 명령어의 동작을 결정할 때, Condition Code 가 사용된다.
C언어로 표현하면 if, switch case, for, while, do while 같은 반복/조건문에서 사용된다.
뿐만 아니라 >. <, == 와 같은 관계 연산자에서도 사용된다.
Condition Code 는 회로적으로 계산하여 뱉어내도록 설계되어있다.
ALU 에서 R, A, S 를 받아 연산을 마친 후 Z / N / V / C 4가지 타입의 코드를 뱉어낸다.
이 코드를 이용해 분기문을 제어한다.
이제 Condition Code 의 4가지 타입이 각각 무엇인지 살펴보자.
Z (Zero) : 연산 결과가 0이라면 1로 설정되고, 아니라면 0으로 설정된다.
N (Negative) : 연산 결과가 음수라면 1로 설정되고, 아니라면 0으로 설정된다.
V (oVerflow) : 연산시 오버플로우가 발생했다면 1로 설정된다. 이는 오직 signed number 연산에서만 유효하다.
C (Carry) : 연산시 Carry 가 발생했다면 1로 설정된다. 이는 오직 unsigned number 연산에서만 유효하다.
빨간색 볼드체로 표시한 내용은 다음 포스팅에서 자세히 살펴볼 것이다.
이 코드는 가령 이렇게 사용된다.
Ex1) 두 숫자가 같은지 비교할 때 => CPU는 비교를 뺄셈을 통해 비교한다.
두 수의 차를 계산했을 때 Z 코드가 활성화 되었다면 두 수의 차가 0, 즉, 두 수가 같다는 의미이다.
Ex2) 두 숫자 중 어떤 수가 더 큰지 비교할 때 => 이때도 뺄셈을 이용해 비교한다.
두 수의 차를 계산했을 때 N 코드가 활성화 되었다면 오른쪽 숫자가 더 크다는 의미이다.
V와 C 는 비교가 아니라, 연산시에 사용된다.
이는 구체적으로 Overflow와 Carry에 대해 다루는 다음 포스팅에서 구체적으로 정리하도록 하겠다.
'CS > 어셈블리' 카테고리의 다른 글
[SPARC] 13. Hardware & 큰 수 연산 (0) | 2023.10.11 |
---|---|
[SPARC] 12. Unsigned/Signed Integer & Carry / Overflow (0) | 2023.10.06 |
[SPARC] 10. SPARC에서 사용하는 메모리 종류 (0) | 2023.10.04 |
[SPARC] 9. Assembly Language Programming (0) | 2023.09.30 |
[SPARC] 8. SPARC Regsiter Window & Assembly Instruction Format (0) | 2023.09.27 |