왜 어셈블리 언어가 필요한가?


27

우리는 주로 고급 언어로 프로그램을 작성합니다. 그래서 공부하는 동안 나는 어셈블리 언어를 만났습니다. 따라서 어셈블러는 어셈블리 언어를 기계 언어로 변환하고 컴파일러는 고급 언어와 동일한 작업을 수행합니다. 어셈블리 언어에 r1 r3 이동, 5 이동 등의 지침이 있다는 것을 알았습니다. 공부하기가 다소 어렵습니다. 그렇다면 어셈블리 언어는 왜 만들어 졌습니까? 아니면 고급 언어보다 먼저 나왔습니까? 컴퓨터 공학 수업에서 어셈블러에 대해 공부하는 이유는 무엇입니까?


13
어셈블러는 사람이 읽을 수있는 기계어 코드입니다.
Andrej Bauer

4
하드웨어에 가까이있을 때 어떻게 작동하는지 아는 것이 중요하기 때문입니다. 어셈블리를 작성할 때 컴퓨터 하드웨어가 저수준에서 작동하고 작동하는 방식을 이해합니다. 기계 언어는 지루하고 어셈블리와 같이 읽을 수 없으므로 어셈블리 언어가 가장 좋습니다. 마법 상자를 사용하고 내부를 절대 보지 않겠습니까?
스펜서 Wieczorek

답변:


32

"왜 어셈블리 언어가 만들어 졌습니까?"

어셈블리 언어는 머신 레벨 코딩을위한 축약 형으로 작성되었으므로 하루 종일 0과 1을 계산할 필요가 없습니다. 명령어 및 피연산자를 사용하여 기계 수준 코드와 동일하게 작동합니다.

"어느 쪽이 먼저 왔습니까?"

위키 백과에는 프로그래밍 언어역사에 대한 좋은 기사가 있습니다.

"컴퓨터 공학 수업에서 어셈블러에 대해 공부하는 이유는 무엇입니까?"

사실이지만, 다음 고객의 앱을 어셈블리로 작성하지는 않을 것입니다. 그러나 어셈블리 학습을 통해 얻을 수있는 이점은 여전히 ​​많습니다.

오늘날 어셈블리 언어는 주로 하드웨어 직접 조작, 특수 프로세서 명령어에 대한 액세스 또는 중요한 성능 문제를 해결하는 데 사용됩니다. 일반적인 용도는 장치 드라이버, 저수준 임베디드 시스템 및 실시간 시스템입니다.

어셈블리 언어는 프로그래머가 얻을 수있는만큼 프로세서와 비슷하므로 잘 설계된 알고리즘이 타 오르고 있습니다. 어셈블리는 속도 최적화에 좋습니다. 모든 것이 성능과 효율성에 관한 것입니다. 어셈블리 언어를 사용하면 시스템 리소스를 완벽하게 제어 할 수 있습니다. 어셈블리 라인과 마찬가지로 단일 값을 레지스터로 푸시하고 메모리 주소를 직접 처리하여 값이나 포인터를 검색하는 코드를 작성합니다. (출처 : codeproject.com )


29

왜 어셈블리 언어가 필요한가?

실제로 우리에게 필요한 언어는 "기계 언어"또는 "기계 코드"라고합니다. 다음과 같이 보입니다 :

0010000100100011

이것은 컴퓨터에서 직접 말할 수있는 유일한 언어입니다. CPU가 말하는 언어입니다 (기술적으로는 다른 유형의 CPU가 다른 버전을 말합니다). 또한보고 이해하려고 노력합니다.

다행히 이진의 각 섹션은 특정 의미에 해당합니다. 여러 섹션으로 나뉩니다.

0010|0001|0010|0011

operation type  source register  other source  destination register
0010            0001             0010          0011

이 값은 다음에 해당합니다.

operation type 0010 = addition
source register 0001 = register 1
other source 0010 = register 2
destination register 0011 = register 3

따라서이 작업은 레지스터 1과 2에 숫자를 추가하고 해당 값을 레지스터 3에 넣습니다. 문자 그대로이 값을 CPU에 넣고 "go"라고하면 두 개의 숫자가 추가됩니다. "빼기"연산은 여기서 0010 대신 0011 또는 다른 것일 수 있습니다. 어떤 값을 사용하든 CPU는 빼기를 수행합니다.

따라서 프로그램은 다음과 같이 보일 수 있습니다 (설명하기 위해이 특정 버전의 기계 코드를 구성했기 때문에 이해하지 마십시오).

instruction 1: 0010000100100011
instruction 2: 0011000110100100
instruction 3: 0101001100010111
instruction 4: 0010001001100000

이거 읽다 보니? 명확히. 그러나 우리는 CPU에 필요합니다 . 모든 머신 코드가 특정 액션에 해당하는 경우, 간단한 "영어"속기를 만들고 프로그램이 수행하는 작업을 이해하면 실제 바이너리 머신 코드로 변환하여 CPU에 실행합니다.

위의 원래 명령은 다음과 같습니다.

(meaning)      operation type  source register  other source  destination register
(machine code) 0010            0001             0010          0011
("English")    add             r1               r2            r3

이 영어 버전은 기계어 코드와 정확히 일치합니다 . 따라서이 "영어"줄을 작성할 때, 우리는 실제로 더 친숙하고 이해하기 쉬운 기계 코드를 작성합니다.

글쎄, 이것은 어셈블리 언어입니다. 이것이 존재하는 이유와 원래 만들어진 이유입니다.

왜 우리가 지금 필요한지 이해하려면 위의 답변을 읽으십시오. 그러나 이것이 이해해야 할 핵심은 이것입니다. 고급 언어에는 단일 표현이 없으며 기계 코드입니다. 예를 들어 C, Python 또는 기타

z = x + y

이것은 x레지스터 1에 y있고 레지스터 2에 있고 레지스터 3에 있다고 가정하면 위에서 추가 한 것처럼 들립니다. z그러나이 줄은 어떻습니까?

z = x * 2 + (y / 6) * p + q - r

라인을 16 비트 바이너리로 표현 하고 CPU에 "go"라고 말하십시오. 당신은 할 수 없습니다. 기계 코드에는 더하기, 빼기 및 한 번에 4 개 또는 5 개의 변수가있는 다른 것을 수행하기위한 단일 작업 명령이 없습니다. 따라서 먼저 일련 의 기계 코드 로 변환해야합니다 . 고급 언어를 "컴파일"또는 "해석"할 때 수행하는 작업입니다.

글쎄, 우리는 그렇게 할 프로그램이 있는데, 왜 지금 집회가 필요한가? 프로그램이 예상보다 느리게 실행되고 있으며 그 이유를 알고 싶다고 말하십시오. 이 행의 기계 언어 "출력"을 보면 다음과 같이 보일 수 있습니다.

1010010010001001
0010001000010000
0110010000100100
0010001011000010
0010100001000001
0100010100000001
0010010101000100
0010101010100000
0000100111000010

한 줄의 파이썬을 끝내기 위해. 그래서 당신은 정말로 그것을 디버깅하고 싶습니까?!?!?! 아니요 . 오히려 컴파일러는 실제로 쉽게 이해할 수있는 형식 으로 해당 기계 코드에 정확히 해당하는 어셈블리 언어 버전 인 출력을 친절하게 제공하도록 요청합니다 . 그런 다음 컴파일러가 멍청한 짓인지 알아 내고 고칠 수 있습니다.

(@Raphael의 조언에 대한 추가 참고 사항 : 실제로 3 진 (기본 3) 또는 10 진수 코드 또는 ASCII와 같은 이진 코드 이외의 작업을 수행하는 CPU를 실제로 구성 할 수 있습니다. 실제로는 실제로 이진을 고수했습니다.)


2
원칙적으로 어셈블리 언어와 직접 작동하는 CPU를 구축하는 데 방해가되는 것은 없습니다. ASCII는이 목적을위한 비효율적 인 인코딩 일뿐입니다.
Raphael

추가해 주셔서 감사합니다. 나는 동의하지만, 의회의 목적을 이해하기 위해 그것을 생략했다. 메모를 추가하겠습니다.
Chris Cooper

15

그렇다면 왜 어셈블리 언어가 만들어 졌습니까? 아니면 고급 언어 이전에도 처음 등장한 것일까 요?

그렇습니다. 어셈블리는 납땜 와이어, 플러그 보드 및 플립 스위치를 사용하는 대신 텍스트를 입력으로 사용한 최초의 프로그래밍 언어 중 하나였습니다. 각 어셈블리 언어는 하나의 프로세서 또는 프로세서 제품군에 대해 만들어졌으며 명령어 는 프로세서가 실행하는 opcode 에 직접 매핑 되었습니다.

컴퓨터 공학 수업에서 어셈블러에 대해 공부하는 이유는 무엇입니까?

장치 드라이버를 프로그래밍하거나 컴파일러를 작성해야하는 경우에는 프로세서 작동 방식을 이해하는 것이 중요하지 않습니다 (필요하지 않은 경우). 이것을 이해하는 가장 좋은 방법은 어셈블리에 코드를 작성하는 것입니다.

컴파일러가 코드를 작성하는 방법을 살펴보면 어셈블리를 알지 못하면 이해할 수없는 규칙호출하는 옵션을 보는 것이 일반적 입니다.

버그를 해결해야하고 유일하게 입력 한 내용이 코어 덤프 인 경우 , 어셈블리 코드 인 출력을 이해하고 운이 좋으면 고급 언어의 상위 레벨 명령문으로 기능 보강 된 어셈블리를 알아야합니다.


14

실용적인 측면을 하나 더 추가하겠습니다. 이것은 아마도 역사적인 이유가 아니라 오늘의 이유입니다.

어셈블리 (고급 언어와 비교)는 알몸 입니다. 소프트웨어에서 수행되는 것은 숨기지 않으며 비교적 작고 고정 된 조작 세트가 있다는 점에서 단순합니다.

이는 정확한 알고리즘 분석에 도움이 될 수 있습니다. 시맨틱 및 제어 흐름은 너무 간단하여 전이 카운트 (확률)로 제어 흐름 그래프에 주석을 달아 모든 작업 (또는 예상 수)을 계산할 수 있습니다. Knuth는 TAoCP 서적에서이를 수행하여 가장 엄격한 알고리즘 분석을 보여줍니다.

일화 : 동료가이 목적을 위해 Java Bytecode를 읽는 법을 배웠습니다.


4

여기에 답변이 있습니다 :

이 모든 대답은 다음을 가리 킵니다.

  • 속도 / 메모리 최적화
  • 기계 작동 방식 이해
  • Noob 프로그래머가 전문가가되었습니다
  • 어셈블리를 알고 있다면 High Lvl 언어의 컴파일러를 작성하는 방법을 알고 있습니다
  • 기타

1
이 모든 견해를 공유하십니까? 당신의 경험은 무엇입니까? (특히, "So Noob 프로그래머가 전문가가된다"라는 항목은 수십 년 전부터 구식 인 것 같습니다.)
Raphael

woah woah 당신은이 주제에 너무 손대지 않아도됩니다. 나는 그의 중복 질문에 대한 답변을 연결하고 있습니다. 그리고 "So Noob 프로그래머가 전문가가되었습니다"가 여기서 가장 높은 표를 얻었 습니다 . 그와 나에게 논쟁하지 마라 =)
compski

1
나는 건전하지 않으며, 당신이 당신의 대답을 좋은 것으로 만드는 것을 돕기 위해 노력하고 있습니다 (현재는 당신이 소수의 자료에만 링크하기 때문에 그 질문에 완전히 대답하지 못합니다). 자신의 생각을 비교 방식으로 포함시키는 것이 첫 번째 단계입니다. (제외적인 방식으로 의견을 연관시킴으로써, 당신은 그들에게 가치를 부여합니다. 다시 말해, 당신은 왜 당신이 그 의견을 (재) 포스트에 대한 답변으로 충분히 평가하는지에 대해 논쟁 할 수 있어야합니다.)
Raphael

글쎄요, 저의 경험은 일부 고급 프로그래밍 언어에 익숙해지면 어셈블리 언어를 배우는 데 정말로 싫어하고 있습니다. 그리고 저는 훌륭한 프로그래머 나 C ++ / C를 알고있는 사람들이 ASM에서 아주 잘 프로그래밍 할 수 있다는 것을 알고 있습니다. 나는 내 의견이 내 답변에 게시 될만큼 가치가 있다고 생각하지 않았다. 그 이유는 ...
compski

첫 번째 링크가 끊어졌습니다.
Hola Soy Edu Feliz Navidad

1

어셈블리 = 머신 코드
어떤 사람들은 어셈블리 언어가 CPU가 이해하는 숫자 코드와 어떻게 다른지에 대해 계속 고민하고 있습니다.
이것은 (진실이지만) 요점을 완전히 놓친 것입니다.
번역이 어셈블리 언어를 사용하는 한 숫자 (이진수, 16 진수)는 하나의 동일한 것입니다.

집어 넣거나 떨어 뜨리기
조립품을 조립하면 실제 컴퓨터의 작동 방식을 알 수 있습니다.
grokking 어셈블리에는 다음이 포함됩니다.

  • 지침 과 그 의미를 배우는 것 (duh).
  • 명령이 무엇을 이해, 그들이 무엇을 하지 않고 모든 부작용 .
  • CPU가 명령어를 처리하는 방법 학습
    • 파이프 라인 작동 방식
    • 무슨 multiscalar
    • CPU 코어 란?
    • 캐시 작동 방식
    • 사이클 수를 이해하는 방법
    • Agner Fog의 가르침을 배우기
  • 컴파일러가 코드를 생성하는 방법과 때때로 실패하는 방법을 이해합니다.
  • 잘 정의되고 매우 구체적인 문제를 최적화합니다.

어셈블리를 시작하면 키보드에 연결된 CPU가 어떻게 작동하는지 거의 완전한 그림이 나타납니다.
두뇌 외과 의사가 메스를 사용하는 것처럼이 지식을 사용해야합니다.

복잡한 추상화가 필요하지 않습니다.
어셈블리 (및 운영 테이블의 CPU)를 grok하지 않는 한 RAM 시스템 추상화의 클러치에서 벗어날 수 없습니다 (또는 Turing 머신 의 공포를 신이 금지합니다 ).

L33t Hax0r 5k1llz
Assembly는 또한 133thax0r이 보호 체계를 무너 뜨리는 방법을 이해하는 데 도움이됩니다. (Q : ASLR하지 작업을 수행하는 이유 ? 때문에 mov rax,fs:[28h]휴식을 ).

0.1 %
중요한 것은 조립에 대한 지식이 아니라 작업하는 기계에 대한 지식입니다.
기계를 알고 싶다면 기계를 이해해야하며 이는 기계의 언어를 말하는 것을 의미합니다.

그렇지 않으면 추상화에 갇혀 있습니다.
그것은 과학이고 좋은 것이지만 그것은 결코 완전한 그림이 아닙니다.

코사 어 를 말하는 법을 배우는 것과 같습니다.
전문가 수준을 목표로하지 않고 자신이 아는 것을 가장 잘 고수하지 않으면 클릭이 삶을 복잡하게 만듭니다 .

재미 있기 때문입니다.


1
내가 본 적이있는 기사에서 grok이라는 단어를 가장 자주 사용
rekciltnuc

-1

지금까지 IBM System 32를 사용하여 RPG II를 처음 배우고 나중에 370에서 APL을 배웠습니다. 저는 크기와 속도에 관한 모든 것이 었습니다. 내 진언은 더 작고 빨랐습니다. 어셈블리는 가장 컴팩트하고 빠른 언어입니다. 나는 C와 Assembly에서 테스트 프로그램을 만들 것이다. C 프로그램에 100KB가 필요한 경우 동등한 어셈블리 프로그램은 종종 5KB 미만입니다. C 컴파일러의 출력을 연구 할 때 매개 변수를 확인하고 다시 확인하는 코드는 매우 드물고 이국적이며 불필요 한 오류를 조건부로 확인하는 코드를 찾았습니다. 모두 시간이 걸렸지 만 가장 큰 메모리 팽창은 절대적으로 모든 것을 전달했습니다. 스택으로 그리고 스택에서

오늘날의 프로그래밍 환경에서 코드 작성은 추가적인 보안 및 보호 수준을 제공합니다. 고급 언어로 액세스 할 수없는 하드웨어에서 직접 정보를 읽을 수 있기 때문에 특정 기계에서만 프로그램을 사용할 수있는 방식으로 Assembly를 사용하여 암호화 할 수 있습니다. 예를 들어 네트워크 인터페이스의 MAC 주소를 사용하여 사용자 키를 암호화 한 다음 등록되지 않은 하드 드라이브의 특정 섹터에 해당 키를 보관 한 다음 다른 파일을 덮어 쓸 수 없도록 섹터를 불량으로 표시합니다. 물론 당신은 부문을 잃어 버렸지 만 그게?니까? 2048 년 또는 4096 바이트 중에서 수십억 또는 수조?


1
"고급 언어로 접근 할 수 없음"은 무엇을 의미합니까?
David Richerby
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.