CPU 수준에서 프로그램은 어떻게 실행됩니까?


14

나는 이것이 매우 일반적인 질문이라는 것을 알고 있습니다. 그러나 나는 다른 마음을 가지고 있습니다. 나는 여기에 그것을 분명히하려고 노력할 것입니다.

내가 아는 것에서 CPU가 실행하는 모든 명령은 기계 언어이며 모든 CPU가 할 수있는 것은 ALU와 트랜지스터 (하드웨어 수준에 가면) 덕분에 산술 연산을 수행하는 것입니다.

그러나 이것은 이해하는 것보다 타이핑하기가 더 쉽습니다. 따라서 모든 CPU가 더하기, 빼기 등을 수행하는 경우 print Hello World라고하는 JAVA 프로그램과 같은 프로그램은 어떻게이 산술 연산으로 실행됩니까?

나는이 프로그램이 어떻게 CPU에 추가 된 것으로 변환됩니까?

추신 :이 질문이이 웹 사이트에 해당되지 않는다면 사과드립니다.

-----두 번째 부분-----

괜찮아. 이 열정에 열정적으로 답변 해 주셔서 감사합니다. 나는 모든 답변에 댓글을 달고 다시 질문하는 것보다 내 질문을 약간 수정하는 것이 낫다고 생각했습니다.

여기 있습니다.

먼저, 모두 Hello World의 예를 구체적으로 대답했습니다. 이건 내 잘못이야 나는 이것을 일반적으로 유지해야했다. Hello world 예제는 출력 장치와 그 처리가 CPU에만 국한되지 않는 방법에 대해 의문을 제기합니다.

또한 많은 사람들이 CPU가 단순한 추가 이상의 기능을한다는 사실을 알게되었습니다. 동의합니다. 나는 단지 그것을 쓰지 않고 그것을 완전히 가정했습니다. 내가 이해 한 바에 따르면, 이것은 프로세스입니다.

  1. 메모리에서 명령 읽기 (데이터 및 주소 버스 및 프로그램 카운터를 사용)

    1. CPU 내부의 레지스터에 데이터 저장
    2. 이제 ALU는 명령을 디코딩 한 후 산술 연산을 수행하거나 if 유사 명령 인 경우 점프를 수행합니다.
    3. 그런 다음 출력 장치 등과 같이 필요한 경우 다른 리소스와 통신하십시오. 이 이상의 프로세스는 현재로서는 사소합니다.

따라서 CPU가 명령을 해독하고 산술 연산을 수행하기로 결정하는 3 단계에서 (현재 명령 점프와 같이 수행 할 다른 연산이 없다고 가정합니다.) 산술 연산이 대부분 수행되므로. ) 여기에서 시각화가 끝납니다. 내 프로그램의 명령이 CPU에 대한 산술 연산 방법입니다. 그것은 산술 연산을 수행하고 그 명령은 그 목적을 제공합니다.

이번에는 내가 분명하게 해주길 바랍니다.

추신 : 나는 ALU가 우리의 프로그램에서 수행하는 실제 산술 연산에만 국한되지 않는다는 것을 큰 가정으로 삼고 있습니다. 모든 명령을 실행합니다.이 명령은 더하기 또는 빼기하여 명령을 의미합니다. 수득. 내가 틀렸다면 아래 답변보다 내 질문에 올바르게 대답하십시오.


컴파일러가 프로그램을 기계 언어로 변환한다는 것을 알고 있습니다. 프로그램을 산술 연산으로 시각화 할 수 없습니다. 프로그램 자체가 두 개의 숫자를 추가하는 것이라면 이해할 수 있지만 그렇지 않으면 그렇지 않습니다. :)
2827893

1
어쩌면 MC6502, Z80과 같은 매우 간단한 CPU와 같은 실제 CPU 세트를 살펴보고 메모리 액세스 명령, 데이터 처리 명령, 분기가 있는지 확인하십시오. 그런 다음 어떻게 될 수 있는지 추측 할 수 있습니다 모든 알고리즘을 구현하기 위해 결합되었습니다.
TEMLIB

3
CPU는 확실히 추가 이상의 기능을 수행 할 수 있습니다. CPU가 비교와 점프를 할 수 있다는 것을 언급하는 것이 중요합니다.
Theodoros Chatzigiannakis

1
IF (의사 결정) 및 MOVE (데이터 읽기 및 저장) 확인을 여전히 거부하는 사용자는 프로그램이 99 % IF 및 MOVE입니다. 산술은 무시할 수 있습니다. 첫 번째 예제 (Hello world)에는 전혀 산술이 없습니다.
edc65

1
1. 질문을 변경하기 위해이 질문을 편집하지 않고 새로운 혼란으로 새로운 질문을하면 좋은 답변을 얻을 가능성이 더 높다고 생각합니다. 원래 질문에 대한 정답을 얻었고 원래 질문이 저절로 설 수있는 것처럼 보이므로 수정 사항을 삭제하고 새로운 질문을하는 것이 어떻습니까? 2. 나는 새로운 부분을 이해할 수 없다고 말했다. 새 부품에 대한 귀하의 질문은 정확히 무엇입니까? 당신이 말할 때, 당신이 뜻은 "이 내 시각화 끝이 어디" 3 단계를 이해, 또는 3 단계를 이해하지? 그렇게하면 무엇을 이해하지 못합니까?
DW

답변:


7

간단한 프로그램을 작성하여 원시 기계 코드로 컴파일 할 수 있습니다. Java는 일반적으로 JVM 코드로 컴파일되지만 Andrew Tennenbaum은 기본적으로 실행되는 CPU를 설계하는 방법을 설명하는 책을 보유하고 있습니다. 예를 들어 GCC에서는 컴파일러에 -S스위치 를 제공합니다 .

이것은 운영 체제를 호출하여 I / O와 같이 까다로운 것을 구현한다는 것을 알려줍니다. 소스를 Linux 커널로 다운로드하여 동일한 작업을 수행 할 수는 있지만 모든 작업은 컴퓨터 메모리 상태 (예 : 실행중인 프로세스 목록 또는 기타를 사용하여 하드웨어와 통신)를 조작하는 것입니다. 이를 제어하거나 x86 in과 같은 특수 CPU 명령어를 사용하는 특수 메모리 주소 out. 그러나 일반적으로 장치 드라이버라는 특수 프로그램 만 특정 하드웨어와 통신하며 OS는 하드웨어 사용 요청을 올바른 드라이버로 보냅니다.

구체적으로, 인쇄하면 "hello, world!" 컴파일러는 문자열을 특정 위치에로드하는 명령어 세트 (예 : 메모리에있는 문자열 주소를 %rdi레지스터에로드)와 call명령어 로 라이브러리 함수를 호출하는 명령어 세트로 변환합니다. 이 라이브러리 함수는 루프가있는 문자열의 길이를 찾은 다음 시스템 호출을 호출 할 수 있습니다.write()문자열에서 파일 디스크립터 번호 1 (표준 출력)에 해당 바이트 수를 기록합니다. 이 시점에서 OS는 해당 프로세스의 파일 번호 1이 무엇인지 찾고 해당 파일의 의미를 결정합니다. 표준 출력에 대한 쓰기가 화면에 인쇄되면 바이트를 버퍼에 복사하는 것과 같은 프로세스가 있으며, 터미널 프로그램이이를 읽음으로써 윈도우 시스템에 어떤 글꼴의 어느 위치에 문자를 넣을지를 알려줍니다. 윈도 잉 시스템은 정확히 어떤 모습을 보일지 결정하고 비디오 메모리를 변경하여 픽셀을 화면에 배치하도록 장치 드라이버에 지시합니다.


@Lorehead에게 감사합니다. 이 설명은 Hello World 예제에서 잘 보입니다.
user2827893

5

알다시피 CPU 자체는 바보입니다. 그러나 주변에는 소우주 하드웨어 칩이 있습니다. CPU의 한 줄을 다른 칩에 연결된 높은 수준으로 설정할 수있는 지침이 있습니다. 이 하드웨어 칩이 회선을 모니터링하고 말합니다. "이 회선이 높으면 다른 회선으로 무언가를합니다."

이 작업을보다 쉽게 ​​수행 할 수 있도록 이러한 행을 그룹화합니다. 일부는 장치를 주소 지정하는 데 사용되고 일부는 해당 주소에 대한 데이터를 전송하는 데 사용되며 다른 일부는 "Dude, 내 칩에 중요한 문제가 있습니다"라인입니다.

결국, CPU는 단지 다른 칩에게 "Hello World"처럼 보이도록 모니터의 신호를 수정하십시오.

구글 7 세그먼트 디스플레이의 그림. 전선이있어 전압을 가하면 세그먼트가 켜집니다. 이제 7- 세그먼트 디스플레이의 한 라인으로 CPU의 출력 라인 하나를 연결하면 디스플레이가 켜집니다. LED가 켜지는 것은 CPU가 아니며 단지 라인에 전압을 적용하는 것이지만 다른 하드웨어는 그로 인해 멋진 일을 할 수 있습니다.

CPU가 H의 모든 행을 high로 설정하면 7 세그먼트는 H를 표시하지만 H는 CPU가 더하거나 빼는 숫자가 아닙니다.

이제 모든 레이어가 7- 세그먼트 디스플레이 H (5 개의 특정 라인을 높게 설정)를 만드는 데 필요한 것을 동의하면 Java 컴파일러는 H를 표시하도록 코드를 만들 수 있습니다. 물론 이것은 다소 불편합니다. 추상화합니다. 가장 낮은 레이어는 "Yo, 26 개의 글자가 있습니다. 각 글자에 숫자를 지정합시다-문자 'H'에 숫자 '72'를 주면 어떻습니까? 그러면"Display letter 72 "라고 말하면됩니다. "라인 309 높이 설정, 라인 310 높음 설정, 라인 498 높음 설정, 라인 549 높음 설정, 라인 3 높음 설정"대신 각 레이어가 정보를 추상화하기 시작하여 특정 결과를 얻는 방법이 필요하지 않습니다. 그들에 대해 걱정합니다.

따라서 그렇습니다 .CPU가 실제로 처리 할 수있는 숫자 또는 비트의 huuuuge 매핑으로 요약하면 체인의 모든 사람들이 동의 한 의미에 해당합니다.


3

CS 학위 프로그램의 일환으로 대학 에서 CPU를 정의하는 레지스터 전송 언어 의 확장 된 예를 공부했습니다 . 나는 다른 표현을 취하고 정의와 같은 표기법을 받아들이는 시뮬레이터를 작성하고 영감을 받아 임베디드 시스템 프로그래밍 (1989 년 3 월호)에서 사람들이 요청한 것과 같은 종류의 질문에 대답하는 방법으로 출판했습니다. 그러한 것들에 대한 직관적 인 이해를 구축하십시오.

수업에서 우리는 레지스터의 실제 논리 게이트로 레지스터 전송 표기법을 증류하기 시작했습니다! 'A'를 대상으로하고 코드 A = (case1) 또는 (case2) ...를 갖는 모든 것을 살펴본 다음, 제품 합계 또는 제품 합계 정규화 형식으로 표시됩니다.

과정이 끝났을 때만 이것이 실제 CPU라는 것을 배웠습니다. 올바르게 기억한다면 PDP-8입니다.

오늘날 게이트 다이어그램을 프로그램 가능한 로직 어레이 칩에 공급할 수 있습니다.

그것은 그 요점입니다 : 레지스터는 AND 및 OR 게이트의 결과로 설정되어 다른 레지스터로 돌아갑니다. 포함 할 값 중 하나가 opcode 값입니다.

상상해보십시오 : A : = (opcode == 17 & X + Y) | (opcode == 18 & X + Z) | ...

최신 CPU는 파이프 라인과 버스로 인해 더 복잡하지만 단일 ALU와 같은 개별 하위 장치가 그렇게 작동합니다.


2

여기서 CPU를 고려하고 있지만 'Hello World'를 실행할 때 표시되는 다른 구성 요소가 있습니다!

CPU의 경우 메모리의 값은 주어진 비트 수 (0과 1)로 표시되는 숫자 일뿐입니다.

화면에서 글자로 바뀌는 방법은 또 다른 이야기입니다. 디스플레이에도 메모리가 있습니다. 이 메모리 (그래픽 메모리)는 화면의 '픽셀'에 매핑됩니다. 각 픽셀은 값으로 인코딩됩니다. 매우 기본적인 흑백 디스플레이 인 경우 값은 단지 강도입니다. 컬러 디스플레이의 경우 값은 다양한 방식으로 인코딩 할 수있는 RGB (Red Green 및 Blue)의 조합입니다.

따라서 CPU가 주어진 값을 디스플레이 메모리에 '쓰기'하면 픽셀이 켜집니다. 실제로 글자를 쓰려면 많은 픽셀을 비춰 야합니다. 일반적으로 컴퓨터에는 운영 체제에 정의 된 문자 세트 (실제로 몇 개)가 있습니다. ( '글꼴'자체를 추상화하여 화면에서 각 문자의 모양에 대한 정의로 매핑 됨)

따라서 코드가 컴파일 될 때 이러한 글꼴 / 문자 세트 등을 포함하여 OS 라이브러리에서 제공되는 모든 종류의 것들이 포함되어 CPU가 그래픽 메모리의 어디에 쓸지를 알 수 있습니다. (매우 복잡하지만 일반적인 아이디어입니다. 컴파일러는 가져온 라이브러리를 통해 'hello world'코드에만있는 것보다 훨씬 많은 코드를 포함합니다)

결국, 당신이 의심하는 것처럼 많은 일들이 일어나고 있었지만 모든 코드를 작성할 필요는 없었습니다.


1

이론적 컴퓨터 과학 분야의 질문에 대한 공식적인 접근 방식은 다음과 같습니다.

기본적으로 CPU의 계산 모델과 튜링 머신 간의 매핑을 정의 할 수 있습니다. 상상할 수있는 모든 튜링 머신 프로그램 세트 (따라서 CPU에서 실행 가능한 모든 상상할 수있는 프로그램)가 무한히 셀 수 있다는 이론적 증거가 있습니다. 이는 자연수를 튜링 기계까지 확장하는 프로그램을 포함하여 고유 한 자연수로 모든 프로그램을 식별 할 수 있음을 의미합니다 .

이미 알고있는 것처럼 거의 모든 CPU가 이진 표현으로 자연수를 계산하는 것이므로 CPU가 상상할 수있는 모든 프로그램을 수행 할 수 있다고 추론 할 수 있습니다.

참고 : 이것은 지나치게 단순화되었지만 제 생각에는 좋은 직감이 있습니다.


1

도움이 될 수있는 것은 당신의 생각을 "산술하기"에서 멀어지게하는 것입니다. 실제로 컴퓨터가 무엇을하고 있는지를 파고 들려고한다면 "Hello World"를 인쇄하여 한 단계 낮게 생각하는 것이 가장 좋습니다. 컴퓨터의 "상태"는 켜거나 꺼진 트랜지스터 스위치 (또는 충전되거나 충전되지 않은 커패시터)에 의해 저장된 일련의 비트로 설명 될 수 있습니다. 컴퓨터는 규칙에 따라 해당 비트를 조작합니다. 컴퓨터가 비트를 조작하도록 허용 된 방식은 0에서 1 또는 1에서 0으로 비트를 변경하는 작업을 수행하는 트랜지스터 형태로 CPU에 기록됩니다.

ALU가 "산술을 수행"할 때 실제로 의미하는 것은 컴퓨터의 상태를 산술 규칙과 일치하는 방식으로 변경 한 것입니다. 그것은 약간의 비트를 변경하는 것입니다. 왜 우리가 그것을 덧셈 또는 뺄셈으로 생각해야하는지 설명하는 것은 소프트웨어 의 의미 입니다. CPU는 무엇을하고 있는지 "알지"않습니다. 그것은 단지 상태에서 상태로 변경되며, 그 이상입니다 (적어도 Skynet이 인수 할 때까지).

그렇게 생각하면 "점프"명령과 같은 더 복잡한 명령도 다르지 않습니다. 그것은 약간의 비트를 변경하는 것입니다. 이 경우 다음에 실행할 명령의 위치를 의미 하는 비트를 변경합니다 . CPU는 이것을 "알지"않지만 우리는 알고 있습니다. 따라서 코드에서 비트를 "점프"로 변경하는 명령을 사용합니다.

IO도 실제로 다르지 않습니다. 비트 만 변경됩니다. 유일한 작은 차이는 그 비트가 결국 화면에 문자를 조명으로 이어질 트랜지스터에 연결되어 있다는 점이다. "Hello World"가 실제로 단순했던 때로 수십 년을 거슬러 올라가면 "Hello World"에 대한 ASCII 문자에 해당하는 비트를 쓴 경우 해당 문자가 화면. 요즘에는 그래픽 카드와 운영 체제가 복잡하기 때문에 조금 더 복잡하지만 기본 아이디어는 동일합니다. 화면에 픽셀을 표시하기 위해 회로에 연결된 트랜지스터 세트가 켜져 있거나 꺼져 있습니다. 올바른 것을 설정하면 화면에 "Hello World"가 나타납니다.

혼란은 단순히 구문 대 의미론의 문제입니다. ALU에서 "반 추가"또는 "전체 추가"의 동작은 구문입니다. 비트를 넣을 때 나오는 비트를 정의합니다. 의미는 덧셈을 수행하는 능력의 개념입니다. 귀하와 저는 ALU가 "추가를 할 수 있음"을 알고 있지만, 아래에서 일어나는 일을 실제로 이해하려면 ALU가 구문의 비트와 바이트 만 조작한다는 것을 기억해야합니다.


0

CPU는 다음과 같이 작동합니다.

  • 현재 명령을 가져오고 "현재 명령"포인터를 증가시킵니다.

  • 그것을 해독하십시오 (예를 들어 CPU에게 지시하는이 명령이 무엇인지 알아 내십시오)

  • 명령을 실행하십시오 (명령의 기능 수행)-명령이 "점프"와 같은 경우 현재 명령 포인터가 수정 될 수 있습니다.

  • 영원히 반복

최신 CPU는 더 복잡하고 그 프로세스의 일부를 예측하기도합니다 (예 : CPU가 "파이프 라인"을 가득 채우기 위해 "현재 명령"포인터보다 훨씬 앞서서 가져 오는 동안 10 개의 다른 명령이 디코딩되는 동안 실행 시작). 필수 과정은 실제로 동일합니다.

많은 유형의 지침이 있으며 그 중 대부분의 예는 다음과 같습니다.

  • "이동"지침. CPU가 이러한 개념을 지원하는 경우 X를 다른 X로 복사 할 수 있습니다. 여기서 X는 메모리 (RAM), 레지스터 또는 I / O 공간의 주소입니다.

  • 레지스터에 팝, 스택에 푸시 레지스터 등을 포함한 스택 조작 명령어. "스택 포인터"레지스터를 사용하고 업데이트하는 "이동"명령어의 특수한 경우입니다.

  • 두 레지스터 또는 메모리와 레지스터 사이에서 수학 연산을 수행하는 명령어. 이 명령어는 플래그 레지스터에 자동으로 영향을줍니다. 이러한 플래그 중 하나는 결과가 0 인 경우 설정되는 "zero"플래그이고, 다른 하나는 결과의 최상위 비트가 설정된 경우 설정되는 "음수"플래그입니다. CPU에 따라 다른 것이있을 수 있습니다.

  • 수학 연산의 특수한 경우는 비교 명령으로 뺄셈과 동일하지만 결과는 유지되지 않습니다. 플래그는 여전히 영향을받습니다.

  • 특정 플래그가 설정된 경우 메모리 주소로 이동하는 분기 명령어가 있습니다. 위에서 언급 한 "zero"플래그를 기억하십니까? 또한 "동일한 경우"플래그로 두 배가되므로 BEQ"0"플래그가 설정된 경우 실제로 분기되는 많은 CPU에서 와 같은 명령어 가 표시됩니다.

  • 논리 연산 (AND, OR, NOT), 시프트 비트 및 테스트 비트를 수행하는 명령어. CPU에 따라 수학 명령과 같은 플래그에 영향을 줄 수 있습니다.

  • 무조건 점프하는 명령.

  • 스택에 리턴 주소를 점프하여 저장하는 명령어 ( "호출") 및 스택에서 주소를 튀어 나오는 기타 명령어 ( "반환").

  • CPU를 정지 시키거나 CPU를 식별하거나 인터럽트 핸들러를 호출하는 것과 같은 특수 명령.

  • "No Operation"-거의 모든 CPU에 사이클을 소비하고 계속 진행하는 "no-op"명령이 있습니다.

이것은 실제로 예일 뿐이며, 명령 유형이 적은 CPU와 더 많은 CPU가 있습니다.

요점은 CPU에서 수학 명령어 외에 많은 유형의 명령어가 있음을 설명하는 것입니다. 고급 언어로 된 모든 것은 위의 작업 유형으로 분류되며 그 중 일부만 수학 또는 ALU 유형 명령어입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.