왜 의회에서 작성된 프로그램이 더 자주 작성되지 않습니까? [닫은]


216

C와 같은 고급 언어보다 어셈블리 프로그래밍이 더 오래 걸리고 프로그래밍하기가 더 어렵다는 주류 의견 인 것 같습니다. 따라서 이러한 이유로 고급 언어로 작성하는 것이 더 좋습니다. 더 나은 이식성의 이유로.

최근 x86 어셈블리로 글을 쓰고 있는데 이식성을 제외하고는 이러한 이유가 실제로 사실이 아니라는 생각이 들었습니다. 아마도 그것은 친숙하고 어셈블리를 잘 작성하는 방법을 아는 문제 일 것입니다. 또한 어셈블리 프로그래밍은 HLL 프로그래밍과는 상당히 다릅니다. 아마도 경험이 풍부하고 숙련 된 어셈블리 프로그래머는 숙련 된 C 프로그래머가 C로 작성하는 것처럼 쉽고 빠르게 프로그램을 작성할 수 있습니다.

어쩌면 어셈블리 프로그래밍이 HLL과 상당히 다르기 때문에 다른 사고, 방법 및 방법이 필요하기 때문에 익숙하지 않은 프로그램을 작성하는 것이 매우 어색해 보이므로 프로그램 작성에 나쁜 이름을 부여합니다.

이식성이 문제가되지 않는다면 실제로 C가 NASM과 같은 훌륭한 어셈블러를 어떻게 갖추었을까요?

편집 : 그냥 지적하십시오. 어셈블리로 작성하는 경우 명령 코드 만 작성하지 않아도됩니다. 매크로와 프로 시저 및 고유 한 규칙을 사용하여 다양한 추상화를 통해 프로그램을보다 모듈화되고 유지 보수 가능하며 읽기 쉽게 만들 수 있습니다. 이것은 좋은 어셈블리를 작성하는 방법에 익숙해지는 곳입니다.


71
쓰기? 코드를 읽는 것은 어떻습니까? 당신 (그리고 다른 사람들)은 당신이 쓰는 것보다 훨씬 더 많은 코드를 읽을 것입니다
nos

81
프로그램이 새로운 플랫폼에서 실행되기 때문에 왜 새로운 언어를 배워야합니까? CPU가 얼마나 많은 레지스터가 있고 그로 무엇을 할 수 있는지에 대한 CPU 아이디어에 맞게 프로그램을 구성해야하는 이유는 무엇입니까? 컴퓨터 입찰을하지 말고 문제를 해결하려고합니다.
Joachim Sauer

8
편집 요약 : C 컴파일러를 사용할 수 있습니다.
Meinersbur

4
@Simon 아마도 몇 년이 지났을 지 모르지만 2010 년에 ASM과 "C와 같은 고급 언어"에 대해 토론하고 있다는 사실에 놀랐습니다. 특히 C가 고급 언어의 예인 경우
매트 b

11
@changelog : 그것은 programming.reddit.com의 철자가 아닙니다.
BoltClock

답변:


331

ASM은이 빈약 한 가독성을 하고 실제로 유지 보수가없는 높은 수준의 언어에 비해.

또한 C와 같이 널리 사용되는 다른 언어보다 ASM 개발자 수가 훨씬 적습니다 .

또한 고급 언어를 사용하고 새로운 ASM 명령어를 사용할 수있게 되면 (예 : SSE) 컴파일러를 업데이트하기 만하면 기존 코드에서 새 명령어를 쉽게 사용할 수 있습니다.

다음 CPU에 두 배의 레지스터가 있으면 어떻게됩니까?

이 질문의 반대는 다음과 같습니다. 컴파일러는 어떤 기능을 제공합니까?

ASM을 gcc -O3할 수있는 것보다 더 잘 최적화하고 싶거나 최적화해야한다고 의심합니다 .


10
gcc는 평균적인 인간보다 훨씬 나은 최적화는 아니지만 최적화 프로그램이 제대로 작동하지 않는 곳이 많이 있습니다. 그렇지 않으면 당신과 동의하십시오.
old_timer

4
@dwelch 아주 드문 경우이지만 gcc (또는 다른 많은 컴파일러)가 컴파일 된 C를 제대로 최적화하지 못하는 경우가 있습니다. 그러나 이러한 경우 항상 ASM에서 제한된 수의 프로 시저를 작성하고 빌드 중에 해당 메소드 만 연결할 수 있습니다.
cortijon

@Ben S : "much"는 단일 객체에만 사용되므로 처음에는 "much"가 아닌 "many"로 편집했습니다. "많은"의 대상은 복수형 (개발자)이므로 "많은"이 올바른 옵션입니다. 그러나 "많이"가 원하는 경우 답을 다시 편집하지 않습니다.
Billy ONeal

1
컴파일러가 제대로 최적화 할 수없는 경우가 많지만 최적화 프로그램의 한계를 알고있는 개발자는 어셈블리에 의존하지 않고 C 코드를 최적화 할 수 있습니다.
Qwertie

1
내 일에 FWIW 나는 gcc -g -O0으로 제품을 컴파일합니다 .gdb를 라이브 시스템에 연결할 수 있고 존재하지 않는 변수로 인해 화 내지 않기 때문에 더 많은 가치가 있습니다. 회사는 매일 40 억 개의 CPU 사이클을 유휴 상태로 두는 것 (총 3 조 개 중)입니다. 크 런칭 정수는 병목 현상이 자주 발생하지 않습니다.
Bernd Jendrissek

1930

Hell®, 저는 컴파일러입니다.

이 문장을 읽는 동안 방금 수천 줄의 코드를 스캔했습니다. 수년간의 연구에 기초한 방대한 양의 학술 연구를 기반으로 수백 가지의 다양한 최적화 기술을 사용하여 한 줄의 광고를 최적화 할 수있는 가능성을 탐색했습니다. 3 줄 루프를 수천 개의 명령으로 변환하면 속도가 빨라져 약간의 당혹감도 느끼지 않습니다. 나는 많은 시간 동안 최적화를하거나 가장 더러운 트릭을하는 것이 부끄러운 일이 아닙니다. 그리고 하루나 이틀 정도 날 원하지 않는다면, 내가 원하는대로 행동하고 할 것입니다. 한 줄의 코드를 변경하지 않고도 원하는 때마다 사용중인 메소드를 변환 할 수 있습니다. 코드가 어셈블리에서 어떻게 보이는지 보여줄 수도 있습니다. 다른 프로세서 아키텍처와 운영 체제 및 원하는 경우 다른 어셈블리 규칙에 따라 네, 몇 초만에요. 알다시피, 나는 할 수 있습니다. 알다시피 할 수 없습니다.

PS Oh, 그런데 당신이 작성한 코드의 절반을 사용하지 않았습니다. 나는 당신에게 호의를 베 풀었습니다.


99

6502, Z80, 6809 및 8086 칩에 대한 어셈블러 헛간을 작성했습니다. 내가 다루는 플랫폼에서 C 컴파일러를 사용할 수있게 되 자마자 그만 두었고 즉시 생산성이 10 배 이상 높아졌습니다. 대부분의 훌륭한 프로그래머는 합리적인 이유로 사용하는 도구를 사용합니다.


72

어셈블리 언어로 프로그래밍하는 것을 좋아하지만 고급 언어와 동일한 작업을 수행하려면 더 많은 코드가 필요하며 코드 줄과 버그 사이에는 직접적인 상관 관계가 있습니다. (이것은 수십 년 전에 The Mythical Man-Month 에서 설명되었습니다 .)

C를 '고수준 어셈블리'라고 생각할 수 있지만 그보다 몇 단계 앞서서 다른 세상에 있습니다. C #에서는 이것을 쓰는 것에 대해 두 번 생각하지 않습니다.

foreach (string s in listOfStrings) { /* do stuff */ }

이것은 어셈블리에 수십 줄, 수백 줄의 코드가있을 것입니다. 각 프로그래머는 다른 접근 방식을 취해야하며 다음 사람이 알아낼 것입니다. 따라서 많은 사람들이 다른 사람들이 읽을 수 있도록 프로그램이 작성되었다고 생각한다면 어셈블리는 일반적인 HLL보다 읽기 어렵습니다.

편집 : 나는 일반적인 작업에 사용되는 개인 코드 라이브러리와 C와 같은 제어 구조를 구현하기위한 매크로를 축적했습니다. 그러나 나는 GUI가 표준이 된 90 년대에 벽을 쳤다. 일상적인 일에 너무 많은 시간이 소비되었습니다.

ASM이 필요한 곳에서 마지막으로 수행 한 작업은 몇 년 전에 맬웨어를 퇴치하는 코드를 작성하는 것이 었습니다. 사용자 인터페이스가 없으므로 팽창이없는 재미있는 부분이었습니다.


확실합니까? 코드 컴플리트에서 읽은 것이 기억 나지 않는 것 같습니다.
jcolebrand

1
나는 '더 적은 라인'의 장점이 '조기 최적화'단점에 의해 극복되는 지점이 있다고 확신합니다. 그러나 나는 나이에 코드 완성을
보지 못했습니다

6
A는 인수로 "조기 최적화"를 사용하는 것이 아이러니 비트 에 대한 ... 조립 (하지만 아마 당신을 잘못 해석 나는 여전히 재미 생각합니다..)
베른트 Jendrissek에게

여전히 어셈블러에서 함수를 호출 할 수 있으므로 foreach-loop에는 수십에서 수백 줄이 걸릴 것으로 의심됩니다. 아니면 내가 무엇을 놓치고 있습니까?
Sebastian Mach

@phresnel : foreach보다 더 많은 작업을 수행합니다 for-유형별 반복자를 인스턴스화하고 사용합니다.
egrunin

15

가독성, 유지 보수성, 코드 단축 및 버그 감소에 대한 다른 사람들의 답변 외에도 훨씬 쉬운 이유를 추가 할 것입니다.

프로그램 속도.

그렇습니다. 어셈블리에서는 코드를 수동으로 조정하여 모든 마지막주기를 사용하고 실제로 가능한 한 빨리 코드를 만들 수 있습니다. 그러나 누가 시간이 있습니까? 완벽하게 바보가 아닌 C 프로그램을 작성하는 경우 컴파일러는 최적화를 위해 정말 훌륭한 작업을 수행합니다. 아마도 추적을 걱정할 필요없이 수작업으로 수행 한 최적화의 최소 95 %를 수행 할 수 있습니다. 여기에 90/10 종류의 규칙이 있습니다. 최종 5 %의 최적화가 결국 95 %의 시간을 차지하게됩니다. 왜 귀찮게?


4
+1. 어셈블러 코드 작성과 빠른 어셈블러 코드 작성 은 서로 다른 두 가지입니다. 좋은 컴파일러를 사용하면 빠른 어셈블러 코드가 무료로 제공됩니다.
Niki

컴파일러를 사용하는 방법을 알고, 대부분 최적화를 사용하지 않고, 대부분의 사람들이 디버그 옵션으로 컴파일하면 결과적으로 느린 어셈블러가 제대로 수행되지 않는 경우에만 빠른 어셈블러 코드를 무료로 얻을 수 있습니다. 그렇습니다. 터치해서는 안되는 시간의 99 % 이상, 컴파일러 노브를 터치하고 출력을 직접 조정하지 마십시오.
old_timer

최적화에 관심이 있다면 컴파일러에서 수행해야합니다 ... 최적화에 관심이 없지만 여전히 어셈블리를 사용하고 있다면 어리석은 것입니다.
Brian Postow

@ dwelch : 도구 사용법을 알지 못하는 스크립트 학습자가있을 수 있습니다. 그러나 나는 그들과 같은 사람들이 빠른 어셈블러 코드를 작성할 수 있을지 의심합니다.
Niki

13

평균 생산 프로그램에서 100k 라인의 코드를 말하고 각 라인이 약 8-12 개의 어셈블러 명령어라면, 이는 백만 개의 어셈블러 명령어입니다.

이 모든 것을 적절한 속도로 직접 작성할 수 있다고해도 (작성해야하는 코드의 8 배 더 많은 코드를 기억하십시오), 일부 기능을 변경하려면 어떻게됩니까? 백만 개의 지침 중 몇 주 전에 작성한 것을 이해하는 것은 악몽입니다! 모듈, 클래스, 객체 지향 디자인, 프레임 워크, 아무것도 없습니다. 그리고 가장 간단한 것조차도 작성해야하는 유사한 코드의 양이 가장 어려울 것입니다.

게다가 코드를 거의 고수준 언어로 최적화 할 수 없습니다. 예를 들어 C가 코드뿐만 아니라 의도 를 설명 하기 때문에 엄청난 수의 최적화를 수행하는 경우 어셈블러에서 코드를 작성하는 경우 어셈블러는 실제로 코드에서 주목할만한 최적화를 수행 할 수 없습니다. 당신이 쓰는 것은 당신이 얻는 것입니다, 그리고 나를 믿으십시오, 당신은 당신이 그것을 작성할 때 패치하고 패치하는 백만 개의 지침을 안정적으로 최적화 할 수 없습니다.


8

글쎄, 나는 "구시대에"많은 어셈블리를 작성해 왔으며, 고급 언어로 프로그램을 작성할 때 훨씬 더 생산적임을 확신 할 수 있습니다.


8
"어셈블리는 라틴어입니다."
Adriano Varoli Piazza

4
@ Adriano : 많은 다른 방언이 있으며 두 개는 비슷하게 보이지 않습니다.
Joachim Sauer

1
물론, 그중 하나에서 프로그래밍하는 법을 배우면 더 높은 수준에서 도움이되는 기계의 아키텍처에 대한 통찰력을 얻을 수 있습니다. 페이징 된 메모리를 다루지 않는 한,이 경우 흉터가 생깁니다. Catullus에서 Carmen 16을 읽는 것과 같습니다.
Adriano Varoli Piazza

5
@Adriano "어셈블리는 라틴어", 아니 asm은 원시인의 grunts입니다. 바위에 대한 하나의 grunt 사슴에 대한 2grunts, 화재에 대한 3grunts-간단한 물건에는 좋지만 제국을 운영하기는 어렵습니다.
Martin Beckett

1
@Martin : 로마 숫자로 복잡한 산술을 시도한 적이 있습니까?
Adriano Varoli Piazza

6

어셈블러 능력의 합리적인 수준은, 어떤 시스템 레벨의 종류 또는 임베디드 프로그래밍에서 일하는 특히 유용한 기술이다 순전히 당신이 그렇게 많은 어셈블러를 작성해야하지만, 때로는 있기 때문에 상자가 무엇인지 이해하는 것이 중요하기 때문에 정말 일 . 어셈블러 개념 및 문제에 대한 수준의 이해가 없으면 매우 어려울 수 있습니다.

그러나 실제로 어셈블러에서 많은 코드를 작성하는 경우 크게 수행되지 않은 몇 가지 이유가 있습니다.

  • 단순히 (거의) 필요가 없습니다. 초창기 시스템 초기화 및 C 함수 또는 매크로에 숨겨진 몇 개의 어셈블러 조각을 제외하고 한 번 어셈블러로 작성된 매우 낮은 수준의 코드는 모두 어려움없이 C 또는 C ++로 작성할 수 있습니다.

  • 고급 언어 (C 및 C ++ 포함)의 코드는 기능을 훨씬 적은 행으로 압축하며 버그 수는 소스 코드 행 수와 상관 관계가 있음을 보여주는 상당한 연구가 있습니다. 즉, 어셈블러와 C에서 해결 된 동일한 문제는 단순히 더 길기 때문에 어셈블러에서 더 많은 버그를 갖게됩니다. 같은 주장은 Perl, Python 등과 같은 고급 언어로의 전환을 유발합니다.

  • 어셈블러로 작성하면 세부적인 메모리 레이아웃, 명령어 선택, 알고리즘 선택, 스택 관리 등 문제의 모든 측면을 처리해야합니다. 고급 언어는이 모든 것을 제거합니다. LOC의 조건.

기본적으로 위의 모든 내용은 C 또는 다른 언어와 비교하여 어셈블러에서 사용할 수있는 추상화 수준과 관련이 있습니다. 어셈블러는 C와 같은 중급 언어, 특히 고급 언어가 기본적으로 제공되는 추상화를 제공하는 자체 학습을 통해 모든 추상화를 작성하고 유지하도록합니다. 비교적 쉽게 새로운 것을 만들 수 있습니다.


6

임베디드 프로그래밍 세계에서 대부분의 시간을 보내는 개발자는 어셈블리가 죽거나 쓸모없는 언어와 거리가 멀다고 주장합니다. 높은 수준의 언어로 정확하거나 효율적으로 표현할 수없는 특정 금속 수준에 가까운 코딩 수준 (예 : 드라이버)이 있습니다. 우리는 거의 모든 하드웨어 인터페이스 루틴을 어셈블러로 작성합니다.

즉,이 어셈블리 코드는 C 코드에서 호출 될 수 있도록 랩핑되며 라이브러리처럼 취급됩니다. 우리는 여러 가지 이유로 전체 프로그램을 어셈블리로 작성하지 않습니다. 가장 중요한 것은 이식성입니다. 우리의 코드 기반은 서로 다른 아키텍처를 사용하는 여러 제품에 사용되며 이들 사이에서 공유 할 수있는 코드의 양을 최대화하려고합니다. 두 번째는 개발자의 친숙 함입니다. 간단히 말해 학교는 예전처럼 어셈블리를 가르치지 않으며 개발자는 어셈블리보다 C에서 훨씬 더 생산적입니다. 또한 어셈블리 언어 코드로는 사용할 수없는 C 코드에 사용할 수있는 다양한 "extras"(라이브러리, 디버거, 정적 분석 도구 등)가 있습니다. 순 조립 프로그램을 작성하고 싶더라도 몇 가지 중요한 하드웨어 라이브러리는 C 라이브러리로만 사용할 수 있기 때문에 불가능합니다. 어떤 의미에서, 그것은 닭 / 계란 문제입니다. 라이브러리와 개발 / 디버그 도구가 많지 않기 때문에 사람들은 어셈블리에서 멀어 지지만, 어셈블리를 사용하는 사람들이 충분하지 않기 때문에 libs / tools는 존재하지 않습니다.

결국, 거의 모든 언어를위한 시간과 장소가 있습니다. 사람들은 가장 친숙하고 생산적인 것을 사용합니다. 프로그래머의 레퍼토리에는 항상 어셈블리를위한 장소가있을 수 있지만 대부분의 프로그래머는 훨씬 짧은 시간에 거의 효율적인 고급 언어로 코드를 작성할 수 있습니다.


6

어셈블리로 작성하는 경우 명령 코드 만 작성하지 않아도됩니다. 매크로와 프로 시저 및 고유 한 규칙을 사용하여 다양한 추상화를 통해 프로그램을보다 모듈화되고 유지 보수 가능하며 읽기 쉽게 만들 수 있습니다.

따라서 기본적으로 말하는 것은 정교한 어셈블러를 능숙하게 사용하면 ASM 코드를 C (또는 어쨌든 자신의 발명품의 다른 저급 언어)에 더 가깝고 가깝게 만들 수 있다는 것입니다. C 프로그래머처럼 생산적입니다.

그 질문에 대답합니까? ;-)

나는 이것을 유쾌하게 말하지 않는다 : 나는 정확하게 그러한 어셈블러와 시스템을 사용하여 프로그래밍했다. 더 좋은 것은 어셈블러가 가상 프로세서를 대상으로 할 수 있고 별도의 변환기가 대상 플랫폼에 대한 어셈블러의 출력을 컴파일 한 것입니다. LLVM의 IF에서와 마찬가지로, 초기 형태로는 약 10 년 전입니다. 따라서 이식성과 효율성이 필요한 특정 대상 어셈블러에 대한 루틴을 작성하는 기능이 추가되었습니다.

이 어셈블러를 사용하여 작성하는 것은 C만큼이나 생산성이 높았으며 GCC-3과 비교했을 때 (내가 관여했을 때쯤 이었음) 어셈블러 / 번역기는 대략 빠르고 빠르고 작은 코드를 생성했습니다. 크기는 정말 중요했고 회사에는 프로그래머가 거의 없었으며 새로운 직원들에게 유용한 일을하기 전에 새로운 언어를 가르치려고했습니다. 또한 어셈블러 (예 : 고객)를 모르는 사람들이 C를 작성하고 동일한 호출 규칙 등을 사용하여 동일한 가상 프로세서에 대해 C를 컴파일하여 깔끔하게 인터페이스 할 수있는 백업을 제공했습니다. 그래서 그것은 한계 승리처럼 느꼈습니다.

그것은 어셈블러 기술, 라이브러리 등을 개발하는 백에서 수년간의 작업으로 이루어졌습니다. 하나의 아키텍처 만 대상으로 삼았다면 모든 것을 갖춘 모든 댄싱 어셈블러가 훨씬 쉬웠을 것입니다.

요약하면, C를 좋아하지 않을 수도 있지만 C를 사용하려는 노력이 더 좋은 것을 찾는 노력보다 크다는 것을 의미하지는 않습니다.


5

다른 마이크로 프로세서간에 어셈블리를 이식 ​​할 수 없습니다.


그것은 현대의 프로세서와 어셈블러 프로그램의 경우에는 사실이 아니며 C에서와 마찬가지로 다른 프로세서를 대상으로 할 수 있습니다.이 경우 전체 명령어 세트를 사용할 수는 없지만 쓰지 않아도됩니다. C.에서 이식성은 주요 관심사가 아닙니다.
Blindy

6
아마도 당신은 건축 을 의미 합니다 .
벤 S

2
@Blindy-x86 제품군 내에서 다른 프로세서를 대상으로 할 수 있지만 x86 변형과 ARM 프로세서 또는 Z80 또는 8051 사이의 어셈블리 명령어에는 공통점이 없습니다.
semaj

사실이지만 z에서 z80도 프로그래밍 할 수 없습니다. 우리 모두 여기서 일반적인 x86 / x64 프로세서에 대해 이야기하고 있다고 생각합니다.
Blindy

1
모든 세계가 x86이 아닙니다. "다른 마이크로 프로세서"에 대해서는 아무것도 동일한 명령어 세트를 실행한다고 제안하지 않습니다.
Bernd Jendrissek

5

우리가 더 이상 외부의 화장실에 가지 않는 것과 같은 이유, 또는 왜 라틴어 나 아람어를 말하지 않는가.

기술이 등장하여 더 쉽고 접근하기 쉽습니다.

편집-불쾌한 사람들을 멈추기 위해 특정 단어를 제거했습니다.


4
당신은 여전히 ​​Luddites라는 단어로 Technology
불쾌합니다

1
"우리"는 라틴어를 못해?
dank

라틴어 나 아람어는 더 나은 기술로 대체 되었기 때문에 사라지지 않았다 (즉, 배우기 쉬운 언어). 실제로 라틴어는 여전히 유럽 어디에서나 우리와 함께 있습니다. 모든 로마 언어는 라틴어를 기반으로합니다. 현대 (네오) 아람어는 오늘날 거의 50 만 명이 사용합니다. 이 언어들이 더 이상 널리 보급되지 않은 이유는 기술적 인 것이 아니라 역사적 (정치적,보다 정확한) 것이다. 영어가 우리 시대의 과학과 지배 계급의 링구아 프랑카 인 것과 같은 이유는 마지막 제국의 사람들 인 영국 (현재 미국계 미국인)이 그것을 말합니다.
리츠 12

4

왜? 단순한.

이것을 비교하십시오 :

        for (var i = 1; i <= 100; i++)
        {
            if (i % 3 == 0)
                Console.Write("Fizz");
            if (i % 5 == 0)
                Console.Write("Buzz");
            if (i % 3 != 0 && i % 5 != 0)
                Console.Write(i);
            Console.WriteLine();
        }

.locals init (
    [0] int32 i)
L_0000: ldc.i4.1 
L_0001: stloc.0 
L_0002: br.s L_003b
L_0004: ldloc.0 
L_0005: ldc.i4.3 
L_0006: rem 
L_0007: brtrue.s L_0013
L_0009: ldstr "Fizz"
L_000e: call void [mscorlib]System.Console::Write(string)
L_0013: ldloc.0 
L_0014: ldc.i4.5 
L_0015: rem 
L_0016: brtrue.s L_0022
L_0018: ldstr "Buzz"
L_001d: call void [mscorlib]System.Console::Write(string)
L_0022: ldloc.0 
L_0023: ldc.i4.3 
L_0024: rem 
L_0025: brfalse.s L_0032
L_0027: ldloc.0 
L_0028: ldc.i4.5 
L_0029: rem 
L_002a: brfalse.s L_0032
L_002c: ldloc.0 
L_002d: call void [mscorlib]System.Console::Write(int32)
L_0032: call void [mscorlib]System.Console::WriteLine()
L_0037: ldloc.0 
L_0038: ldc.i4.1 
L_0039: add 
L_003a: stloc.0 
L_003b: ldloc.0 
L_003c: ldc.i4.s 100
L_003e: ble.s L_0004
L_0040: ret 

기능면에서 동일합니다. 두 번째는 어셈블러가 아니라 .NET IL (Java의 바이트 코드와 유사한 중개 언어)입니다. 두 번째 컴파일은 IL을 원시 코드 (예 : 거의 어셈블러)로 변환하여 더욱 암호 적으로 만듭니다.


3

컴파일러가 최적화하기 어려운 명령어를 사용하여 많은 것을 얻는 경우에는 x86 (_64)에서도 ASM이 의미가 있다고 생각합니다. 예를 들어 x264는 인코딩에 많은 asm을 사용하며 속도 게인이 엄청납니다.


2

나는 많은 이유가 있다고 확신하지만, 내가 생각할 수있는 두 가지 빠른 이유는

  1. 어셈블리 코드는 확실히 읽기가 어렵습니다 (쓰기에 더 많은 시간이 소요됨)
  2. 제품을 개발하는 거대한 개발자 팀이있는 경우 코드를 논리적 블록으로 나누고 인터페이스로 보호하는 것이 좋습니다.

1
어셈블리를 논리 블록으로 분리 할 수도 있습니다.
Paul Williams

2

초기 발견 중 하나 ( 1960 년대의 경험에서 나온 Brooks의 Mythical Man-Month 에서 찾을 수 있음 )는 사람들이 매일 한 줄의 코드 라인에서 다른 언어만큼 생산성이 높았다는 것입니다. 이것은 보편적으로 사실이 아니며, 너무 멀리 밀면 깨질 수 있지만, 일반적으로 Brooks 시대의 고급 언어에는 해당됩니다.

따라서 생산성을 얻는 가장 빠른 방법은 하나의 개별 코드 행이 더 많은 언어를 사용하는 것이며 실제로는 FORTRAN 및 COBOL과 같은 복잡한 언어에 대해 작동하거나보다 현대적인 예제 C를 제공하는 것입니다.


2

이식성은 항상 문제입니다. 지금은 아니더라도 적어도 결국은 문제입니다. 프로그래밍 산업은 오래된 소프트웨어를 포팅하는 데 매년 수십억 달러를 소비하는데,이 소프트웨어는 당시에는 이식성 문제가 전혀 없었습니다.


2
"다른 아키텍처로 포팅 할 필요가 없습니다." "연도에 두 자리 이상이 필요하지 않습니다."
David Thornley

아니면 Windows가 내년에 없을 수 있기 때문에 C #을 사용할 수 없습니까?
Martin Beckett

예를 들어 Motorola MC68000 시리즈 프로세서, PowerPC (IBM 등) 및 현재 Intel x86 (IA-32 (e)) 프로세서를 기반으로하는 Apple의 MacIntosh 컴퓨터 따라서, 이식성은 오랫동안 사용 된 모든 시스템에서 문제가되며, 예상보다 오래 지속되는 코드에 물린 적이없는 프로그래머는 아직 경험이 없습니다.
mctylr

@Martin : 20 년이 지난 지금, 사람들이 실행하고자하는 C # 프로그램이 많으므로 C # 프로그램을 컴파일하고 실행하는 방법이있을 것입니다. C #에 대해서는 본질적으로 고정되어있는 것이 없지만 20 년이 지난 지금도 여전히 인기가 있다면 놀랐습니다. 그러나 20 년 안에 우리의 CPU는 상당히 다를 것입니다. 1990 년에 작성된 어셈블러 프로그램은 현재 잘 작동 할 수 있지만 최적의 것은 아니며 컴파일 된 C보다 느리게 실행될 것입니다.
David Thornley

x86의 지침이 변경 되었기 때문에 6 개월 전보다 높은 수준의 프레임 워크가 변경 되었기 때문에 포팅 문제가 훨씬 많았습니다. 특히 xcode의 지침이 변경 되었기 때문에 특히 손으로 코딩 한 asm이 가장 간단한 방법을 고수하기 때문입니다.
Martin Beckett

2

어셈블리가 덜 보편적이되면서 악순환이있었습니다. 고급 언어가 성숙함에 따라 어셈블리 언어 명령어 세트는 프로그래머 편의와 컴파일러의 편의를 위해 더 적게 구축되었습니다.

따라서 현실적으로는 어떤 레지스터를 사용해야하는지 또는 어떤 명령어가 약간 더 효율적인지에 대한 올바른 결정을 내리기가 매우 어려울 수 있습니다. 컴파일러는 휴리스틱을 사용하여 어떤 보상이 최상의 보상을받을 가능성이 있는지 파악할 수 있습니다. 우리는 아마도 작은 문제를 통해 생각할 수 있고 현재 매우 정교한 컴파일러를 능가하는 로컬 최적화를 찾을 수 있지만, 보통은 좋은 컴파일러가 좋은 프로그래머가하는 것보다 첫 번째 시도에서 더 나은 작업을 수행 할 가능성이 높습니다. 결국 존 헨리처럼 우리는 기계를 이길 수 있지만, 우리는 그곳에 도착하는 것을 심각하게 태워 버릴 수 있습니다.

우리의 문제는 지금도 상당히 다릅니다. 1986 년에 화면에 몇 백 픽셀을 넣는 작은 프로그램에서 속도를 높이는 방법을 알아 내려고 노력했습니다. 애니메이션이 덜 흔들 리기를 원했습니다. 어셈블리 언어에 대한 적절한 사례. 이제는 계약 언어 및 모기지 서비스 정책에 대한 추상화를 표현하는 방법을 알아 내려고 노력하고 있으며 비즈니스 사람들이 말하는 언어와 비슷한 것을 읽으려고합니다. LISP 매크로와 달리 어셈블리 매크로는 규칙을 많이 적용하지 않으므로 좋은 어셈블러에서 DSL에 합리적으로 가까운 것을 얻을 수는 있지만 모든 종류의 쿼크가 발생하기 쉽습니다. Ruby, Boo, Lisp, C # 또는 F #으로 동일한 코드를 작성하면 문제가 발생하지 않습니다.

그러나 효율적인 어셈블리 언어로 문제를 쉽게 표현할 수 있다면 더 많은 힘을 얻을 수 있습니다.


2

다른 사람들이 말한 대부분의 내용을 이해하십시오.

C가 발명되기 전의 좋은 시절에는 유일한 고급 언어가 COBOL 및 FORTRAN과 같은 것이었을 때 어셈블러에 의지하지 않고는 할 수 없었던 많은 것들이있었습니다. 유연성을 최대한 활용하고 모든 장치에 액세스 할 수있는 유일한 방법이었습니다. 그러나 C가 발명되었고 조립에서 가능한 거의 모든 것이 C에서 가능했습니다. 그때.

즉, 새로운 프로그래머가 어셈블러로 작성하는 것을 배우는 것이 매우 유용한 연습이라고 생각합니다. 실제로 사용하기 때문이 아니라 컴퓨터 내부에서 실제로 일어나는 일을 이해하기 때문입니다. 비트와 바이트 및 레지스터에서 실제로 무슨 일이 일어나고 있는지 전혀 모르는 프로그래머의 많은 프로그래밍 오류와 비효율적 인 코드를 보았습니다.


예, 알아봐 몇 년 전 IBM 메인 프레임의 Fortran 디스크 및 테이프 I / O는 쓸모가 없었으므로 370 / 어셈블러에서 자체 I / O 루틴을 작성하여 Fortan IV 코드에서 호출했습니다. 어셈블리 코드를 작성하면 기본 아키텍처를 실제로 이해할 수있었습니다. 나는 지금까지 몇 년 동안 어셈블리 코드를 작성하지 않았으며 함께 일하는 모든 젊은이들은 아무 것도 쓰지 않았습니다.
사이먼 나이츠

2

나는 약 한 달 동안 지금 어셈블리로 프로그래밍했습니다. 나는 종종 C로 코드 조각을 작성한 다음 그것을 돕기 위해 어셈블리로 컴파일합니다. 아마도 C 컴파일러의 전체 최적화 기능을 사용하고 있지는 않지만 C asm 소스에 불필요한 작업이 포함되어있는 것 같습니다. 그래서 좋은 어셈블리 코더보다 우수한 C 컴파일러의 이야기가 항상 진실한 것은 아니라는 것을 알기 시작했습니다.

어쨌든 내 어셈블리 프로그램은 너무 빠릅니다. 그리고 어셈블리를 많이 사용할수록 코드를 작성하는 데 걸리는 시간이 줄어 듭니다. 실제로 그렇게 어렵지는 않습니다. 또한 가독성이 좋지 않은 조립품에 대한 의견은 사실이 아닙니다. 프로그램에 올바르게 레이블을 지정하고 추가 설명이 필요할 때 주석을 달면 모두 설정해야합니다. 실제로 어셈블리 수준은 프로세서 수준에서 무슨 일이 일어나고 있는지 알기 때문에 프로그래머에게는 더 명확합니다. 나는 다른 프로그래머들에 대해 모른다. 그러나 나는 일종의 블랙 박스에있는 것보다는 무슨 일이 일어나고 있는지를 알고 싶다.

컴파일러의 실제 장점은 컴파일러가 패턴과 관계를 이해 한 다음 소스의 적절한 위치에서 자동으로 코딩 할 수 있다는 것입니다. 널리 사용되는 한 가지 예는 컴파일러에서 함수 포인터를 최적으로 매핑해야하는 C ++의 가상 함수입니다. 그러나 컴파일러는 컴파일러 제작자가 컴파일러가 허용하는 작업을 수행하는 것으로 제한됩니다. 이로 인해 프로그래머는 때때로 코드를 사용하여 기괴한 작업을 수행하여 어셈블리로 사소하게 수행 할 수있을 때 코딩 시간을 추가해야합니다.

개인적으로 저는 시장이 높은 수준의 언어를 많이 지원한다고 생각합니다. 오늘날 어셈블리 언어가 유일하게 존재하는 언어라면, 프로그래밍 언어가 약 70 % 줄어들고 90 년대에 우리의 세계가 어디에 있는지 알고있을 것입니다. 더 높은 수준의 언어는 더 넓은 범위의 사람들에게 어필합니다. 이를 통해 더 많은 프로그래머가 세계의 필요한 인프라를 구축 할 수 있습니다. 중국과 인도와 같은 개발 도상국은 Java와 같은 언어의 혜택을 많이받습니다. 이 국가들은 IT 인프라를 빠르게 개발할 것이며 사람들은 더욱 상호 연결될 것입니다. 제 요점은 고급 언어는 우수한 코드를 생산하는 것이 아니라 세계 시장에서 수요를 충족시키는 데 도움이되기 때문에 인기가 있다는 것입니다.


블랙 박스에 +1. 그렇습니다, 우리는 블랙 박스를 사용하고 있으며, 블랙 박스를 들여다 볼 수있는 방법이 없습니다 (너무 쉽습니다). C # foreach는 실제로 어떻게 작동합니까? 누가 알아. 마이크로 소프트는 완벽하다고 말했다. 그렇다면 그렇습니다.
ern0

또한 '고급 언어'를 사용하면 실제 세계에서 중요한 다른 많은 것들이 있다는 것을 잊지 마십시오. C에는 표준 라이브러리 (수학, 문자열 처리, I / O 등)가 포함되어 있으며 Java와 같은 무거운 구성 요소에는 연결, 이미지 처리, 데이터 처리, 웹 개발 등을위한 다른 패키지 및 라이브러리가 많이 있습니다. 시간을 사용하여 하나의 플랫폼에서 높은 성능을 발휘하는 1 개의 세부 작업 (따라서 어셈블리 사용)에 집중하는 데 비해 버그를 최소화하면서 여러 플랫폼에서 실행 훨씬 더 큰 작업을 수행하는 .
jbx

1

저는 지금 comporg에서 어셈블리를 배우고 있으며 흥미롭지 만 글을 쓰는 것도 매우 비효율적입니다. 일을하려면 머리에 더 많은 세부 사항을 유지해야하며, 일을 더 느리게 작성해야합니다. . 예를 들어, C ++의 간단한 6 줄 for 루프는 18 줄 이상의 어셈블리와 같을 수 있습니다.

개인적으로, 하드웨어 수준에서 일이 어떻게 작동하는지 배우는 재미가 많으며 컴퓨팅 작동 방식에 대해 크게 감사드립니다.


1

C가 좋은 매크로 어셈블러를 능가하는 것은 언어 C입니다. 타입 검사. 루프 구문. 자동 스택 관리. (거의) 자동 변수 관리. 어셈블러의 동적 메모리 기술은 엉덩이에 엄청난 고통입니다. 링크 된 목록을 올바르게 수행하는 것은 C에 비해 겁이 나거나 foo.insert ()를 나열하는 것이 좋습니다. 그리고 디버깅-더 쉬운 디버깅에 대한 경쟁은 없습니다. HLL은 거기에서 손을 이깁니다.

어셈블러에서 경력의 거의 절반을 코딩하여 어셈블러에서 생각하기가 매우 쉽습니다. 그것은 C 컴파일러가 무엇을하고 있는지 알 수있게 해주고, C 컴파일러가 효율적으로 처리 할 수있는 코드를 작성하는데 도움이됩니다. C로 작성된 잘 알려진 루틴은 약간의 작업으로 원하는 것을 정확하게 출력하도록 작성 될 수 있으며 이식성이 뛰어납니다! 크로스 플랫폼 이유로 인해 몇 가지 오래된 asm 루틴을 C로 다시 작성해야했지만 재미가 없습니다.

아니요, C를 고수하고 HLL로 얻는 생산성 시간에 비해 가끔씩 성능이 약간 저하되는 문제를 해결합니다.


1

왜 내가 개인적으로 프로그램을 더 자주 집필하지 않는지에 대해서만 대답 할 수 있으며, 주된 이유는 더 지루 하기 때문입니다. 또한 나는 그것이 즉시 눈치 채지 않고 미묘하게 잘못하는 더 쉽다고 합니다. 예를 들어, 한 루틴에서 레지스터 사용 방식을 변경할 수 있지만 한 곳에서 변경하는 것을 잊어 버릴 수 있습니다. 잘 조립되며 나중에까지 눈치 채지 못할 수도 있습니다.

즉, 여전히 어셈블리에 유효한 용도가 있다고 생각합니다. 예를 들어, SIMD를 사용하고 편집증 "모든 비트가 성스러운"[quote V.Stob] 접근 방식에 따라 대량의 데이터를 처리하기 위해 상당히 최적화 된 여러 어셈블리 루틴이 있습니다. 그러나 순진한 어셈블리 구현은 종종 컴파일러가 생성하는 것보다 훨씬 나쁩니다.


1

C는 매크로 어셈블러입니다! 그리고 그것은 최고입니다!

그것은 어셈블리가 할 수있는 거의 모든 것을 할 수 있고, 이식 가능하며, 드물게 임베디드 어셈블리 코드를 사용할 수없는 경우가 대부분입니다. 이렇게하면 어셈블리에서 작성해야하는 프로그램의 일부만 남게됩니다.

더 높은 수준의 추상화와 이식성으로 인해 대부분의 사람들이 C로 시스템 소프트웨어를 작성하는 것이 더 가치가 있습니다. 또한 일부 프로그램을 작성하는 데 많은 시간과 돈을 투자하면 자신을 제한하고 싶지 않을 수도 있습니다. 앞으로 사용할 수있게 될 것입니다.


1

사람들은 다른 방향도 있다는 것을 잊는 것 같습니다.

처음에 어셈블러로 글을 쓰는 이유는 무엇입니까? 프로그램을 진정으로 저수준 언어로 작성해보십시오.

대신에

mov eax, 0x123
add eax, 0x456
push eax
call printInt

당신은뿐만 아니라 쓸 수

B823010000
0556040000
50 
FF15.....

너무 많은 장점을 , 프로그램의 정확한 크기를 알고 있습니다. 명령 값을 다른 명령의 입력으로 재사용 할 수 있으며 그것을 작성하는 어셈블러조차 필요하지 않습니다. 텍스트 편집기를 사용할 수 있습니다 ...

그리고 당신이 여전히 이것에 대해 어셈블러를 선호하는 이유는 다른 사람들이 C를 선호하는 이유입니다.


0

항상 그런식이 기 때문에 : 시간 경과와 좋은 것들도 사라집니다 :(

그러나 asm 코드를 작성할 때는 생산성이 훨씬 낮다는 것을 알지만 고급 랭을 코딩 할 때와는 전혀 다른 느낌입니다. 마치 마치 화가 인 것 같습니다. 당신은 원하는대로 마음대로 원하는 것을 자유롭게 그릴 수 있습니다. 이 언어가 사라지는 것은 유감입니다. 그러나 누군가는 여전히 그것을 기억하고 코딩하지만 결코 죽지 않을 것입니다!


진실. 반면에, 계산원과 슈퍼마켓이 수표를 현금으로 바꾸지 않을 때 경험하는 굴욕이 있습니다.
Jay

0

$$$

회사는 개발자를 고용하여 코드를 $$$로 전환합니다. 유용 할수록 빠를수록 코드를 생성 할 수 있으며, 빠른 회사는 $ $ $에 해당 코드를 설정할 수 있습니다.

높은 수준의 언어는 일반적으로 많은 양의 유용한 코드를 생성하는 데 더 좋습니다. 이것은 집회에 그 자리가 없다고 말하는 것은 아닙니다. 왜냐하면 다른 일이 없을 시간과 장소가 있기 때문입니다.


0

HLL의 장점은 어셈블리를 C보다 높은 수준의 언어 (예 : Java, Python 또는 Ruby)와 비교할 때 훨씬 더 큽니다. 예를 들어, 이러한 언어에는 가비지 콜렉션이 있습니다. 메모리 청크 해제시기에 대해 걱정할 필요가없고 너무 일찍 해제되어 메모리 누수 나 버그가 발생하지 않습니다.


0

다른 사람들이 언급했듯이 도구가 존재하는 이유는 도구가 얼마나 효율적으로 작동하는지입니다. HLL이 많은 asm 코드와 동일한 작업을 수행 할 수 있으므로 다른 언어로 어셈블리를 대체하는 것이 당연하다고 생각합니다. 하드웨어와의 근접성을 위해 C 언어와 언어별로 인라인 어셈블리가 있습니다. Dr. Paul Carter의 PC 어셈블리 언어에서

"... 파스칼과 같은 프로그래밍 언어에서보다 컴퓨터가 실제로 어떻게 작동하는지 더 잘 이해합니다. 컴퓨터가 어떻게 작동하는지에 대한 심층적 인 이해를 통해 독자는 종종 C와 같은 고급 언어로 소프트웨어를 훨씬 더 생산적으로 개발할 수 있습니다 C ++. 어셈블리 언어로 프로그래밍하는 법을 배우는 것이이 목표를 달성하는 훌륭한 방법입니다. "

대학 과정에서 집회를 소개합니다. 개념을 명확하게하는 데 도움이됩니다. 그러나 우리 중 누군가가 어셈블리에 코드의 90 %를 쓰지 않을 것입니다. 오늘날 심도있는 어셈블리 지식은 얼마나 관련이 있습니까?


-2

이 답변을 뒤집어 놓으면 9/10의 응답자가 어셈블리 작업을 한 적이 없습니다.

이것은 자주 제기되는 오래된 질문이며 대부분 틀린 정답과 동일합니다. 이식성이 없다면 어셈블리의 모든 것을 직접 수행 할 것입니다. 그럼에도 불구하고 어셈블리에서했던 것처럼 C로 코딩합니다.


1
+1은 asm 경험이없는 사람들을 언급하고 +1은 "asm과 같은 C 코딩"을해야합니다. 임베디드 용 C ++ (예, CPP, C가 아닌) 앱을 작성할 때 new / malloc ()을 전혀 사용하지 않는 것처럼 asm처럼 코딩하고 있습니다.
ern0

따라서 char buf [MAX_PATH]와 같은 많은 것을 사용하면 누군가 MAX_PATH + n 크기의 데이터를 가질 때 쓰러지나요? ;)
paulm 2013

1
@ paulm-당신은 C와 같은 의미입니까?
Rob

1
어셈블러 작성자는 malloc () 사용을 피하지 않기를 바랍니다. 예, 임베디드에는 메모리가 제한되어 있습니다. 그러나 Unix 또는 다른 데스크탑 (또는 대부분의 모바일 OS)에서 그렇게하면 불필요하게 자신과 사용자를 제한하고 있습니다. 또한 : LOC가 적을수록 실수의 가능성이 적으므로 높은 수준의 코드는 낮은 것보다 오류가 적습니다.
uliwitness

1
내가 의심 스러웠던 원인을 보았을 것입니다. 그래도 레디 터와 HNers가 여기 있다고 말할 수 있습니다.
Rob
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.