조립시 연습 문제를 해결해야합니까? [닫은]


9

나는 프로젝트 오일러 문제 48을 보고 있었다 :

시리즈, 1 1 + 2 2 + 3 3 + ... + 10 10 = 10405071317.

계열의 마지막 10 자리를 찾으십시오 (1 1 + 2 2 + 3 3 + ... + 1000 1000) .

파이썬에서는 한 줄 로이 작업을 수행 할 수 있습니다.

sum((x**x for x in xrange(1,1001))

그러나 이것과 동등한 어셈블리는 100 줄과 진정한 도전이 될 것입니다.

저수준 프로그래밍에 대한 통찰력을 얻고 컴퓨터가 실제로 어떻게 작동하는지 이해하기 위해이 퍼즐을 조립해야합니까?


2
메모리가 어떻게 작동하는지 모르는 경우 포인터와 같은 주제를 어떻게 다룰 수 있습니까? 컴퓨터와 운영 체제의 작동 방식을 이해하지 못하면 응용 프로그램을 어떻게 프로그래밍 할 수 있습니까?
Ramhound

나는 많은 추상화를 할 수있다. Ramhound 그 이유는 내가 당신에게 이것을 물었다. 포인터가 다른 데이터 유형의 메모리 위치를 저장한다고 가정하면 논리적으로 의미가있는 스와핑과 같은 포인터에서 무언가를 수행 할 수있는 포인터의 완전한 중단을 얻지 못할 수도 있습니다. 내가 읽어야 할 주제? 어셈블리 언어와 약간의 COA가 좋을까요?
Nishant

포인터가 완전히 걸리지 않으면 일부 위치에서 심각한 단점이 있음을 알 수 있습니다.
David Thornley

3
파이썬 라인은 1..1000에서 x에 대해 x ^ 2를 1..1000으로 계산하거나 (1..1000에서 x에 대해 x ^ x 대신) 파이썬은 생각보다 훨씬 마술입니다. :)
Ingo

*파이썬에서 "power of power of"기능 이 있습니까?

답변:


1

학습 어셈블리 외에도 C와 같은 저수준 언어가 어떻게 컴파일되는지 배우는 것이 매우 가치 있다고 생각합니다. 내 대답은 그렇습니다.하지만 저수준 프로그래밍을 즐기기 때문에 아마도 편향적입니다.

예를 들어, 간단한 문장이 어떻게 컴파일되는지 이해하십시오. 다음 기능

int func(int val)
{
  int num = val * 5;
  return num;
}

... (최소한 흥미로운 부분이 됨) :

movl    %edi, -20(%rbp)
movl    -20(%rbp), %edx
movl    %edx, %eax
sall    $2, %eax
addl    %edx, %eax

이 코드는 스택 (val, 매개 변수를 func으로)에서 인수를 가져 와서 왼쪽 2 자리 (2 ^ 2 또는 4를 곱한 값)만큼 이동 한 다음 원래 값을 결과에 추가합니다. 최종 결과는 5를 곱한 것입니다. 이와 같은 예는 컴파일러 최적화와 같이 알아야 할 많은 사항을 보여줍니다. 직접 5를 곱하는 명령어를 호출하는 대신 두 자리를 4로 곱한 다음 원래 값을 더합니다. 더 낮은 수준에서 사물에 대한 이해를 크게 향상시키기 위해 이와 같은 예를 찾았습니다.

-S옵션을 사용하여 gcc에서 어셈블러 출력을 생성하십시오 . 그러나 결과는 컴파일러 및 최적화 수준에 따라 달라질 수 있습니다.

어쨌든, 나는 어셈블리 언어 프로그래머어셈블리이해 하는 것과 같지 않다고 생각 합니다. 다시 한 번 C와 같은 언어로 프로그래밍하고 그것이 어떻게 기계 코드에 삽입되는지를 아는 것이 귀중한 방법이라고 생각합니다.


11

실제로 어셈블러를 작성할 수있을 필요는 없습니다 (대부분 시스템의 초기화 및 호출 규칙에 대한 세부 사항).

소스없이 무언가를 디버깅하려고하는 경우를 대비하여 일부를 이해할 가치가 있습니다.

그러나 최소한 'C'레벨과 포인터 (본질적으로 높은 수준의 어셈블러) 수준에서 기계를 이해하면 루프에서 백만 번 문자열을 연결하는 것이 왜 나쁜지 알 수 있습니다.


실제로, 비교적 영리한 일부 구현은 for i in range(1000000): s = s + '.'재사용하는 "최적화 된"버전보다 훨씬 나쁘지 않을 수 있습니다 s. 마찬가지로, 여러 다른 개발은 C 지식에 대한 합리적인 가정을 무효화하고 순진한 구현을 가정합니다. 그러나 일반적으로 해로운 것보다 유용합니다. 언어 구현이 때때로 당신보다 똑똑하다는 것을 명심하십시오.)

2
@delnan-Java / C #에서 무해한 것이 실리콘에서 매우 비쌀 수있는 간단한 예가 필요했습니다. 특히 대용량 메모리 할당 및 복사가 즉각적이라고 생각하는 많은 사람들을 만났습니다.
Martin Beckett

나는 delnan :-)
Nishant

5

좋은 질문. 학습 어셈블리 는 확실히 훌륭하고 노력할 가치가 있습니다.

  1. 이러한 낮은 수준의 이해는 임베디드 소프트웨어 개발에 유용하게 사용될 것입니다
  2. 낮은 수준의 리팩토링
  3. 효과적으로 디버거를 활용하는 데 도움이됩니다
  4. 코드 동굴 과 같은 것들을 돕기 위해 분해 된 코드에 대한 이해를 제공하십시오.

2
코덱을 찾아야했습니다. 나는 이것을 많이 사용하지만 지금은 "우회"라고 부릅니다. research.microsoft.com/ko-kr/projects/detours
ProdigySim

1

예, 아니오

그것이 당신의 코드가 무엇을하고 있는지, 그리고 왜 어떤 것들이 노력에 대해 생각해야하는 나쁜 아이디어인지에 대한 더 나은 이해를 허락 할 것이 사실입니다.

학습 어셈블러는 주말 프로젝트가 아니므로 많은 시간이 걸리므로이 시간을 더 잘 사용할 수 있는지 생각해야합니다.

최적화 된 코드를 작성하지 않으면 아마도 노력과 동등한 이점을 보지 못할 것입니다.


1

어렸을 때 많은 어셈블러를 사용했는데 어셈블러 외부의 것을 이해하는 데 도움이되지 않는다고 생각합니다. 현대 어셈블러를 살펴보면 어쨌든 모두 매크로 언어입니다. 나는 보통 유추를 싫어하지만 어쨌든 여기에 간다 : 자동차 엔진이 어떻게 작동하는지 아는 것이 당신을 더 나은 운전자로 만드는가?


자동차 엔진이 어떻게 작동하는지 아는 것이 더 나은 운전자입니까? 아니요.하지만 엔진이 고장 나면 수리 할 수 ​​있기 때문에 더 나은 자동차 소유자가됩니다.
Cameron Martin

동의하지만 그것은 당신이 더 나은 드라이버를 만들지 않습니다. 이것은 내가 사용했던 비유입니다. 엔진을 직접 수리하면 역학을 채택하여 더 넓은 경제를 지원하지 않습니다. 유추에는 한계가 있습니다. 일반적으로 나는 누군가가 관심이 있다면 무언가를 배우려고하지 않는 것을 절대로 권장하지는 않지만, 더 높은 수준의 언어에 유용하게 적용하려면 토끼 구멍 아래로 내려 가야한다고 생각합니다. 시작하려면 특정 언어가 컴파일 된 경우, 인터프리터 또는 지터가 사용하는 컴파일 최적화를 이해해야합니다. 거대한 지역입니다.
Ian

1

내가 어셈블러를 이해하기 위해 노력한 방식은 고급 언어로 프로그램을 작성한 다음 부품을 기능적으로 동등한 코드로 대체하는 것입니다. 즉, HLL을 사용하여 높은 수준의 문제를 구성하고 해결하는 데 유용하며 금속을 치기 위해 asm을 사용합니다.

(HLL로 작성된 호스트 프로그램에 대해 이야기 할 때 x86_64 asm을 배우려고 할 때 C 또는 ObjC를, Z80, 6502 및 6809 asm을 작업 할 때 BASIC을 의미합니다).

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