첫 번째 어셈블러는 기계어 코드로 작성 되었습니까?


41

부울 게이트에서 고급 응용 프로그램에 이르기까지 컴퓨터의 빌드를 포함하는 프로젝트가 포함 된 프로젝트가 포함 된 첫 번째 원칙에서 현대 컴퓨터 구축 :의 요소를 읽고 있습니다 (순서대로). 현재 작업중 인 프로젝트는 Hack 어셈블리 코드에서 Hack machine code로 변환하기 위해 선택한 고급 언어를 사용하여 어셈블러를 작성하는 것입니다 (Hack은 이전 장에서 빌드 된 하드웨어 플랫폼의 이름입니다). 하드웨어가 모두 시뮬레이터에 내장되어 있지만 실제 프로세스에서 해당 시점에 사용 가능한 도구 만 사용하여 각 레벨을 실제로 구성하고 있다고 가정했습니다.

즉, 그것은 나를 생각하게했다. 고급 언어를 사용하여 어셈블러를 작성하는 것이 확실히 편리하지만 역사상 처음으로 작성된 어셈블러의 경우 그 당시 존재했던 모든 것이 기계 코드로 작성 될 필요는 없습니까?

그리고 관련된 질문은 ... 오늘은 어떻습니까? 새로운 명령어 세트와 새로운 어셈블리 구문으로 완전히 새로운 CPU 아키텍처가 나오면 어셈블러는 어떻게 구성됩니까? 새 플랫폼의 어셈블리 언어와 기계 언어의 구문을 알고 있다면 어셈블러 작성 작업은 실제로는 단지 고급이므로 기존 고급 언어를 사용하여 어셈블러 프로그램의 이진 파일을 생성 할 수 있다고 가정합니다. 텍스트 분석 작업이며 해당 플랫폼과 본질적으로 관련이 없습니다 (즉, 해당 플랫폼의 기계 언어로 작성해야 함). 2012 년에 Hack 어셈블러를 작성하는 동안 "속임수"를 사용하고 기존의 일부를 사용하는 이유 나를 돕는 고급 언어.


17
항상 크로스 컴파일러를 작성하고이를 사용하여 요즘 새 하드웨어에 대한 코드를 생성 할 수 있습니다.
Kerrek SB

@PersonalNexus 감사합니다. snafu는 내 부분을 편집합니다.
yannis

1
@YannisRizos 문제 없습니다, 우리 중 최고에 일이 :)
PersonalNexus

8
첫 번째 어셈블러가 종이에 어셈블리로 작성되었을 수 있습니다. 그런 다음 종이에서 기계 코드로의 변환이 여전히 수행되어 스위치를 사용하여 한 번에 한 단어 씩 ROM에 기록 될 수 있습니다.
mouviciel

내 첫 번째 컴퓨터는 1KB RAM을 가진 ZX81이었으며, 기계 코드 프로그램은 실제로 직접 번역되었습니다.
user281377

답변:


36

역사상 가장 처음으로 작성된 어셈블러의 경우 머신 코드로 작성할 필요가 없습니다.

반드시 그런 것은 아닙니다. 물론 어셈블러의 첫 번째 버전 v0.00은 머신 코드로 작성 되었어야하지만 어셈블러라고 부르기에 충분히 강력하지는 않습니다. "실제"어셈블러의 절반 기능 만 지원하지는 않지만 다음 버전 자체를 작성하는 것으로 충분합니다. 그런 다음 어셈블리 언어의 하위 세트로 v0.00을 다시 쓰고 v0.01이라고 부르고이를 사용하여 어셈블러 v0.02의 다음 기능 세트를 빌드 한 다음 v0.02를 사용하여 v0.03을 빌드하고 v1.00에 도달 할 때까지 계속합니다. 결과적으로 첫 번째 버전 만 기계 코드에있게됩니다. 첫 번째로 출시 된 버전은 어셈블리 언어입니다.

이 트릭을 사용하여 템플릿 언어 컴파일러를 개발했습니다. 내 초기 버전은 printf명령문 을 사용 했지만 회사에서 사용하기 위해 사용한 첫 번째 버전은 처리중인 템플릿 프로세서를 사용하고있었습니다. 부트 스트랩 단계는 4 시간도 채 걸리지 않았습니다. 프로세서가 거의 유용한 출력을 생성 할 수있게 되 자마자 나는 자체 언어로 다시 작성하고 컴파일하여 템플릿이 아닌 버전을 버렸습니다.


4
당신은 여전히 ​​모든 단계를 가지고 있습니까? 나는 그것들을보고 서로 비교하고 싶습니다. 당신이 겪은 과정에 대한 느낌을 얻으려면.
Marjan Venema 2012 년

3
@MarjanVenema 아니요, 더 이상은 없습니다. 1998 년에 지어졌고 StringTemplate을 발견 한 2005 년까지 계속 사용했습니다 . 초기 사용 가능한 버전으로 작업하면서 이전 단계를 다음 단계로 덮어 쓰고있었습니다. 내 개발주기는 새로운 내용을 코딩하고, 코드 생성기를 실행하여 별도의 디렉토리에 자체 빌드하고 diff, 현재 코드 생성기에 대해 실행 하여 생성 된 코드 부분이 예기치 않은 방식으로 변경되지 않았으며, 코드를 교체하고, 사이클을 완료하기 위해 한 번 더 실행하십시오.
dasblinkenlight

안타깝지만 이해할 만하다 :) 당신이 한 일을 설명해 주셔서 감사합니다 (링크).
Marjan Venema

3
부트 스트랩 체인을 유지해야한다고 생각합니다. 기계 코드 => 제한된 ASM => 전체 ASM => 일부 언어. 그렇지 않으면 바이너리를 잃어 버릴 경우 조여지는 길을 따라야합니다. (실제로 모든 C 컴파일러 바이너리가 한 번에 사라지는 것은 아니기 때문에 C 크로스 컴파일 버전을 사용할 수도 있습니다.)
edA-qa mort-ora-y

3
어셈블러가 "실제"어셈블러 여야하는 유일한 "기능"은 조립하는 것입니다.
Miles Rout

23

Wikipedia에 따르면, 최초의 어셈블러 / 어셈블리 언어는 Nathaniel Rochester에 의해 IBM 701에 대해 구현되었습니다 . (날짜는 그것은 로체스터는 1948 년 IBM에 합류한다고. 위키 피 디아 기사에서 조금 불확실하지만, 701 공개적으로 1952 년 발표 된 또 다른 위키 백과 페이지 상태 이 IBM 페이지 것을 상태 "[A] ctual 디자인은 2 월 시작 1, 1951 년 1 년 후 완료되었습니다 . "

그러나 David Salomon의 "어셈블러 및 로더" (7 페이지)는 EDSAC에도 어셈블러가 있다고 설명합니다.

"최초의 저장 프로그램 컴퓨터 중 하나는 1949 년 케임브리지 대학교에서 Maurice Wilkes와 W. Renwick에 의해 개발 된 EDSAC (Electronic Delay Storage Automatic Calculator)였습니다. 처음부터 EDSAC는 Initial Orders라는 초기 어셈블러를 사용했습니다. 로터리 전화기 셀렉터 세트로 구성된 읽기 전용 메모리에 있고 기호 명령을 받아들였으며, 각 명령은 하나의 문자 니모닉, 십진 주소 및 문자 인 세 번째 필드로 구성되었습니다. "조립시 주소에 추가되도록 프로그래머가 사전 설정 한 상수." (참조 생략 ... 원본을 참조하십시오.)

"초기 주문"이 우선한다고 가정하면 첫 번째 어셈블러 기계 코드 구현 되었다는 확실한 증거가 있습니다.

이 패턴 (머신 코드에 초기 어셈블러 작성)은 1950 년대의 표준이었습니다. 그러나 Wikipedia 에 따르면 "[a] 어셈블러는 부트 스트랩을 수행하는 최초의 언어 도구"라고한다. 또한 어셈블리 언어로 코딩 된 고급 어셈블러를 부트 스트랩하기 위해 원시 어셈블러로 작성된 머신 코드를 사용하는 방법을 설명하는 이 섹션 도 참조하십시오 .

요즘 어셈블러 및 컴파일러는 고급 언어로 작성되며 새로운 기계 아키텍처를위한 어셈블러 또는 컴파일러는 일반적으로 다른 아키텍처에서 개발되고 크로스 컴파일됩니다.

(FWIW-기계 코드에서 사소한 프로그램을 작성하고 디버깅하는 것은 매우 힘든 과정입니다. 기계 코드로 어셈블러를 개발하는 사람은 가능한 빨리 어셈블러로 작성된 어셈블러로 부트 스트랩 할 가능성이 높습니다.)

부트 스트랩 컴파일러 및 어셈블러 에 대한이 Wikipedia 페이지 는 읽을 가치가 있습니다.


추측 만하는 것이 아니라 실제로 대답하는 것에 찬성했습니다. 정말 재미있는 독서입니다!
JacquesB

14

첫 번째 어셈블러는 머신 코드로 작성되었다고 가정합니다.

그러나 오늘날 새로운 CPU 아키텍처가 나오면 크로스 컴파일러 (Cross-Compiler )를 사용합니다.이 컴파일러는 실행중인 아키텍처가 아니라 다른 아키텍처에 대한 머신 코드를 생성하는 컴파일러입니다.

(사실, 당신이 읽고있는 책에서 나중에 알게 될 것이 확실하기 때문에 컴파일러가 본질적으로 실행중인 아키텍처의 기계 코드를 생성하는 데 더 적합하게 만드는 것은 아무것도 없습니다. 컴파일러의 제작자로서 어떤 아키텍처를 목표로 삼을 것인지는 문제가됩니다.)

따라서 오늘날 (최소한 이론 상으로는) 완전히 새로운 아키텍처를 만들고 해당 아키텍처에 대한 어셈블러를 사용하기 전에 기본적으로 고급 언어 컴파일러가 실행되고 (크로스 컴파일러를 사용하여 다른 아키텍처에서 컴파일) 가능합니다.


12

처음에는 "조립"이 종이에 쓰여진 다음 펀치 카드에 수동으로 "컴파일"되었습니다.

제 할아버지는 ZRA1을 사용하고 계셨습니다 (죄송합니다. 페이지는 독일어로만 존재하지만 Google 번역은 실제로 가장 중요한 사실을 알 수있는 시점까지 괜찮습니다 : D).
modus operandi는 일종의 어셈블리 언어로 종이에 코드를 작성하는 것이었고, 비서는 실제로 카드를 펀칭하기 위해 전사를 한 다음 운영자에게 전달하면 결과는 다음날 아침에 전달됩니다.

이 모든 것은 본질적으로 프로그래머가 키보드를 통해 데이터를 입력하고 화면에서 볼 수있는 고급 스러움을 갖기 전이었습니다.


3
대학에서 공부할 때 여전히 기계 코드 작성에 사용되는 종이 블록이있었습니다. 오른쪽에 프로그램을 작성하고 왼쪽에 명령어를 16 진수로 변환하는 열이 있습니다. 현재 주소에 대한 열입니다. 첫 번째 어셈블러는 실제로 인간이었습니다.
Florian F

9

그것은 대해 확신하기 어렵다 매우 (심지어였습니다을 정의하는 하드) 첫번째 어셈블러. 몇 년 전, 어셈블러가없는 기계를 위해 몇 개의 어셈블러를 작성할 때도 여전히 어셈블리 언어로 코드를 작성했습니다. 그런 다음 코드 섹션을 합리적으로 완성한 후 수동으로 기계 코드로 변환했습니다. 그래도 여전히 두 단계로 완전히 분리되었습니다. 코드를 작성할 때 기계 코드 수준에서 전혀 작업하거나 생각하지 않았습니다.

나는 몇 가지 경우에 한 단계 더 나아가 야한다고 덧붙였다. 사용하기가 더 쉬운 것으로 밝혀진 어셈블리 언어로 대부분의 코드를 작성한 다음 작은 커널을 작성했다. 대상 프로세서에서이를 해석합니다. 그 속도는 매우 느리지 만 (특히 1MHz, 8 비트 프로세서에서), 보통 한 번만 (또는 최대 몇 번) 실행 되었기 때문에 별 문제가되지 않았습니다.


8

어셈블리 언어 코드를 기계 코드로 직접 어셈블하기 위해 어셈블러가 필요하지 않습니다. 어셈블리 언어 코드를 작성하기 위해 편집기가 필요하지 않은 것처럼.

역사적 관점

첫 번째 어셈블러는 아마도 어셈블리 언어로 작성된 다음 기계 코드로 수작업으로 어셈블되었습니다. 프로세서에 공식 '어셈블리 언어'가 없더라도 프로그래머는 아마도 그 코드를 기계 명령어로 변환하기 전에 일종의 의사 코드를 사용하여 프로그래밍 작업을 수행했을 것입니다.

초창기의 컴퓨팅 조차도 프로그래머는 일종의 상징적 표기법으로 프로그램을 작성 하여 컴퓨터에 공급하기 전에 기계 코드 로 번역했습니다 . Augusta Ada King의 경우, 그녀는 그것들 을 BabbageAnalytical Engine을 위한 펀치 카드 로 번역해야 했지만 아쉽게도 만들어지지 않았습니다.

개인적인 경험

내가 소유 한 첫 번째 컴퓨터는 Sinclair ZX81 (미국의 Timex 1000)입니다. 매뉴얼 뒷면에는 Z80 어셈블리 언어를 기계어 코드로 변환하는 데 필요한 모든 정보가 있습니다 ( Z80이 가진 모든 이상한 인덱스 모드 opcode를 포함 하더라도).

어셈블리 언어로 프로그램 (종이에)을 작성하고 코드를 통해 드라이 런합니다. 프로그램에 버그가없는 것이 마음에 들었을 때 설명서 뒷면의 각 명령을 찾아서 기계 코드로 번역하고 종이에 기계 코드를 기록했습니다. 마지막으로 테이프에 저장하고 실행하기 전에 모든 머신 코드 명령어를 ZX81에 입력합니다.

작동하지 않으면 핸드 어셈블리를 다시 확인하고 변환이 잘못되면 테이프를 다시 저장하고 프로그램을 다시 실행하기 전에 테이프에서로드 된 바이트를 패치합니다.

경험상 기계 코드보다 어셈블리 언어로 작성된 코드를 디버깅하는 것이 훨씬 쉽다는 것을 알 수 있습니다. 따라서 디스어셈블러의 인기가 있습니다. 어셈블러가없는 경우에도 Mel 과 같은 Real Programmer 가 동의하지 않을 수도 있지만 수동 어셈블 링은 기계 코드를 직접 작성하는 것보다 오류가 덜 발생 합니다. * 8 ')


5

그때나 지금은 차이가 없습니다. 새로운 프로그래밍 언어를 발명하고자한다면, 오늘날 사용할 수있는 언어 중 하나를 선택하여 첫 번째 컴파일러를 만드십시오. 일정 기간 동안 프로젝트의 목표라면 해당 언어로 컴파일러를 작성한 다음 자체 호스트 할 수 있습니다.

첫 번째 또는 다음 새 명령 세트에 대한 사용자 인터페이스로 연필과 종이, 일부 스위치 또는 펀치 카드 만 있으면 사용할 수있는 항목 중 하나 또는 전부를 사용했습니다. 종이에 어셈블리 언어를 작성한 다음 어셈블러를 사용하여 기계 코드로 변환하거나 8 진수로 변환 한 다음 어떤 시점에서 인터페이스를 기계로 변환 할 수 있습니다.

오늘날 새로운 명령어 세트가 발명 될 때 회사 / 개인, 실습 등에 따라 다르지 않을 것입니다. 아마도 하드웨어 엔지니어가 아마도 verilog 또는 vhdl로 프로그래밍하는 것은 아마도 처음 몇 가지 테스트 프로그램을 기계 코드로 작성합니다 (아마도 16 진 또는 2 진). 소프트웨어 팀의 진행 상황에 따라 어셈블리 언어로 전환 한 다음 컴파일러로 전환하는 데 시간이 오래 걸리거나 매우 빠를 수 있습니다.

최초의 컴퓨팅 머신은 어셈블러 및 컴파일러를 작성하는 데 사용할 수있는 범용 머신이 아닙니다. 이전 alu의 출력에서 ​​다음 alu의 입력으로 일부 와이어를 이동하여 프로그래밍했습니다. 결국에는 범용 프로세서를 사용하여 어셈블리에 어셈블러를 작성하고 수동으로 어셈블하고 기계 코드로 피드 한 다음이를 사용하여 ebcdic, ascii 등을 구문 분석하고 자체 호스트 할 수 있습니다. 바이너리를 일부 매체에 저장하면 나중에 수동으로 기계 피드 코드를 전환하기 위해 스위치를 계속 켤 필요가없는 읽기 /로드가 가능합니다.

펀치 카드와 종이 테이프를 생각하십시오. 스위치를 뒤집는 대신 컴퓨터가 읽을 수있는 미디어를 만든 완전히 기계적인 기계 (노동 절약 장치)를 만들 수 있습니다. altair와 같은 스위치를 사용하여 기계 코드 비트를 입력하는 대신 종이 테이프 또는 펀치 카드를 공급할 수 있습니다 (프로세서가 아닌 기계식 또는 메모리 또는 프로세서에 공급 된 작은 기계 코드 또는 부트 로더로 작성된 작은 기계 코드 사용). 종이 테이프 나 펀치 카드를 기계적으로 생산할 수있는 컴퓨터로 무언가를 만들어 다시 넣을 수 있기 때문에 이것은 나쁜 생각이 아닙니다. 비 컴퓨터 기반 기계 노동 절약 장치 인 펀치 카드의 두 가지 소스 및 컴퓨터 구동 기계. 둘 다 컴퓨터의 "이진"을 생성합니다.


1
"어셈블러 사용자"의견에 +1 단어의 하나의 정의 (예 : 어셈블러 = 소프트웨어)에 쉽게 첨부 할 수 있지만 여러분의 의견은 실제로 분명한 관점으로 되돌아갑니다. 인간 어셈블러.
The111

1
또한 사람들은 초기 컴퓨터에 명령 세트가 있다는이 개념을 계속 고수합니다. 초기 컴퓨터는 연필과 종이를 사용하여 수학 능력이 뛰어난 여성이었습니다. 그것이 바로 컴퓨터입니다. 그런 여성들 (또는 특히 여성들)은 명령 세트를 사용하지 않는 전선을 연결하여 eniac을 프로그래밍했습니다. 명령 세트를 사용한 프로그래밍은 잘 진행되었습니다. 그렇습니다. 어셈블러 나 컴퓨터와 같은 단어 나 용어를 사용하는 데 매우 빠릅니다.
old_timer

4

Brook의 컴퓨터 동물원 에는 "니모닉은 우리의 발명품입니다. 디자이너는 단순히 숫자 opcode 또는 코드가 opcode 인 문자를 사용했습니다"라는 말이 있습니다. 어셈블리어.

프로그램을 입력하면 전면 패널에서 디버깅이 종료됩니다 (메모리를 설정하지 않은 경우 메모리를 설정하는 방법, 일부 스위치를 주소로 설정하고 다른 스위치를 값으로 설정하고 다른 버튼을 누름) 값을 읽으십시오)는 훨씬 흔했습니다. 일부 오래된 타이머는 여전히 광범위하게 사용하는 시스템의 부팅 코드를 입력 할 수 있다고 자랑합니다.

기계 코드를 직접 작성하고 메모리 덤프에서 프로그램을 읽는 데 어려움은 기계 언어에 따라 매우 다르며, 일부는 비교적 쉽습니다 (가장 어려운 부분은 주소를 추적하고 있음), x86은 더 나쁜 것 중 하나입니다.


pdp-11에는 손잡이가 없었습니다. 8 개의 토글 스위치에 이진 주소를 입력하고 16 개의 토글 스위치에있는 값을 입력 한 다음 버튼을 눌러 스토리지를 변경할 수 있습니다. 나는 실제로 누군가가 이런 식으로 루핑 프로그램을 수정하는 것을 보았습니다!
James Anderson

2

나는 1975 년에 컴퓨터를 만들었습니다. 그것은 현대의 알테어에 비해 매우 발전했습니다. '모니터 롬'은 기계 코드를 16 진수로 입력하고이 코드를 비디오 모니터에서 볼 수 있습니다. Altair의 각 기계 명령어는 스위치를 사용하여 한 번에 조금씩 입력해야했습니다.

그렇습니다. 컴퓨터의 초기와 개인용 컴퓨터의 초기에 사람들은 머신 코드로 응용 프로그램을 작성했습니다.


2

일화 :

애플에서 어셈블리 언어를 배웠을 때] [, ROM에는 마이크로 어셈블러라는 프로그램이 포함되어있었습니다. 입력 한대로 어셈블리 명령어를 바이트로 즉시 변환했습니다. 이는 레이블이 없음을 의미합니다. 점프하거나로드하려면 오프셋을 직접 계산해야합니다. 명령어 레이아웃을 찾아 16 진수 값을 입력하는 것보다 훨씬 쉽습니다.

의심 할 여지없이, 실제 어셈블러는 마이크로 어셈블러를 사용하거나 처음에는 완전히 완성되지 않은 환경을 사용하여 작성되었습니다.

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