학습 어셈블리는 프로그래밍에 어떤 도움이됩니까? [닫은]


132

저는 약 10 년 동안 더 높은 수준의 언어 (Python, C #, VBA, VB.NET)로 프로그래밍을 해왔으며 "후드"아래에서 무슨 일이 일어나고 있는지 전혀 전혀 모르고 있습니다.

학습 어셈블리의 이점이 무엇인지 궁금하며 프로그래머로서 어떻게 도움이됩니까? 더 높은 수준의 코드로 작성한 내용과 어셈블리에서 발생하는 내용 사이의 연결을 정확하게 보여줄 리소스를 제공해 주시겠습니까?


2
코드에 대한 자세한 내용을 알고 싶다면 인텔 프로세서 설명서 (소개 부분 만 해당)를 참조하십시오 ( download.intel.com/products/processor/manual/325462.pdf) . 어쩌면 이것은 당신이 원했던 것보다 조금 더 깊지 만 유용하다고 생각합니다.
superM

4
.Net에서 특히 어떤 일이 발생하는지 알고 싶다면 CIL에 대해 더 배우고 싶을 것입니다. 어떤면에서는 조립과 비슷하지만 훨씬 더 높은 수준입니다. 이 때문에 실제 조립보다 이해하기가 더 쉽습니다.
svick

6
어셈블리를 배우면 for외부에서 변수를 선언 하여 루프를 최적화한다고 생각하지 않아도됩니다.
StriplingWarrior

7
세상에. 약 1 년 전에 제가 대학에서 수강 한 어셈블리 언어 수업에 대해 상기시켜 주셨습니다. 우리가 당연하다고 생각하는 매우 간단한 것들이 수백 또는 수천 개의 더 작고 더 낮은 수준의 작업으로 번역되는 것을 보는 것은 놀랍습니다. 컴퓨터는 특별한 기계입니다.
Radu Murzea

14
어셈블리 학습은 어셈블리에서 복잡한 코드를 다시 작성할 필요가 없도록 프로그래밍 언어 개념에 대한 깊이 있고 지속적인 사랑을 부여합니다.
Shadur

답변:


188

실제로 어떻게 작동 하는지 이해할 수 있기 때문 입니다.

  • 함수 호출은 무료가 아니며 호출 스택이 오버플로 될 수있는 이유 (예 : 재귀 함수)를 이해합니다. 인수가 함수 매개 변수에 전달되는 방법과 수행 할 수있는 방법 (메모리 복사, 메모리 지정)을 이해합니다.
  • 메모리는 무료가 아니며 자동 메모리 관리가 얼마나 가치가 있는지 이해합니다. 기억은 당신이 "그냥 가지고있는 것"이 ​​아닙니다. 실제로 기억하고 관리해야하며, 가장 중요한 것은 잊지 말아야합니다.
  • 제어 흐름이 가장 기본적인 수준에서 어떻게 작동하는지 이해합니다.
  • 더 높은 수준의 프로그래밍 언어로 된 구문을 더 높이 평가할 것입니다.

결론은 C # 또는 Python으로 작성한 모든 내용이 컴퓨터가 실행할 수있는 일련의 기본 동작으로 변환되어야한다는 것입니다. 클래스, 제네릭 및 목록 이해 측면에서 컴퓨터를 생각하기는 쉽지만 고급 프로그래밍 언어로만 존재합니다.

우리는 정말 멋져 보이지만 저수준의 일을하는 것으로 잘 번역되지 않는 언어 구조를 생각할 수 있습니다. 그것이 실제로 어떻게 작동하는지 알면 왜 일이 그 방식대로 작동하는지 더 잘 이해할 수 있습니다.


12
"고급 프로그래밍 언어로 작성된 구문에 대해 더 높이 평가할 것"은 +1입니다. 좋은 대답입니다.
DevSolo

42
몇 주간의 asm을 제외하고는 C를 고급 프로그래밍 언어로 생각하기 시작할 것입니다. 저수준 임베디드 장치 개발자와 이야기하지 않는 한, 큰 소리로 내면 대부분의 사람들이 자신이 약간 미쳤다고 생각하게됩니다.
Dan Neely

19
@ Dan : 시간이 지남에 따라 이러한 용어가 어떻게 변하는 지 재미 있습니다. 20 년 전 프로그래밍을 시작할 때 누군가에게 "물론 C는 고급 언어입니다!"라고 물으면 그것은 분명 해야한다 . 표준화 된 힙 및 메모리 액세스 모델을 제공합니다. 그리고 그것은 하드웨어와는 거리가 멀다. A의 낮은 수준의 언어, 모든 메모리를 추적해야하는 것은 자신을 해결, 또는 당신이 뭔가를하고 있다면 정말 멋진, 당신은 당신의 자신의 힙 할당 쓰기! 그래서 오늘날 고수준 또는 저수준을 만드는 기준은 무엇입니까?
메이슨 휠러

9
높은 수준 / 낮은 수준은 이진이 아닙니다. 커리어에서 어셈블리와 파이썬을 모두 쓴 다재다능한 프로그래머는 C 또는 C ++를 중급 언어로 간주 할 수 있습니다.
Russell Borogove

6
그것들은 이해해야 할 중요한 것들이지만, 컴퓨터 교육 수준의 컴퓨터 입문 과정과 같은 추상적 인 수준에서 쉽게 다루어집니다. 저는 어셈블리 프로그래머는 아니지만 직접 말하면 잘 이해합니다. 일부 SO 답변에서 나는 명령 캐시와 파이프 라인에 대한 토론을 보았으며 실제로 사람들은 내 머리를 돌립니다. 그러나이 하위 지시 수준은 (지금까지) 답변에서 누락되었습니다. 그렇다면 기초 과정을 수강하는 것과는 반대로 실제로 어셈블리 프로그래밍을 배우면 어떤 이점이 있습니까?
Alexis

33

"후드에서 발생하는"항목과 포인터 작동 방식 및 레지스터 변수 및 아키텍처 (메모리 할당 및 관리, 매개 변수 전달 (값 / 기준) 등)의 의미에 대한 이해를 돕습니다.

C를 빠르게 살펴 보려면 어떻습니까?

#include <stdio.h>

main()
{
  puts("Hello World.");
  return(0);
}

gcc -S so.c다음으로 어셈블리 출력을 컴파일 하고 살펴보십시오 so.s.

 $ cat so.s

    .file   "so.c"
    .section    .rodata
.LC0:
    .string "Hello World."
    .text
.globl main
    .type   main, @function
main:
    pushl   %ebp
    movl    %esp, %ebp
    andl    $-16, %esp
    subl    $16, %esp
    movl    $.LC0, (%esp)
    call    puts
    movl    $0, %eax
    leave
    ret
    .size   main, .-main
    .ident  "GCC: (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3"
    .section    .note.GNU-stack,"",@progbits

2
+1 : 좋은 팁! C 컴파일러의 기능을 살펴보면 많은 것을 배울 수 있습니다.
Giorgio

8
... SOS가 의도적인가? (도움말 등)
Izkata

1
@ Izkata 하하 .. 좋은 하나, 나는 심지어 그것을 알아 차리지 못했습니다. 나는 표준이 so.c(내가 가지고있는 것처럼 유래 질문에 대한 파일을 so.py, so.awk등)을 신속하게 일을 테스트합니다. So.S .. :)
Levon

9
컴파일 gcc -O -c -g -Wa,-ahl=so.s so.c하면 C 코드의 각 줄에 대한 어셈블리 출력을 볼 수 있습니다. 이것은 무슨 일이 일어나고 있는지 이해하기 쉽게 만들어줍니다.
Mackie Messer

1
예, 출력이 길다. 의 5:so.c5 행에 대한 코드를 찾기 위해 검색 할 수 있습니다 so.c.
Mackie Messer

30

나는 당신이 찾는 대답이 여기 있다고 생각합니다 : http://www.codeproject.com/Articles/89460/Why-Learn-Assembly-Language

기사에서 인용 :

사실이지만, 다음 고객의 앱을 어셈블리로 작성하지는 않을 것입니다. 그러나 어셈블리 학습을 통해 얻을 수있는 이점은 여전히 ​​많습니다. 오늘날 어셈블리 언어는 주로 하드웨어 직접 조작, 특수 프로세서 명령어에 대한 액세스 또는 중요한 성능 문제를 해결하는 데 사용됩니다. 일반적인 용도는 장치 드라이버, 저수준 임베디드 시스템 및 실시간 시스템입니다.

문제는 사실 더 복잡한 고급 언어가되고 ADT (추상 데이터 형식)가 많을수록 이러한 옵션을 지원하기 위해 더 많은 오버 헤드가 발생한다는 것입니다. .NET의 경우 아마도 부풀어 오른 MSIL 일 것입니다. MSIL을 알고 있다고 상상해보십시오. 이곳은 어셈블리 언어가 빛을 발하는 곳입니다.

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

어셈블리로 쓰려면 프로세서와 메모리가 어떻게 작동하여 "일이 발생하도록"하는지를 정확히 이해해야합니다. 어셈블리 언어는 암호화되어 있으며 응용 프로그램 소스 코드 크기는 고급 언어의 코드보다 훨씬 큽니다. 그러나 그것에 대해 실수하지 마십시오. 시간을 내고 어셈블리를 마스터하려는 노력을 기울이면 더 나아질 것이며 현장에서 눈에 띄게됩니다.

또한이 책은 컴퓨터 아키텍처의 단순화 된 버전을 가지고 있기 때문에이 책을 추천합니다. 컴퓨팅 시스템 소개 : 비트 및 게이트에서 C 및 그 너머로, Austin Sanjay J. Patel의 텍사스 대학교 (University of Texas)의 2 / e Yale N. Patt, 어 바나 / 샴페인 일리노이 대학교


7
이것은 ASM이 사용되는 것을 설명하고 HLL이 부풀어 오른다는 것을 언급하지만 ASM 학습에 주어진 유일한 이점은 초고속 코드를 작성하는 것입니다. 예. 그러나 ASM을 배우더라도 실제로 앱에 포함시킬 가능성은 얼마나됩니까? 하드웨어 컨트롤러 나 장치 드라이버가 아닌 비즈니스 앱을 작성한다고 가정합니다.

+1 @notkilroy, 링크와 특히 책 추천에 감사드립니다
Anthony

2
@Jon, 비즈니스 소프트웨어를 개발하는 이유를 모르겠습니다. DBA이거나 컴파일러를 작성하거나 메모리 공간이 부족한 경우 한 가지이지만, 많은 사람들이 자주 사용한다고 생각하지 않습니다. 최적화는 대부분 컴파일러가 처리하므로 어셈블리에서 작성하는 가장 큰 이유입니다. 때로는 메모리 누수를 추적 할 때 도움이됩니다.
Brynne

비즈니스 응용 프로그램 개발을 전문으로하기 때문에 주로 4GL을 사용하는 SQL 기반 응용 프로그램 개발 도구를 사용합니다. 이를 통해 앱을 신속하게 프로토 타입하고 프로덕션 시스템에 맞게 사용자 지정할 수 있습니다. 호출 가능한 cfunc를 작성해야하는 경우는 거의 없습니다. 배달 시간과 수정 시간은 세상에서 큰 요소입니다!
Frank R.

2
나는 매우 동의하지 않습니다. 자동화 된 옵티마이 저는 종종 빠른 어셈블리 생성에서 인간 프로그래머를 능가 할 수 있습니다.
DeadMG

22

내 겸손한 의견으로는 별로 도움이되지 않습니다.

나는 x86 어셈블리를 매우 잘 알고있었습니다. 내 과정에서 어셈블리가 나타 났을 때 약간 도움이되었고 인터뷰 중에 한 번 나타 났으며 컴파일러 (Metrowerks)가 잘못된 코드를 생성했음을 증명하는 데 도움이되었습니다. 컴퓨터가 실제로 어떻게 작동하는지는 매혹적이고, 나는 그것을 배운 것에 대해 지적으로 부유하다고 느낍니다. 당시에 노는 것도 재미있었습니다.

그러나 오늘날의 컴파일러는 거의 모든 코드에서 거의 모든 사람보다 어셈블리를 생성하는 것이 좋습니다. 컴파일러를 작성하거나 컴파일러가 옳은 일을하고 있는지 확인하지 않는 한, 아마도 배우면서 시간을 낭비하고있을 것입니다.

C ++ 프로그래머가 여전히 유용하게 묻는 많은 질문은 어셈블리를 아는 것으로 알려집니다. 예를 들어 : 스택 또는 힙 변수를 사용해야합니까? 값이나 const 참조로 전달해야합니까? 그러나 거의 모든 경우에있어서, 이러한 선택은 계산 시간 절약이 아닌 코드 가독성에 기초하여 이루어져야한다고 생각합니다. 예를 들어 변수를 범위로 제한 할 때마다 스택 변수를 사용하십시오.

저의 겸손한 제안은 소프트웨어 디자인, 알고리즘 분석 및 문제 해결과 같이 실제로 중요한 기술에 초점을 맞추는 것입니다. 큰 프로젝트를 개발 한 경험이 있으면 직관력이 향상되어 어셈블리를 아는 것보다 훨씬 가치가 높아집니다.


2
동의하지 않습니다. 특정 알고리즘에 대한 광범위한 지식과 하드웨어를 잘 알고 있다면 일반적으로 컴파일러가 안전하게 재생해야하므로 컴파일러가 만들 수있는 것보다 더 최적화 된 어셈블리 코드를 만들 수 있습니다. 코드가 어셈블리로 어떻게 변환되는지를 아는 것도 최적화를 수행하는 데 도움이됩니다.
Leo

최적화는 그것을 배우는 이유가 아닙니다. 그런 점에서, 나는 Neil G에 동의합니다. 그러나 Neil G는 그 요점이 없습니다. 그는 실제 기계에 대한 기본적인 이해가 어떻게 고급 언어를 사용 하는지를 평가하고 있습니다.
Warren P

내 경험상 알고리즘 구현, 사물 측정, 최적화 방법 찾기, 더 나은 방법 구현 등을 통해 알고리즘을 빠르게 만들 수 있습니다. 어셈블리의 문제점은 구현하는 데 시간이 오래 걸리므로 반복해서 다듬을 기회가 있습니다.
gnasher729

요즘 어셈블리에서 코딩해야 할 경우는 거의 없지만 작동 방식을 아는 것은 매우 귀중하며 모든 작동 방식을 알고 싶은 사람들에게 많은 도움이 될 것입니다. 예를 들어, 왜 그런 일이 일어나고 있는지 알지 못하면 일을 따르는 것이 어렵다는 것을 알게 됩니다.
Winger Sendon

21

작업중인 시스템의 한 단계 '더 깊은'에 익숙해야합니다. 한 번에 너무 멀리 건너 뛰는 것은 나쁘지 않지만 원하는만큼 도움이되지 않을 수 있습니다.

고급 언어의 프로그래머는 하위 언어를 배워야합니다 (C는 훌륭한 선택입니다). 컴퓨터가 객체를 인스턴스화하거나 해시 테이블 또는 세트를 만들도록 지시 할 때 덮개 아래에서 진행되는 일을 이해하기 위해 어셈블리에 이르기까지 모든 과정을 진행할 필요는 없지만 코딩 할 수 있어야합니다 그들.

Java 프로그래머의 경우 C를 배우면 인수를 전달하여 메모리 관리에 도움이됩니다. C로 광범위한 Java 라이브러리를 작성하면 Set의 구현을 사용할 때 (해시를 원하십니까? 또는 트리를 원하십니까?) 스레드 환경에서 char *를 처리하면 String을 변경할 수없는 이유를 이해하는 데 도움이됩니다.

다음 단계로 ... AC 프로그래머는 어셈블리에 어느 정도 익숙해야하며 어셈블리 유형 (내장 시스템 상점에서는 찾을 수 없음)은 게이트 레벨에서 사물을 이해하는 데 도움이 될 것입니다. 게이트를 다루는 사람들은 양자 물리학을 알아야합니다. 그리고 양자 물리학 자들은 여전히 ​​다음 추상화가 무엇인지 알아 내려고 노력하고 있습니다.


1
한 단계 더 깊이가 맞습니다. 나는 커플을 찾는 경향이 있지만 C # 프로그래머를 위해 MSIL을 연구하는 것보다 x86 어셈블리 지식이 투자 가치가 있다고 가정하면 너무 많이 요구합니다. Uni에서 어셈블리 및 솔리드 스테이트 물리학을 연구 한 사람으로서, 게이트 디자인의 물리학을 아는 것이 전자 분야에서 학위를 취득하는 것 외에는 전혀 도움이되지 않았다고 생각합니다.
Muhammad Alkarouri

@MuhammadAlkarouri 나는 전류 누설, 런의 길이, 저항 및 열이 시스템에 미치는 영향을 이해하는 선을 따라 생각하고 있었다. 기본 '이유'에 대한 이해는 최소한의 미량 분리 및 작동 허용 오차의 규칙 이상의 결정을 내리는 데 도움이됩니다.

5

알고있는 언어로 C 또는 C ++에 대해서는 언급하지 않았으므로 어셈블리에 대해 생각하기 전에 잘 배우는 것이 좋습니다. C 또는 C ++는 관리되는 언어로 완전히 투명한 모든 기본 개념을 제공하며이 페이지에서 언급 된 대부분의 개념을 실제 프로젝트에서 사용할 수있는 가장 중요한 언어 중 하나로 이해합니다. 그것은 당신의 프로그래밍 기술에 진정한 부가 가치입니다. 어셈블리는 매우 특정한 영역에서 사용되며 C 또는 C ++만큼 유용하지는 않습니다.

또한 관리되지 않는 언어의 작동 방식을 이해하기 전에 어셈블리로 뛰어 들지 말아야한다고 말하고 싶습니다. 그것은 거의 의무적 인 독서입니다.

더 나아가려면 어셈블리를 배워야합니다. 언어의 각 구문이 정확히 어떻게 생성되는지 알고 싶습니다. 정보를 제공하지만 완전히 다른 수준의 복잡성입니다.


5

언어를 잘 알고 있다면 최소한 한 단계의 추상화 수준으로 기술에 대한 기본 지식이 있어야합니다.

왜? 일이 잘못되면 기본 메커니즘에 대한 지식을 통해 이상한 문제를 훨씬 쉽게 디버깅하고 자연스럽게 더 효율적인 코드를 작성할 수 있습니다.

예를 들어 Python (/ CPython)을 사용하여 이상한 충돌이나 성능 저하를 시작하면 C 코드를 디버깅하는 방법에 대한 지식은 참조 계산 메모리 관리 방법에 대한 지식과 마찬가지로 매우 유용 할 수 있습니다. 이것은 또한 C 확장으로 무언가를 쓸 때 / 그렇다면 알 수 있도록 도와줍니다.

이 경우 귀하의 질문에 대답하기 위해 어셈블리에 대한 지식은 실제로 숙련 된 Python 개발자에게 도움이되지 않습니다 (추상화에 너무 많은 단계가 내려갑니다 .Python에서 수행 한 작업은 많은 어셈블리 명령을 초래합니다)

그러나 C에 익숙한 경우 "다음 단계 아래로"(어셈블리)를 아는 것이 실제로 유용 할 것입니다.

마찬가지로 CoffeScript를 사용하는 경우 Javascript를 아는 것이 (매우) 유용합니다. Clojure를 사용하는 경우 Java / JVM에 대한 지식이 유용합니다.

이 아이디어는 프로그래밍 언어 외부에서도 작동합니다. 어셈블리를 사용하는 경우 기본 하드웨어가 작동하는 방식에 익숙해지는 것이 좋습니다. 웹 디자이너 인 경우 웹 응용 프로그램이 어떻게 구현되는지 아는 것이 좋습니다. 당신이 자동차 정비공이라면, 물리학에 대한 지식을 가지고있는 것이 좋습니다


3

작은 c 프로그램을 작성하고 출력을 분해하십시오. 그게 다야. 그러나 운영 체제의 이점을 위해 추가 된 다소의 "하우스 키핑"코드를 준비하십시오.

어셈블리는 메모리, 프로세서 레지스터 등을 직접 처리하기 때문에 후드에서 발생하는 상황을 이해하는 데 도움이됩니다.

복잡한 복잡한 운영 체제를 사용하지 않고 베어 메탈로 전환하려면 Arduino를 어셈블리 언어로 프로그래밍하십시오 .


3

프로그래머가 모두 유형이 아니기 때문에 명확한 답은 없습니다. 아래에 무엇이 숨어 있는지 알아야합니까? 그렇다면 배우십시오. 당신은 단지 호기심에서 그것을 배우고 싶습니까? 그렇다면 배우십시오. 그것이 당신에게 실질적인 이익이 없다면 왜 귀찮게합니까? 자동차를 운전하기 위해 기계공 수준의 지식이 필요합니까? 정비공은 자동차에서 일하기 위해 엔지니어의 지식 수준이 필요합니까? 이것은 심각한 비유입니다. 정비사는 자신이 보유한 차량에 대한 깊이있는 이해를 위해 다이빙하지 않고도 매우 우수하고 생산적인 정비사가 될 수 있습니다. 음악도 마찬가지입니다. 멜로디, 하모니 및 리듬의 복잡한 부분을 정말 잘 활용하여 훌륭한 가수 또는 연주자가 되십니까? 아닙니다. 재능이 뛰어난 일부 음악가들은 도리안 모드와 리디 언 모드의 차이점을 말할뿐 아니라 악보를 읽을 수 없습니다. 원하지만 괜찮아도 필요하지 않습니다. 당신이 웹 개발자라면 어셈블리는 내가 생각할 수있는 실질적인 용도가 없다. 당신이 임베디드 시스템이나 정말로 특별한 무언가에 있다면, 필요할 수도 있지만, 알고 있다면 알 것입니다.

Joel은 고급이 아닌 언어를 기대하는 이러한 가치에 대해 다음과 같이 설명합니다. http://www.joelonsoftware.com/articles/ThePerilsofJavaSchools.html


2

실제로, 아마도 당신에게 가장 적합한 것은 (내 지식으로는) 어디에도 존재하지 않는 클래스 일 것입니다. 머신 / 어셈블러 언어 및 스토리지 어드레싱 개념에 대한 간략한 개요와 컴파일러 구성 둘러보기가 결합 된 클래스입니다 , 코드 생성 및 런타임 환경.

문제는 C # 또는 Python과 같은 하드웨어에서 멀리 떨어진 고급 언어를 사용하면 수천 번의 기계 명령이 아니라면 매번 움직일 때마다 수백 가지가된다는 사실에 정말로 감사하지 않으며 몇 줄의 고급 언어로 방대한 양의 스토리지를 액세스하고 수정할 수있는 방법을 이해하는 경향이 없습니다. "표지 아래"에서 무슨 일이 일어나고 있는지 정확히 알아야 할 필요는 없지만, 발생하는 범위와 발생하는 유형에 대한 일반적인 개념을 이해해야합니다.


1

이 질문에 대한 나의 대답은 비교적 최근에 발전했습니다. 기존 답변에는 과거에 말했던 내용이 포함됩니다. 실제로, 이것은 여전히 높은 수준의 프로그래밍에서 구조를 이해하십시오 .``라는 최고의 대답으로 덮여 있지만, 언급 할 가치가 있다고 생각되는 특별한 경우입니다 ...

연구를 참조하는 이 Jeff Atwood 블로그 게시물 에 따르면 과제를 이해하는 것이 프로그래밍 이해의 핵심 문제입니다. 학습자 프로그래머는 표기법이 단지 컴퓨터가 따르는 단계와 단계에 따른 이유를 나타내거나 수학 방정식 등에 대한 오해를 불러 일으키는 방식으로 끊임없이 혼란스러워한다는 것을 이해합니다.

6502 어셈블러에서 다음을 이해한다면 ...

LDA variable
CLC
ADC #1
STA variable

정말 단계 일뿐입니다. 그런 다음 할당 문으로 번역하는 법을 배우면 ...

variable = variable + 1;

수학 방정식에 오해를 불러 일으킬 필요가 없습니다. 이미 매핑 할 올바른 정신 모델이 있습니다.

편집 -물론 당신이 얻는 설명 LDA variable이 기본적으로 ACCUMULATOR = variable어떤 자습서와 참조에서 얻은 것이라면, 시작한 곳으로 돌아가서 전혀 도움이되지 않습니다.

나는 6502 어셈블러를 제 2 언어로, 첫 번째는 코모도 베이직 (Comodore Basic)으로 배웠고, 배우는 것이 거의 없었지만, 어셈블러는 그 당시 훨씬 더 흥미로워 보였기 때문에 그 당시에는 그다지 많이 배우지 못했습니다. . 일부는 14 살짜리 괴짜 였기 때문입니다.

내가 한 일을 권장하지는 않지만 아주 간단한 어셈블러 언어로 몇 가지 간단한 예제를 공부하는 것이 고급 언어를 배우는 데 가치가 있는지 궁금합니다.


0

컴파일러 작성자이거나 데이터 처리 알고리즘과 같이 고도로 최적화 된 것이 필요하지 않은 경우 어셈블리 코딩을 학습하면 아무런 이점이 없습니다.

어셈블리로 작성된 코드를 작성하고 유지하는 것은 매우 어렵습니다. 따라서 어셈블러 언어를 잘 알고 있더라도 다른 방법이 없으면 사용해서는 안됩니다.

" SSE 최적화 : 사례 연구 "기사에서는 어셈블리로 이동할 때 수행 할 수있는 작업을 보여줍니다. 저자는 알고리즘을 100 사이클 / 벡터에서 17 사이클 / 벡터로 최적화했습니다.


1
저자는 C ++ 버전에서 벡터 명령어 나 내장 함수를 사용하지 않았습니다. SSE 코드를 작성하기 위해 어셈블러가 필요하지 않습니다.
gnasher729

@ gnasher729 예, 필요 없습니다. 그러나 어셈블리를 사용하면 프로그램이 훨씬 빠르게 실행될 수 있습니다. 인간은 더 똑똑 할 수 있으며 결국에는 컴파일러가 될 수 있습니다 (드문 경우).
BЈовић

0

어셈블리에 쓰면 세부 정보의 양 (레지스터 할당 등)으로 인해 속도가 크게 향상되지 않습니다. 아마도 가장 사소한 알고리즘을 작성하게 될 것입니다.

또한 최신 (70-80 년대 이후에 읽은 설계) 프로세서 어셈블리를 사용하면 현재 진행중인 작업 (즉, 대부분의 프로세서)을 알 수있는 충분한 세부 정보가 제공되지 않습니다. 최신 PU (CPU 및 GPU)는 예약 명령이 진행되는 한 상당히 복잡합니다. 조립의 기초 (또는 의사 조립)를 알면 컴퓨터 아키텍처 서적 / 코스를 이해하여 추가 지식 (캐시, 고장난 실행, MMU 등)을 제공 할 수 있습니다. 일반적으로 복잡한 ISA를 이해하기 위해 복잡한 ISA를 알 필요는 없습니다 (MIPS 5는 매우 인기있는 IIRC입니다).

왜 프로세서를 이해합니까? 무슨 일이 일어나고 있는지 더 많이 이해할 수 있습니다. 순진한 방식으로 행렬 곱셈을 작성한다고 가정 해 봅시다.

for i from 0 to N
    for j from 0 to N
        for k from 0 to N
            A[i][j] += B[i][k] + C[k][j]

그것은 목적에 따라 '충분히'좋을 수도 있습니다 (4x4 행렬 인 경우 어쨌든 명령어를 벡터로 컴파일 할 수 있음). 그러나 대규모 배열을 컴파일 할 때 매우 중요한 프로그램이 있습니다-최적화 방법? 어셈블리에서 코드를 작성하면 몇 %의 향상이있을 수 있습니다 (대부분의 사람들이하는 것처럼-순진한 방식으로 레지스터 활용률 저하, 메모리로드 / 저장 및 HL 언어에서 느린 프로그램 효과를 갖는) .

그러나 큰 행렬에 대한 다양한 요인에 따라 IIRC는 10 배가 될 수 있습니다.

for i from 0 to N
    for k from 0 to N
        for j from 0 to N
            A[i][j] += B[i][k] + C[k][j]

즉, 컴파일러 ( gcc의 흑연 및 LLVM을 사용하는 모든 것에 대한 Polly) 를 수행 할 수있는 컴파일러에 대한 작업이 있습니다 . 그들은 심지어 그것을 변환 할 수 있습니다 (죄송합니다-메모리에서 차단을 쓰고 있습니다) :

for i from 0 to N
    for K from 0 to N/n
        for J from 0 to N/n
            for kk from 0 to n
                for jj from 0 to n
                    k = K*n + kk
                    j = J*n + jj
                    A[i][j] += B[i][k] + C[k][j]

요약하면-어셈블리의 기본 사항을 알면 프로세서 디자인에서 다양한 '세부 사항'을 파고 들어 더 빠른 프로그램을 작성할 수 있습니다. RISC / CISC 또는 VLIW / 벡터 프로세서 / SIMD / ... 아키텍처의 차이점을 아는 것이 좋습니다. 그러나 x86으로 시작하지는 않을 것입니다 (아마도 ARM도 가능합니다). 레지스터 등이 무엇인지 아는 것으로 시작하기에 충분합니다.


여러 코드 샘플을 제공했지만 어셈블리 언어로 작성된
Robert Harvey

-1

일반적으로 디버깅 목적으로 매우 중요합니다. 명령 도중 시스템이 중단되고 오류가 의미가없는 경우 어떻게합니까? 안전한 코드 만 사용하는 한 .NET 언어에서는 문제가 훨씬 적습니다. 시스템은 거의 항상 시스템을 보호합니다.


-2

요컨대 나는 집회를 배우면 더 많은 일을 할 수 있기 때문에 답이된다고 생각합니다. 학습 어셈블리는 임베디드 디바이스 프로그래밍, 보안 침투 및 우회, 리버스 엔지니어링 및 시스템 프로그래밍의 영역에 대한 액세스 권한을 부여합니다.

프로그램 성능을 향상시키기 위해 그것을 배우는 것에 관해서는, 이것은 응용 프로그래밍에서 의심의 여지가 있습니다. 대부분의 경우 디스크와 네트워크 모두에서 I / O 액세스 최적화, GUI 구축 방법 최적화, 올바른 알고리즘 선택, 모든 코어 최대 활용 등이 수준의 최적화에 도달하기 전에 가장 먼저 집중해야 할 사항이 많습니다. , 최고의 하드웨어 머니로 운영하면 해석 언어에서 컴파일 언어로 전환하여 구매할 수 있습니다. 다른 최종 사용자를위한 소프트웨어를 작성하지 않는 한, 특히 클라우드 가용성의 경우 프로그래머의 시간당 임금에 비해 하드웨어가 저렴합니다.

또한 버스에 부딪 히거나 코드 버전으로 돌아와 마지막 버전을 작성한 후 1 년 후에 코드를 변경 한 후에는 코드의 가독성으로 프로그램 실행 속도를 높여야합니다.


-3

정렬 알고리즘, 연결된 목록, 이진 트리, 해싱 등 학습 알고리즘을 권장합니다.

또한 lisp를 배우십시오. 컴퓨터 프로그램의 구조 및 해석 groups.csail.mit.edu/mac/classes/6.001/abelson-sussman-lectures이 비디오 과정은 알고리즘을 포함하여 알아야 할 모든 것을 가르쳐 줄 것입니다 (모든 것을 수행하는 방법). 몇 가지 기본 명령, 하나의 lisp 기본 및 일부 어셈블러 도발).

마지막으로 어셈블러를 배워야하는 경우 ARM과 같은 쉬운 것을 배우십시오 (또한 x86보다 약 4 배 더 많은 장치에서 사용됨).


-8

대답은 단순히 사용하는 언어가 마지막에 어셈블러로 해석되거나 컴파일되어야하기 때문입니다. 언어 나 기계에 상관없이

언어 디자인은 CPU 작동 방식에서 파생됩니다. 저수준 프로그램에 대해서는 더 많고, 고수준 프로그램에 대해서는 더 적습니다.

나는 당신이 작은 어셈블러를 알아야 할뿐만 아니라 CPU 아키텍처를 알아야한다는 것을 말함으로써 끝날 것입니다. 어셈블러를 배우면 배울 수 있습니다.

몇 가지 예 : 왜 이것이 작동하지 않는지 이해하지 못하는 많은 Java 프로그래머가 있으며, 실행할 때 발생하는 일을 아는 것보다 적습니다.

String a = "X";
String b = "X";
if(a==b)  
    return true;

작은 어셈블러를 알고 있다면 메모리 위치의 내용과 해당 위치를 가리키는 포인터 변수의 숫자가 같은 것은 아니라는 것을 항상 알 것입니다.

더 나쁜 것은 출판 된 책에서도 JAVA 프리미티브가 값과 객체를 참조로 전달하는 것입니다. Java의 모든 인수는 값으로 전달되며 Java는 객체를 함수로 전달할 수 없으며 포인터 만 값으로 전달합니다.

만약 당신이 지금 무슨 일이 벌어지고 있는지 분명하게 조립한다면, 그렇지 않다면 대부분의 저자들이 단지 당신에게 진지한 거짓말을한다고 설명하기가 너무 복잡합니다.

물론, 이러한 결과는 미묘하지만 나중에 실제로 문제를 일으킬 수 있습니다. 어셈블러를 알고 있다면 문제가 아니며, 그렇지 않은 경우 오랫동안 밤새 디버깅을하고 있습니다.


5
첫 번째 단락은 완전히 잘못되었습니다. 언어는 ASM으로 컴파일되지 않고 기계어 코드로 컴파일됩니다. 통역사는 ASM으로 컴파일되지 않으며 코드 또는 바이트 코드를 해석하고 사전 컴파일 된 기계 코드에서 함수 또는 메소드를 호출합니다.

6
Java에 대해 주장하는 것은 잘못된 것입니다. String a = "X"; String b = "X"; if( a==b) return true;실제로 컴파일러가하는 == true것 때문에 시작 String interning합니다. 다른 모든 Java 문도 잘못되었습니다. Java에는 포인터가 없으며 동일한 것이 아닌 참조가 있습니다 . 그리고 그 어떤 것도 어떤 방식으로도 어셈블러와 관련이 없습니다. Java는 프리미티브를 값으로 전달하고 값으로 참조를 전달합니다. Java에는 포인터가 없으므로 아무것도 전달할 수 없습니다. 다시 ASM을 아는 것과 관련이 없습니다.

저는 항상 고급 언어가 ASM이 아닌 객체 (머신 코드) 또는 의사 코드로 컴파일되었다고 생각했습니다.
Frank R.

@FrankComputer는 정확하지만 머신 코드 바이트는 어셈블리 명령에 1 : 1로 매핑되므로 코드 객체와 ASM (디 컴파일 또는 조립)간에 쉽게 변환 할 수 있습니다.
dbr

2
@FrankComputer 지난번에 gcc가 C / C ++ / fortran / java / ada / etc를 내부 바이트 코드로 컴파일하고 내부 바이트 코드를 어셈블러로 컴파일하는 것을 보았습니다. 그런 다음이 어셈블러 코드를 어셈블러로 디스패치하여 기계 코드로 변환합니다.
ctrl-alt-delor
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.