Devo tentar praticar problemas na montagem? [fechadas]


9

Eu estava olhando para o Projeto Euler Problema 48 :

A série, 1 1 + 2 2 + 3 3 + ... + 10 10 = 10405071317.

Encontre os últimos dez dígitos da série, 1 1 + 2 2 + 3 3 + ... + 1000 1000 .

No Python, eu posso fazer isso com uma única linha:

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

Mas a montagem equivalente a isso seria 100 linhas e um verdadeiro desafio.

Devo estar fazendo alguns desses quebra-cabeças em montagem para obter algumas dicas sobre programação de baixo nível e entender como o computador realmente funciona?


2
Se você não sabe como a memória funciona, como pode lidar com tópicos como ponteiros? Se você não entende como funciona um computador e um sistema operacional, como pode programar um aplicativo?
Ramhound

Eu posso fazer muitas abstrações. Ramhound foi por isso que te perguntei isso. Talvez eu não consiga entender completamente os ponteiros capazes de fazer algo em ponteiros, como trocar, o que faz sentido lógico quando você assume que os ponteiros armazenam a localização da memória de algum outro tipo de dados. tópicos que devo ler? Linguagem Assembly e um pouco de COA seria bom?
Nishant

Se você não entender completamente o ponteiro, verá que isso é uma séria desvantagem em alguns lugares.
David Thornley

3
Sua linha Python calcula x ^ 2 para x em 1..1000 (em vez de x ^ x para x em 1..1000) ou python é ainda mais mágico do que eu pensava. :)
Ingo

A função "elevar ao poder de" *no Python?

Respostas:


1

Além de aprender montagem, acredito que aprender como uma linguagem de baixo nível como C é compilada é altamente valioso. Então, minha resposta é sim, mas, novamente, provavelmente sou tendenciosa porque gosto de programação de baixo nível.

Por exemplo, apenas entendendo como instruções simples são compiladas. A seguinte função,

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

... torna-se (pelo menos um pouco interessante):

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

Esse código pega o argumento da pilha (val, o parâmetro para func), move-o para a esquerda 2 lugares (multiplique por 2 ^ 2 ou 4) e depois adiciona o valor original ao resultado. O resultado final é uma multiplicação por 5. Um exemplo como esse ilustra uma série de coisas a serem observadas, como otimizações do compilador. Em vez de chamar uma instrução para multiplicar diretamente por 5, ela muda dois lugares para multiplicar por 4 e adiciona o valor original. Encontrei exemplos como esse para melhorar muito minha compreensão das coisas em um nível inferior.

Gere a saída do assembler do gcc com a -Sopção No entanto, esteja ciente de que os resultados variam de acordo com o compilador e o nível de otimização.

De qualquer forma, eu não acho que ser um programador de linguagem assembly é o mesmo que entender assembly . Novamente, sinto que programar em uma linguagem como C e saber como isso é inserido no código de máquina é uma prática valiosa.


11

Provavelmente não é necessário ser capaz de escrever o assembler (a maioria dos quais são detalhes da convenção de inicialização e chamada para o seu sistema).

Vale a pena entender alguns, caso você esteja tentando depurar algo sem fonte.

Mas definitivamente vale a pena entender a máquina pelo menos no nível de 'C' e ponteiros (essencialmente um montador de alto nível), para que você saiba por que é ruim conceder uma string um milhão de vezes em um loop.


Na verdade, algumas implementações relativamente inteligentes for i in range(1000000): s = s + '.'não podem piorar muito as versões "otimizadas" que estou reutilizando s. Da mesma forma, vários outros desenvolvimentos invalidam o que é uma suposição razoável no conhecimento de C e assumem uma implementação ingênua. Mas, em geral, é mais útil do que prejudicial. Basta ter em mente que implementações de linguagem às vezes são mais espertos do que você;)

2
@ delnan -Eu só precisava de um pequeno exemplo de onde algo que parece inócuo em Java / C # pode ser muito caro em silício. Eu já encontrei muitas pessoas que acham que uma grande alocação e cópia de memória é instantânea.
22811 Martin Martinketkett

Eu odeio a acreditar que delnan :-)
Nishant

5

Boa pergunta. Aprender Assembléia é definitivamente bom e vale o esforço.

  1. Esse entendimento de baixo nível será útil no desenvolvimento de software embarcado
  2. Refatoração em um nível baixo
  3. Isso o ajudará a utilizar efetivamente o depurador
  4. Compreenda o código desmontado para ajudar em coisas como cavernas de código

2
Eu tive que procurar codecaves. Eu uso muito isso, mas nós os chamamos de "desvios" agora. research.microsoft.com/en-us/projects/detours
ProdigySim

1

Sim e não.

Embora seja verdade que isso lhe permitirá entender melhor o que seu código está fazendo e por que algumas coisas são apenas uma má idéia, você precisa pensar no esforço.

Aprender montador não é um projeto de fim de semana, você levará muito tempo e você precisará pensar se esse tempo poderia ou não ser melhor gasto.

Se você não está no código otimizado, provavelmente nunca verá benefícios iguais ao esforço que você coloca.


1

Fiz muitos assembler quando era mais jovem e acho que não ajudou a entender nada fora do assembler. Se você der uma olhada no assembler moderno, é tudo sobre linguagem de macro de qualquer maneira. Eu geralmente odeio analogias, mas aqui vai de qualquer maneira: saber como o motor de um carro funciona faz de você um motorista melhor?


Saber como funciona o motor de um carro faz de você um motorista melhor? Não, mas faz de você um proprietário melhor, porque se o motor quebrar, você poderá consertá-lo.
Cameron Martin

Concordo, mas isso não faz de você um driver melhor, que é a analogia que eu estava usando. Ao consertar você mesmo o motor, você não está apoiando a economia em geral empregando mecânica, ... As analogias têm limites. Geralmente, eu nunca desencorajaria alguém de procurar aprender alguma coisa, se estiver interessado, mas acho que você precisa ir bem fundo na toca do coelho para poder aplicá-la de maneira útil em idiomas de nível superior. Para começar, você precisa entender as otimizações de compilação usadas pelo idioma específico, se ele for compilado, ou o intérprete ou o tremor. É uma área enorme.
Ian

1

O jeito que eu tenho trabalhado para entender o assembler é escrevendo programas em linguagens de nível superior e substituindo partes por (pelo menos, esperançosamente) trechos funcionalmente equivalentes de código montado. Isso significa que eu uso HLLs para o que é bom para organizar e resolver problemas de alto nível - e eu uso asm para bater o metal.

(Quando falo sobre o programa host sendo escrito em uma HLL, quero dizer C ou ObjC quando estou tentando aprender x86_64 asm e BASIC quando estou trabalhando em Z80, 6502 e 6809 asm).

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.