용어 Memory : stores a programs instructions and data size of an instrcution : 4 byte size of data : Byte(1 byte), Half word(2 byte), Word(4 byte), Double (8 byte) => memory read/write size Register : memory place in a processor (CPU), store intermediate results during calculation, or values often used size of register : 4 byte Text Section : save the program instructions, save read-only data (glo..
10진수 소수 2진수 소수 상호 변환 이번 글에서부터는 컴퓨터가 '실수'를 어떻게 표현하는지 정리하고자 한다. 이진수를 다루는 컴퓨터가 실수를 어떻게 표현하는지를 알기 위해 먼저 10진수의 소수가 어떤 식으로 표현되고 있는지를 생각해보자. 10.155 라는 소수는 1 x 10^1 0 x 10^0 1 x 10^-1 5 x 10^-2 5 x 10^-3 이렇게 표현된다는 건 자연스럽게 알고 있다. 이는 이진수에서도 마찬가지로 작용한다. 10.111 이라는 이진수 소수는 1 x 2^1 0 x 2^0 1 x 2^-1 1 x 2^-2 1 x 2^-3 이렇게 표현된다. 그리고 이 값을 10진수로 잘 계산해주면 우리가 사용하는 10진수 소수값이 나온다. 그리고 이 과정을 통해 자연스럽게 2진수를 10진수로 변환하는 방..
지난 글에서는 6개를 넘는 매개변수를 서브루틴에 넘기는 방법과 그 예제를 살펴보았다. 이번 글에서는 서브루틴의 값 반환 중 '구조체'를 반환하는 경우를 중점적으로 정리해보고자 한다. 서브루틴의 값 반환 서브루틴에서 값을 반환할 때, word 하나 사이즈의 데이터를 반환하는 것은 %i0 레지스터를 통해 값을 넘기면 되었다. 그리고 서브루틴을 호출한 함수 입장에서는 %o0 위치에서 반환 값을 읽어올 수 있었다. 그렇다면 아래 C 코드와 같이 구조체를 반환하는 경우는 어떻게 받아올 수 있을까? struct point { int x; int y; }; struct point zero() { struct point local; local.x = 0; local.y = 0; return local; } struct..
지난 글에서는 함수를 호출하는 call 명령어와, 이와 비슷하게 코드의 실행을 조정하는 jmpl 명령어, 그리고 이전 주소로 복귀하는 ret 명령어와 retl 명령어에 대해 정리하였다. 이번 글에서는 call 명령어를 호출한 이후, 함수의 시작을 알리는 역할로 불리는 save 명령어에 대해 정리하고자 한다. 'Save' Instruction save 명령어는 서브루틴을 위한 공간을 할당하는 명령어로서, 함수의 시작을 나타낸다. save 명령어는 2가지 기능을 한다. 첫번째 기능은 스택 메모리에 사용자가 지정한 사이즈 (스택 프레임의 사이즈) 만큼 공간을 할당한다. 공간을 할당하는 것은 %fp, %sp 의 이동과 같다. %fp 은 스택 프레임의 시작점, %sp 는 스택 프레임의 끝 점을 의미한다. 스택 공..
지난 글에서는 스택 프레임을 사용하는 예제를 정리하였다. 이번 글에서는 스택 메모리에 일차원 배열을 선언하는 방법을 정리하고자 한다. 스택에서 일차원 배열 선언하기 함수 안에서 아래와 같이 변수를 선언한다고 해보자. int a; int array[5]; int b; 이 경우, 실제 스택에는 지역변수들이 어떤 순서로 들어갈까? 우선 선언한 순서대로, 높은 주소인 %fp부터 채워지므로 a > array > b 순서로 채워진다. 그렇다면 array 내부에서는 어떤 순서로 채워질까? array 내부에서는 array[0]~array[4] 가 주소가 '증가하는' 순서대로 할당이 되어야 한다. 그런데 스택에서는 점점 주소가 감소하는 방향으로 공간이 넓어지므로 아래와 같은 순서로 할당받게 된다. [높은 주소] [낮은 ..
지난 글에서는 스택 프레임의 개념에 대해 정리하였다. 스택프레임은 스택이라는 메모리 공간을 차지하는 기본 단위이다. 서브루틴을 호출할 때마다 레지스터와 스택프레임이 할당된다. 이때 할당되는 스택프레임의 크기는 save 명령어를 통해 지정할 수 있는데, 최소 사이즈는 64바이트였다. (l-register, i-register 저장 용도) 만약 스택 프레임 내에서 또다른 함수를 호출한다면, 구조체 반환 포인터 크기 4byte와, 매개변수 전달 용도의 24byte 사이즈 공간이 추가로 더 필요해 최소 92byte 사이즈가 필요했다. 여기에 만약 지역변수를 추가로 사용한다면 사용할 지역변수의 총 사이즈만큼 추가로 할당이 필요했다. 마지막으로 총 사용하는 사이즈 크기를 8의 배수로 맞춰 생성해야 한다. 스택 프레..
지난 글에서는 Unsigned Integer / Signed Integer 연산에 대해 정리하였다. Unsigned 연산에서는 덧셈 뺄셈시 Carry가 중요했다. 만약 덧셈을 했는데 Carry 가 발생했다면 오버플로우가 발생한 것이고, 뺄셈을 했는데 Carry가 발생했다면 빼는 수가 빼지는 수보다 더 큰 것임을 의미했다. (그래서 이것이 subcc 를 비교에 사용하는 이유이다.) Signed 연산에서는 덧셈 뺄셈시 Overflow 가 중요했다. 만약 양수와 양수를 더했는데 음수가 나온 것처럼 N 이 활성화 되었다면 오버플로우가 발생한 것이고, 원래 의도된 계산 값이 양수임을 알 수 있다. 만약 음수와 음수를 더했는데, 양수가 나온 것처럼 N 이 활성화되지 않았다면, 오버플로우가 발생한 것이고, 원래 의도..
지난 글에서는 산술 연산과 그 결과에 따라 발생하는 Condition Code 의 종류에 대해 정리하였다. 산술 연산에 대표적으로 add 와 sub 가 있는데, 명령어에 cc 옵션(?)을 붙인 addcc, subcc 명령어는 연산 후 condition code를 반환한다. Condition Code에는 Z, N, V, C 4가지가 있었으며, Z는 연산 결과가 0인지 판별하고, N 은 연산 결과가 음수인지 판별한다. V는 오버플로우 여부를 판별하고, C는 캐리를 반환한다. 이번 글에서는 4가지 코드 중 V 와 C 에 대해 조금 더 자세하게 정리해보고자 한다. 그리고 이를 위해 먼저 Unsigned Integer 와 Signed Integer 에 대해 정리해보겠다. Unsigned Integer / Sign..
지난 글에서는 SPARC 언어에서 사용하는 메모리의 종류 Static, Heap, Stack 에 대하여 알아보았다. 전역 변수의 값은 Static 영역, 지역 변수의 값은 Stack 영역, 동적 할당 시에는 Heap 메모리 영역에 데이터가 저장되었다. 그 중 Stack을 자세하게 알아보았는데, Stack은 높은 메모리주소부터 감소하면서 할당되었다. (어셈블리 기준 직접 할당) 할당 명령어는 save, 반환 명령어는 restore 이었고, save 명령어를 통해 stack 과 32byte register 공간도 같이 할당 받았다. 스택의 할당시에는 스택 포인터를 이용해 할당 위치를 알 수 있었다. 이번 글에서는 산술 연산과 Condition Code에 대해 간단하게 살펴보고자 한다. 산술연산 C언어에서 사..
지난 포스팅에서는 어셈블리 언어의 명령어 타입 3가지를 정리해보았다. 의사 명령어 / 기계 명렁어 / 합성 명령어 이렇게 3가지 종류의 명령어가 있었으며, 의사 명령어 = 기계어 번역 x, 어셈블러에게 추가 정보 전달 기계 명령어 = 기계어로 1:1 번역 합성 명령어 = 기계 명령어 형태로 바뀐 뒤 기계어로 번역 이렇게 정리할 수 있었다. 이번에는 SPARC에서 사용하는 메모리 종류에 대해 정리해보겠다. 프로그램에서 사용하는 메모리의 종류 프로그램에서 사용하는 변수는 크게 3가지가 있다. 1. 전역 변수 (Global Variable) 2. 지역 변수 (Local Variable) 3. 동적 할당 변수 (Heap) 전역 변수는 말 그대로 global 한 범위에서 사용이 가능한 변수이다. 전역 변수는 전역..