< 2강. 명령어 : 컴퓨터 언어 >
[문과 코린이의 IT기록장] 컴퓨터 구조 - 2.(4) ~ 2.(6)
[ 부호있는수와 부호없는 수, 명령어의 컴퓨터 내부 표현, 논리연산 명령어 ]
4. 부호있는 수와 부호없는 수
- 모든 정보는 이진 자리 수(binary digit), 즉 bit로 구성되므로 비트가 계산의 기본 단위가 된다.
* 기본 단위 표현방식 : 높음/낮음, 온/오프, 참/거짓, 1/0
- 어떤 기수(진수)의 숫자에서 I번째 숫자 d의 값은 : d * Base^i
- 여기서 I는 0에서 시작해서 왼쪽으로 갈 수록 증가한다.
- LSB : MIPS워드에서 가장 오른쪽 비트 0
- MSB : MIPS워드에서 가장 왼쪽 비트 31 [=부호비트]
- MIPS워드의 길이는 32bit이므로 2^32가지의 서로 다른 32비트 패턴을 표현할 수 있다.
* 0부터 2^32-1(4,294,976,295ten)까지의 숫자 표시 가능.
- 오버플로
: 이진 비트 패턴의 사칙연산 결과가, 하드웨어에 구현된 오른쪽 비트들로만은 표현이 불가능하다면 오버플로가 발생했다고 한다.
: 이는 프로그래밍 언어와 운영체제 및 프로그램의 몫이다.
ex) 2의 보수 연산의 경우 결과가 음수인데,무수히 많은 비트로 표현해서 MSB가 0이 되는 경우
- 컴퓨터 프로그래밍은 양수와 음수를 모두 계산함. 따라서 이를 구분하는 표현방법이 필요한데 이 방법의 이름은 부호와 크기 표기법임.
[ 부호와 크기 표기법의 단점 ] |
- 그 결과 0들이 앞에 나오면 양수, 1들이 앞에 나오면 음수가 되었음.
- 부호있는 이진수를 표현하는 이러한 방식은 2의 보수 표현법이라고 함.
2의 보수에는 대응되는 양수가 없는 음수 -2,147,483,648ten이 존재한다. 이러한 불균형이 부주의한 프로그래머에게는 문제였지만, 기존의 부호와 크기 표현법은 프로그래머와 하드웨어 설계자 모두에게 문제였었다. 결과적으로 오늘날 모든 컴퓨터는 부호있는 수를 2의 보수로 표현하고 있다. |
- 부호있는 수와 부호없는 수는 산술연산뿐 아니라, 적재명령어랑도 관련 있음.
: 부호있는 적재의 경우 레지스터의 남는 곳을 채우기 위해 부호를 반복하여 복사 [부호 확장을 함.]
: 이것의 목적은 레지스터 내부에 정확한 값을 적재하기 위함임.
cf) 32bit 레지스터에 32bit 워드를 적재할 경우에는 논의 필요
lb(load byte) : 바이트를 부호있는 수로 간주하고 남은 24bit를 부호확장하여 채운다.
lbu : 부호없는 정수를 다룸. 바이트 적재를 위해서만 사용
- 메모리 번지는 항상 양수 (음수 주소는 의미가 없음)
5. 명령어의 컴퓨터 내부 표현
- 레지스터가 명령어에서 참조가 되기 때문에, 레지스터 이름을 숫자로 매핑하는 규칙 O
① [ MIPS ]
$s0~$s7 : 레지스터 번호 16~23
$t0~$t7 : 레지스터 번호 8~15
[ MIPS 어셈블리 언어를 기계어로 변환 ]
ex ) 다음 어셈블리 명령어를 실제 MIPS 언어 버전을 십진수와 이진수 형태로 표현하라
add $t0, $s1, $s2
풀이 )
십진수 표현은 다음과 같다.
0 |
17 ($s1) |
18 ($s2) |
8 ($t0) |
0 |
32 |
필드 : 명령어의 각 부분
[ 필드 역할 설명 ] |
이 명령어의 필드 값을 이진수로 표현하면?
000000 |
10001 |
10010 |
01000 |
00000 |
10000 |
② MIPS 명령어의 필드
- 표시하기 쉽게 MIPS명령어의 각 필드에는 다음과 같은 이름이 붙어 있다.
1. R타입 )
op |
rs |
rt |
rd |
shamt |
funct |
[ 각 이름의 의미 ] 1) op : 명령어가 실행할 연산자의 종류로서, 연산자(opcode)라고 부른다 2) rs : 첫 번째 근원지(source) 피연산자 레지스터 3) rt : 두 번 째 근원지 피연산자 레지스터 4) rd : 목적지 레지스터. 연산 결과가 기억된다. 5) shamt : 자리이동(shift) 6) funct : op필드에서 연산의 종류를 표시하고 funct필드에서는 그 중의 한 연산을 구체적으로 지정한다. 기능 코드(function code)라고 한다. |
- 하드웨어 설계원칙 3
: 좋은 설계에는 적당한 절충이 필요하다
ex) lw를 사용할 때 5비트 필드로는 부족함.
* MIPS 설계자들이 택한 절충안은 모든 명령어의 길이를 같게 하되, 명령어 종에 따라 형식은 다르게 하는 것이었음.
2. I타입 )
op |
rs |
rt |
constant or address |
- I 타입은 수치연산 및 데이터 전송 명령어에서 사용된다.
* lw 주소, addi 상수는 +-2^15보다 클 수 없다.
ex ) lw $t0, 32($s3) 여기서 rs필드에는 19($s3)의 번호, rt필드에는 8($t0), 주소필드에는 32가 들어간다. 이 명령어에서는 rt필드의 의미가 R타입과는 다르며, 적재 결과가 들어갈 목적지 레지스터 번호를 표시하는 것으로 바뀌었다. |
- 명령어형식은 op필드를 통해 확인 가능 : R타입 (0), I타입(ten형식)
[ MIPS 명령어 인코딩 ]
instruction |
Format |
op |
rs |
rt |
rd |
shamt |
funct |
address |
add |
R |
O |
reg |
reg |
reg |
0 |
32ten |
n.a. |
sub |
R |
O |
reg |
reg |
reg |
0 |
34ten |
n.a. |
addi |
I |
8ten |
reg |
reg |
n.a. |
n.a. |
n.a. |
constant |
lw |
I |
35ten |
reg |
reg |
n.a |
n.a. |
n.a. |
address |
sw |
I |
43ten |
reg |
reg |
n.a. |
n.a. |
n.a. |
address |
[ MIPS 어셈블리 언어를 기계어로 번역 ]
ex ) $t1에 배열 A의 시작 주소가 기억되어 있고, $s2는 변수 h에 대응된다고 할 때 다음 C문장
A[300] = h + A[300]은 아래와 같이 컴파일된다.
풀이 )
lw $t0, 1200($t1)
add $t0, $s2, $t0
sw $t0, 1200($t1)
이 세 명령어에 해당하는 MIPS기계어를 보여라
1) 편의를 위해 먼저 기계어 명령어를 십진수로 표기
op |
rs |
rt |
rd |
shamt/address |
funct |
35 |
9 |
8 |
1200 |
||
0 |
18 |
8 |
8 |
0 |
32 |
43 |
9 |
8 |
1200 |
2) 이진수 변환
100011 |
01001 |
01000 |
0000 0100 1011 0000 |
||
000000 |
10010 |
01000 |
01000 |
00000 |
100000 |
101011 |
01001 |
01000 |
0000 0100 1011 0000 |
[ 하드웨어 소프트웨어 인터페이스 ] 모든 명령어의 길이를 같게 하려는 욕망과, 더 많은 레지스터를 가지스터를 가지려는 욕망이 충돌을 일어킬 가능성 O - 레지스터 개수 증가 : 명령어 형식에서 각각의 레지스터 필드는 적어도 1bit가 더 필요하게 됨. - ‘작은 것이 더 빠르다’라는 설계원칙 반영 필요성 존재. ** 이와 같은 요인들 때문에 대부분 오늘날의 명령어 집합은 16 또는 32개의 범용 레지스터를 갖고 있음. |
오늘날의 컴퓨터는 두 가지 중요한 원리에 바탕을 두고 있음. [ 내장 프로그램의 개념 ] 1. 명령어는 숫자로 표현된다. * 프로그램이 이진수 파일 형태로 판매되게 되었음. * 이는 상업적으로, 만약 기존 명령어 집합과 호환성이 있다면 다른 컴퓨터의 소프트웨어를 물려받을 수 있다는 의미를 갖는다. * 이러한 이진 호환성 문제 때문에, 상업적으로 살아남는 명령어 집합 구조는 극히 소수로 집합된다. 2. 프로그램은 메모리에 기억되어 있어서 숫자처럼 읽고 쓸 수 있다. * 이 개념을 발명한 덕택에 컴퓨터가 눈부시게 발전할 수 있었음. |
6. 논리연산 명령어
- 초기 컴퓨터 : 워드 전체에 대한 처리에만 관심
- 후기 컴퓨터 : 워드 내 일부 비트들에 대한 연산, 개개 비트들에 대한 연산도 관심을 가지게 됨.
[ 논리 연산 명령어 ]
- 명령어 집합에, 비트를 워드로 묶는 (packing) 작업과, 워드를 비트 단위로 나누는 (unpacking) 작업을 간단하게 하는 명령들이 추가되었음.
Logical operations |
C operators |
MIPS instructions |
Shift left |
<< |
sll |
Shift rgiht |
>> |
srl |
Bit-by-bit And |
& |
and, andi |
Bit-by-bit OR |
| |
or, ori |
Bit-by-bit Not |
~ |
nor |
1) Shift(자리이동)
- sll $t2, $s0, 4 // 왼쪽으로 4bit 자리이동
[ 기계어 ]
op |
rs |
rt |
rd |
shamt |
funct |
0 * op, funct 모두 0이면 sll |
0 * 기초적인 것이 X |
16 |
10 |
4 * 자리이동량 |
0 * op, funct 모두 0이면 sll |
- sll명령은 왼쪽으로 I비트 자리이동하면, 2^i을 곱한 것과 같은 결과가 된다.
ex) |
2) AND
- AND는 비트 대 비트 연산자로서 두 비트 값이 모두 1일 경우에만 결과가 1이 된다.
ex ) MIPS 명령어 : AND $t0, $t1, $t2 실행하기
$t2 : 0000 0000 0000 0000 0000 1101 1100 0000 two
$t1 : 0000 0000 0000 0000 0011 1100 0000 0000 two
일 경우,
$t0 : 0000 0000 0000 0000 0000 1100 0000 0000 two
- AND는 어떤 비트 패턴에서 0의 위치에 해당하는 비트들을 강제로 0으로 만들 수 있다.
= 마스크(mask) * 일부 비트를 감추는 역할
3) OR
- OR은 비트 대 비트 연산자로 둘 중 하나만 1이면 결과가 1이 되는 것이다.
ex) MIPS 명령어 : OR $t0, $t1, $t2 실행하기
$t2 : 0000 0000 0000 0000 0000 1101 1100 0000 two
$t1 : 0000 0000 0000 0000 0011 1100 0000 0000 two
일 경우,
$t0 : 0000 0000 0000 0000 0011 1101 1100 0000 two
4) NOT
- 피연산자 하나를 받아서, 피연산자의 비트가 1이면, 결과를 0으로, 0이면 1로 변환한다.
- MIPS 설계자들은 NOT 피연산자 대신 NOR(Not Or) 명령어를 포함시켰다.
- 피연산자 하나가 0이면 NOT과 같아진다.
즉, NOR 0 = NOT(A OR 0) = NOT(A)
5) XOR
- 두 비트가 서로 다르면 1, 같으면 0이 된다.
- C에서는 워드 안에 비트 필드 또는 필드라는 것을 정의할 수 있음.
- 이를 이용하면 한 워드 내에 여러 값을 넣을 수도 있고, 입출력장치같이 외부의 융통성 없는 인터페이스에 맞출 수도 있음
- 모든 필드는 한 워드에 들어갈 수 있는 크기이어야 하며 최소 길이 1bit의 부호없는 정수
- C 컴파일러는 MIPS의 논리연산 and, or, sll, srl등을 사용하여 필드를 삽입,추출 가능
6) 논리연산 명령어인 andi와 ori를 사용하면 상위 16bit에 32bit 상수를 만들 수 있다. 이는 addi와 다른데, addi는 부호를 확장한다.
* 유의사항 - 아직 공부하고 있는 문과생 코린이가, 정리해서 남겨놓은 정리 및 필기노트입니다. - 정확하지 않거나, 틀린 점이 있을 수 있으니, 유의해서 봐주시면 감사하겠습니다. - 혹시 잘못된 점을 발견하셨다면, 댓글로 친절하게 남겨주시면 감사하겠습니다 :) |