Dev_bob

[논리회로]Machine Language 본문

전공수업정리/논리회로

[논리회로]Machine Language

킹대왕너구리 2024. 5. 27. 14:59

Machine Languages

-기계어 프로그램: 일련의 (이진)코드화 된 명령어

어셈블리어

-기계 명령어의 기호 표기법

-어셈블러에 의해 이진(기계명령어)로 번역됨

하드웨어 구조에 크게 의존함(CPU 작동, 레지스터의 수와 유형)

-각 컴퓨터마다 다른 기계어를 가짐

 

Machines

1. 메모리

데이터와 명령어를 저장하는 하드웨어 장치 모음

"단어"의 배열

표기법:Memory[주소],RAM[주소],M[주소]

2.프로세서(CPU:중앙처리장치)

기본적인 작업을 수행할 수 있는 장치

피연산자는 레지스터 또는 메모리에서 가져옴

결과는 레지스터 또는 메모리에 저장됨

3. 레지스터

고속의 로컬 메모리

각각 단일 값을 가질 수 있음

느린 메모리 접근 작업을 보완하는데 사용됨

프로세서가 데이터와 명령어를 빠르게 조작할 수 있게 함

 

이미지출처 : https://www.totalphase.com/blog/2023/05/what-is-register-in-cpu-how-does-it-work/

 

 

기계어 명령어 

산술논리

덧셈,뺄셈,비트단위 부정, 비트 이동

ADD R2,R1,R3  // R2=R1+R3 여기서 R1,R2,R3는 레지스터
ADD R2,R1,foo // R2=R1+foo 여기서 foo는 사용자가 정의한 레이블 foo가 가리키는 메모리 위치의 값
AND R1,R1,R2  // R1=R1과 R2의 비트 단위 AND

 

메모리접근

1. 산술 및 논리 명령어

2. 명시적 로드 및 저장 명령어

//직접 주소 지정
LOAD R1,67  // R1=Memory[67]
// 또는 bar가 메모리 주소 67을 참조한다고 가정하면:
LOAD R1,bar // R1=Memory[67]

//즉시 주소 지정
LOADI R1,67  // R1=67

//간접 주소 지정(포인터처리)
// x=foo[j] 또는 x=*(foo+j)의 번역:
ADD R1,foo,j  // R1=foo+j
LOAD* R2,R1   // R2=Memory[R1]
STR R2,x      // x=R2

 

제어흐름

반복문/조건부 실행

//무조건 점프
// A while loop:
while (R1>=0) {
    code segment 1
}
code segment 2

//조건부 점프
beginWhile:
JNG R1,endWhile  // R1<0이면 endWhile로 이동
// code segment 1의 번역이 여기로 옴
JMP beginWhile  // beginWhile로 이동
endWhile:
// code segment 2의 번역이 여기로 옴

참고로, JNG는 Jump not greater의 약자로 조건부 점프 명령어입니다. R1이 0보다 작으면 지정된 라벨로 점프합니다.

그래서 코드를 보면 JNG R1, endwhile이면 R1이 0보다 작게되면 endWhile로 이동함을 알 수 있습니다.

무조건 점프 코드와 로직이 비슷하니 비교하면서 보시면 이해가 되실겁니다!

 

 

Hack 컴퓨터

16비트 기계

구성요소 :

1개의 CPU

두개의 별도 메모리 모듈(ROM과 RAM)

두 개의 메모리 맵 입출력 장치 (화면,키보드)

이미지 출처 : https://en.wikipedia.org/wiki/Hack_computer

Hack 메모리 주소 공간

두 개의 독립된 주소 공간

-ROM은 명령어 메모리

-RAM은 데이터 메모리

16비트 너비 및 15비트 주소공간(32K 16비트 단어)

명령어 메모리

-읽기 전용

-프로그램은 하드웨어 시뮬레이터에 의해 텍스트 파일에서 명령어 메모리로 로드됨

 

Hack 레지스터

두개의 16비트 레지스터-D&A

D 레지스터 (data)- 데이터 값을 저장하는데만 사용됨

A 레지스터(address) - 데이터 및 주소를 모두 저장

-간접 주소 지정 모드를 사용해 데이터 메모리에 직접 접근을 용이하게 할 수 있다.

-16비트 명령어,15비트 주소

--명령어 코드와 주소는 함께 패킹될 수 없다.

--메모리 위치 "M"은 항상 A레지스터 현재 값을 참조함.

 -명령어 메모리에 직접 접근을 용이하게 위해 사용됨-점프 연산은 항상 A레지스터가 가리키는 메모리 단어에 있는 명령어로 점프

 

Hack 언어

대부분 자체 설명적이다.

"@value" : 지정된 값을 A 레지스터에 저장

ex) "sum"이 메모리 위치 17을 참조하는 경우, "@17"과 "@sum"은 둘 다 "A<-17" 수행

메모리 위치와 관련된모든 연산은 두개의 Hack 명령어가 필요

 

Hack Example

 

1부터 100까지 더하는 코드를 C로 작성해보겠습니다.

// 1부터 100까지의 합을 구합니다.
int i = 1;
int sum = 0;
while (i <= 100) {
    sum += i;
    i++;
}

 

이에 대한  Hack 어셈블리 코드를 작성해보겠습니다.

// 1부터 100까지의 합을 구합니다.
@i          // i는 메모리 위치를 참조합니다.
M=1         // 메모리 위치 i에 1을 저장합니다.
@sum        // sum은 메모리 위치를 참조합니다.
M=0         // 메모리 위치 sum에 0을 저장합니다.
(LOOP)      // LOOP 레이블
@i          // i의 값 가져오기
D=M         // D 레지스터에 i의 값을 저장합니다.
@100        // 상수 100을 참조합니다.
D=D-A       // D = D - 100 (이후, D == i - 100)
@END        // END 레이블을 참조합니다.
D;JGT       // 만약 D > 0 (i > 100)이면 END로 점프합니다.
@i          // i의 값을 다시 가져오기
D=M         // D 레지스터에 i의 값을 저장합니다.
@sum        // sum의 값을 가져오기
M=M+D       // sum = sum + i
@i          // i의 값을 다시 가져오기
M=M+1       // i = i + 1
@LOOP       // LOOP 레이블을 참조합니다.
0;JMP       // 무조건 LOOP로 점프합니다.
(END)       // END 레이블
@END        // END 레이블을 참조합니다.
0;JMP       // 무한 루프 (여기서는 프로그램 종료를 나타냅니다)

 

Lab Activity: Try Running the 1st ASM Program

A-명령어

A레지스터를 15비트 값으로 설정하는데 사용

예) @5 -> 0000 0000 0000 0101

 

@constant_value

컴퓨터에 상수를 입력하는 유일한 방법

15비트 제한

음수는 입력 불가

일반적으로 피연산자 A다음에 온다.

 

@RAM_address

특정 데이터 메모리 위치를 조작하도록 설계된 후속 C-명령어를 위해 설정

일반적으로 M다음에 온다.

 

@ROM address

점프를 지정하는 후속C 명령어를 위해 설정

일반적으로 점프 명령어 다음에 온다.

 

 

C-명령어(첫번째~세번째 비트)

가장 왼쪽비트(MSB): 항상 1->C-명령어를 나타냄

2번째 3번째 비트: 사용되지 않음. 11로 설정

comp필드:a c1 c2 c3 c4 c5 c6 : ALU에 무엇을 계산할지 지시

ALU 함수 (a,c1~c6 비트)comp

 ALU function입니다.

ALU 함수는 'comp'필드에 의해 지정됨

a값 a=0 a=1
연산 0, 1, -1, D, A, !D, !A, -D, -A, D+1, A+1, D-1, A-1, D+A, D-A, A-D, D&A, D|A M, !M, -M, M+1, M-1, D+M, D-M, M-D, D&M, D|M

목적지 비트(d1,d2,d3)

d1:A레지스터

d2:D레지스터

d3:M,Mem[A]

 

  • 000 (null): 결과가 저장되지 않음
  • 001 (M): Memory[A]
  • 010 (D): D 레지스터
  • 011 (MD): Memory[A] 및 D 레지스터
  • 100 (A): A 레지스터
  • 101 (AM): A 레지스터 및 Memory[A]
  • 110 (AD): A 레지스터 및 D 레지스터
  • 111 (AMD): A 레지스터, Memory[A], D 레지스터

점프 (j1,j2,j3)

점프 명령어는 컴퓨터가 다음에 무엇을 할지 알려줍니다.

점프 수행 주소는 A레지스터에 설정됩니다.

점프 명령어 구문은 <computation>;<jump>형식입니다.

computation은 M/A를 포함하지 않는 comp형식이 될 수 있습니다.

 

점프를 수행한 후에는 A레지스터에 저장된 주소로 이동합니다.

 

<점프 명령어>

  • 000 (null): 점프 없음
  • 001 (JGT): 결과가 0보다 크면 점프
  • 010 (JEQ): 결과가 0이면 점프
  • 011 (JGE): 결과가 0이거나 0보다 크면 점프
  • 100 (JLT): 결과가 0보다 작으면 점프
  • 101 (JNE): 결과가 0이 아니면 점프
  • 110 (JLE): 결과가 0이거나 0보다 작으면 점프
  • 111 (JMP): 무조건 점프

명령어

1. <destination>=<computation>

특정연산computation을 수행하고 그 결과를 destination 위치에 저장하는 방식입니다.

조건 : j1,j2,j3는 0이여야함(점프 명령어를 수행하지 않기 위해)

예시 : M=D+M(D레지스터 값과 M값을 더한 값을 메모리에 저장한다.)

 

2.<computation>;<jump>

계산을 수행 한 후, 특정 조건이 충족되면 점프를 수행한다.

조건 : d1,d2,d3는 0이여야 합니다.(점프 명령어는 값을 저장하지 않기 때문에)

예시:D;JEQ

D레지스터 값이 0이면 점프!

 

Assembly Language Files를 작성하는 방법에 대해 알아보겠습니다.

-asm 파일 확장자를 사용합니다. 

 

//RAM[k]=Ram[i]+RAM[j]

@28	//28의 값을 참조해 A레지스터에 저장A=28

D=A	//A레지스터 값을 D레지스터에 할당 , D=28

@i	//i 주소 값 참조(메모리에 저장, M=Ram[i])

M=D //Ram[i]=28

 // RAM[j]=72
 @72
 D=A
 @j
 M=D
 
  // RAM[k]=RAM[i]+RAM[j]
 @i
 D=M
 @j
 D=D+M
 @k
 M=D