4강)
논리 연산
- 기계어에서의 논리연산은 숫자로 보는 관점이 아니라 비트 단위의 AND OR 를 나타낸다
- XOR 는 두 비트가 같으면 거짓 (0), 두 비트가 다르면 참 (1) 이 되는 연산.
- and immediate : 더 큰 숫자와 작은 숫자를 연산 할 때는 작은 부분을 확장해야 한다. 확장할 때는 전부 0으로 채워준다 (일반적임).
- 꼭 그렇지 않을수 도 있음. 양수만 있으면 작은 숫자에 상위 비트를 0으로 채우면 되지만, 숫자중 음수가 있다면 ?
- 컴퓨터에서는 2의 보수형태를 이용해서 음수를 표현함. 1로 채우기 (?) => 연산 장치를 편리하게 구성할 수 있기 때문임.
- 최상위비트를 1로 나타내기도 함
메모리에 접근하는 연산
1. LOAD
2. STORE
- 로드는 메모리에서 읽어와서 레지스터로 값을 저장하는 것
- 스토어는 반대로 메모리 번지에 레지스터 값을 저장하는 것
- load byte unsigned : 1바이트를 메모리에서 레지스터로 저장하는 것
메모리의 주소를 표현하기 위해서는 32비트가 필요했다.
그런데, 기계어 하나가 32비트기 때문에 메모리 주소를 표현하기 위해 가용한 공간은 26비트 뿐이다.
적어도 레지스터 하나를 기계어에 표현해야 하기때문에 또 5비트가 빠져서 21비트만 남는다.
=> 21비트 한정적 ...
LOAD STORE 에서는 접근하려는 메모리의 기본 주소는 register 에다가 집어넣게 된다.
레지스터 내용을 계속 바꾸는 것은 그것 자체로 오버헤드가 되기 때문에 레지스터에 기본 주소를 넣고 16비트에 오프셋을 적어서 메모리 주소를 표현한다.
레지스터에 있는 주소와 오프셋을 합한 주소로 접근 $s1 = Memory [ $s2 + 100 ]
4byte 단위로 LOAD, STORE 하는 것이고 Store byte 등을 해주면 1바이트 단위로 가능함.
- 근데, 레지스터는 4바이트인데 ?
레지스터는 지금 4바이트의 내용이 있는데, 메모리 번지에 1바이트만 저장?
메모리에는 일부만 저장한다는데 어떻게 하면 되는가?
- 레지스터에서 앞의 3바이트는 잘라내고, 최하위 바이트만 메모리에 저장한다.
- 위에 3바이트 비는 것은 어떻게 하는가? - 양수면 0으로, 음수면 1로 채워 넣어서 레지스터 값을 복원 (?)
모든 MIPS 의 연산에서는 unsigned 로 하는 것이 가능하다.
즉, 저장된 값을 양수로만 해석을 하라는 의미이다.
load byte 하고 load byte unsinged 의 차이는?
$s1 = Memory [$s2 + 100]
- 1바이트만 읽어서 저장하면 나머지 3바이트는 양수 음수인지에 따라 0 또는 1로 채운다.
- 만약 unsigned 로 된 연산이 가능하면 메모리 위치에서부터 양수로 읽어와서, 넣는다. 8bit 를 모두 양수로 해석하라.
operation 에서 unsigned 가 붙지 않으면 기본적으로 모두 signed operation 이다.
Alignment restriction 경계를 지켜 주어야 한다.
- MIPS 에서 주소를 표현할 때 4바이트 단위로 뭔가 읽고 쓰고 할 때는 메모리의 주소가 반드시 4의 배수여야
- 메모리에서 2바이트 접근 할 때 는 주소도 2의 배수여야 한다.
5강)
기계어를 CPU가 매 번 하나씩 실행하게 되는데, MIPS 의 경우 4바이트의 기계어를 CPU가 실행한다.
그러고 나서 PC가 자동적으로 그 다음 4바이트로 옮겨가서 다음 명령어를 실행하도록 한다. (자동적으로 4씩 증가)
고급 언어로 프로그램을 작성하다 보면 조건에 따라서 조건을 만족하지 않으면 다른 부분을 실행한다던가,
반복문을 실행하기도 하는 등 다른 위치로 PC가 바뀌어야 할 필요성이 있다.
이런식으로 PC 위치를 바꾸는 것이 conditional branch instruction, unconditional jump instruction 이다.
Conditional Branch
- branch on equal
- branch on not equal
포맷 : 레지스터 두개와 16비트 이미디어트를 사용
레지스터 값 두개 같으면 go to .../ 다르면 go to ... 와 같이 사용된다.
ra - 31번 레지스터, 리턴 어드레스.
점프 레지스터 : 메모리의 위치를 레지스터에 적는다. 모든 2^32개 주소 참조 가능.
점프 2500 => 4의 배수로 주소를 계산하게 되므로 실제로는 10000번지를 참조하게 될 것. (go to 10000)
6강)
기계어의 구성을 살펴보면, 32비트 중 6비트는 연산자를 나타내고, 나머지 28비트는 피연산자의 주소를 표현하는 데 사용된다. 하지만 피연산자의 종류에 따라서 (레지스터인지, 이미디어트인지, 메모리주소인지 ... ) 비트가 남을 수 도 있다.
연산자의 종류를 더욱 다양하게 구성하기 위해서 (혹은 남는 비트를 잘 활용하기 위함인지?) 연산자를 위한 앞의 6비트 말고도 피연산자 부분의 6비트를 연산자를 표현하는 데 동원하기도 한다.
위의 연산자 코드를 보면, 가장 위에 000000, 000001 과 같은 식으로 opcode 가 구성이 되면, 다른 브랜치 연산에 필요한 명령어라든가, 레지스터 연산을 위한 연산자를 참조할 수 있게 된다. (남는 비트에다가 연산자를 넣고, 실제 opcode 비트에는 0... 1로 채워넣는 것.
위의 표에서 맨 앞의 6비트가 오피코드 (opcode) 로써 연산자를 나타내는 부분이다. 그리고 맨 뒤의 funct 라는 부분 또한 경우에 따라 연산자를 표현하는 데 사용되기도 한다.
위의 기계어의 의미 : 로드 바이트 연산, 1바이트를 메모리에서 읽어서 레지스터 8번에 저장하라는 뜻.
- 어셈블리 언어와 비트 표현은 순서가 다르다는 것 참고
9번 레지스터에 메모리의 베이스 주소가 있고, 여기서부터 4바이트 떨어진 위치에서 1바이트를 읽는다.
읽은 값을 레지스터 8번에 저장한다.
메모리에서 최하위 3바이트는 저장하지 않고, 양수이면 0으로 음수이면 1로 채워서 넣는다.
17번 18번 레지스터의 값을 더해서 8번 레지스터에 저장해라.
더하는 연산의 경우 기계어의 공간이 남기 때문에 실제 opcode 에는 0으로 채워져 있고, funct 부분에 더하라는 연산이 채워진다.
* PPT : function field 가 실제 operation 을 결정.
레지스터 9번의 값과 이미디어트 4번을 더해서 8번 레지스터에 저장하라.
- 이미디어트는 인스트럭션 자체에 직접 포함되는 상수 필드
- 이미디어트는 재사용 불가 => 레지스터나 메모리에 값을 저장해놓으면 그 다음 인스트럭션에서 값을 다시 꺼내볼 수 있으나, 기계어 안에 내장된 이미디어트의 경우 재사용 불가. 굉장히 작은 숫자만 표현할 수 있다. 하지만 추가적인 메모리 접근이 없어서 연산이 빠르다.
나머지 26비트로 점프할 타겟 어드레스를 표현한다.
점프의 타겟 어드레스는 항상 4의 배수가 된다.
점프 타겟 어드레스 전체를 적을 필요가 없고, 4로 나눈 값을 적어도 된다.
4의 배수 = 뒤의 마지막 비트가 00 인 것
28비트로 표현 가능한 메모리의위치를 커버할 수 있음 !
브랜치 이퀄 : 5번과 7번이 같으면 엑스로 점프하라.
현재 위치로부터 그 숫자(XXX)만큼 떨어진 곳으로 branch 를 하라는 뜻
브랜치가 없으면 PC는 자동으로 4씩 증가한 값을 가리킨다.
18비트로 표현 가능한, 현재 위치로부터 가까운 곳으로 점프가 가능하기 때문에 브랜치 제약이 있음.
하지만 Spatial locality 에 의해서 아주 먼 주소로 점프를 하게 될 가능성은 별로 없음.
그냥 점프는 26비트에 적힌 절대 주소로 점프하는 것.
브랜치는 16비트에 현재 위치로부터의 오프셋이 적혀있고, 조건에 맞으면 그 주소로 가는 것.
'Operating System' 카테고리의 다른 글
[System Software] 프로그램의 메모리 주소 공간 구조 (0) | 2021.02.08 |
---|---|
[System Software] C언어&어셈블리 예제 (0) | 2021.02.07 |
[System Software] MIPS Operators (0) | 2021.01.26 |
[System Software] ISA / MIPS (0) | 2021.01.24 |
[OS] Communication in Client - Server Systems (0) | 2020.06.27 |