Pergunta

Eu sou um crente firme na ideia de que uma das coisas mais importantes que você começa a partir de aprender uma nova língua não é como usar uma nova linguagem, mas o conhecimento de conceitos que você começa a partir dele. Não estou pedindo o quão importante ou útil você acha Assembléia é, nem me importo se eu nunca usá-lo em qualquer um dos meus projetos reais.

O que eu quero saber é o que conceitos de montagem que você acha que são mais importantes para qualquer programador geral de saber? Ele não tem de estar directamente relacionada com Assembly -. Ele também pode ser algo que você sente o programador típico que gasta todo o seu tempo em linguagens de alto nível não entendem ou toma como certo, como o cache da CPU

Foi útil?

Solução

Eu acho linguagem assembly pode ensinar-lhe muitas coisas pequenas, assim como algumas grandes conceitos.

Vou listar algumas coisas que eu posso pensar aqui, mas não há substituto para ir e aprender e usar x86 e um conjunto de instruções RISC.

Você provavelmente acha que as operações de inteiros são mais rápido. Se você quiser encontrar um inteiro raíz quadrada de um inteiro (piso ou seja (sqrt (i))) é melhor usar uma rotina de aproximação somente inteiro, certo?

Nah. O co-processador matemático (em x86 que é) tem um fsqrt instrução. Convertendo para float, tomando a raiz quadrada, e converter para int de novo é mais rápido do que um algoritmo all-inteiros.

Depois, há coisas como acessar a memória que você pode seguir, mas não devidamente apprecatiate, até que você mergulhou na montagem. Digamos que você tinha uma lista ligada, e o primeiro elemento da lista contém uma variável que você vai precisar de acesso com freqüência. A lista é reordenada raramente. Bem, cada vez que você precisa de acesso que variável, você precisa carregar o ponteiro para o primeiro elemento da lista, em seguida, usando que, carregar a variável (supondo que você não pode manter o endereço da variável num registo entre os usos) . Se você em vez armazenada a variável fora da lista, você só precisa de uma única operação de carregamento.

É claro que salvar um par de ciclos aqui e há geralmente não é importante nos dias de hoje. Mas se você está pensando em escrever código que precisa ser rápido, este tipo de conhecimento pode ser aplicado tanto com linha de montagem e, geralmente, em outros idiomas.

Que tal chamar convenções? (Algumas montadoras cuidar do presente para você -. Os programadores reais não usam aqueles) Será que o chamador ou callee limpar a pilha? Você ainda usa a pilha? Você pode passar valores nos registos - mas devido ao conjunto de instruções x86 engraçado, é melhor para passar certas coisas em certos registros. E quais registros serão preservados? Uma coisa compiladores C não pode realmente otimizar por si só é chamadas.

Há pequenos truques como empurrar um endereço de retorno e, em seguida, JMPing em um procedimento; quando o procedimento retorna ele irá para o endereço empurrado. Este afastamento da forma usual de pensar sobre chamadas de função é mais um daqueles "estados de iluminação". Se você nunca foram para projetar uma linguagem de programação com características inovadoras, que você deve saber sobre as coisas engraçadas que o hardware é capaz de fazer.

O conhecimento da linguagem de montagem ensina assuntos específicos da arquitetura sobre a segurança do computador. Como você pode explorar buffer overflows, ou quebrar em modo kernel, e como prevenir tais ataques.

Depois, há o ubercoolness de código de auto-modificar e como um problema relacionado, mecanismos para coisas como as deslocalizações e aplicar patches ao código (este necessidades de investigação do código de máquina também).

Mas todas essas coisas precisam o tipo certo de espírito. Se você é do tipo de pessoa que pode colocar

while(x--)
{
  ...
}

para uma boa utilização, uma vez que você aprende o que ele faz, mas teria dificuldade para descobrir o que ele faz por si mesmo, então linguagem assembly é provavelmente um desperdício de seu tempo.

Outras dicas

Register atribuição e gestão

Assembleia dá-lhe uma boa idéia de quantas variáveis ??(machine-palavra-sized inteiros) a CPU pode manipular simultaneamente. Se você pode quebrar seus loops para baixo para que elas envolvem apenas algumas variáveis ??temporárias, todos eles se encaixam em registos. Se não, o loop será executado lentamente como as coisas são trocados para a memória.

Este realmente me ajudou com o meu C codificação. Eu tento fazer todos os laços apertados e simples, com um mínimo de spaghetti quanto possível.

x86 é burro

Aprender várias línguas montagem me fez perceber o quão coxo o conjunto de instruções x86 é. instruções de comprimento variável? Difícil de prever tempo? Não ortogonal modos de endereçamento? Ugh.

O mundo seria melhor se todos nós MIPS correu, eu acho, ou até mesmo ARM ou PowerPC :-) Ou melhor, se Intel / AMD levou seus conhecimentos de semicondutores e é usado para fazer multi-core, ultra-rápido, ultra -barato processadores MIPS em vez de x86 processadores com todas essas qualidades redentoras.

É bom saber montagem linguagem a fim de obter uma melhor apreciação para como funciona o computador "sob a capa", e isso ajuda quando você está depurando algo e tudo o depurador pode dar-lhe um código assembly listando, que na menos dá-lhe lutar chance de descobrir o que o problema poderia ser. No entanto, tentando aplicar o conhecimento de baixo nível para linguagens de programação de alto nível, como tentando tirar vantagem de como as instruções caches de CPU e, em seguida, escrever código de alto nível wonky para forçar o compilador para produzir código de máquina super-eficiente, é provavelmente um sinal de que você está tentando micro-otimizar. Na maioria dos casos, geralmente é melhor não tentar ser mais esperto que o compilador, a menos que você precisa o ganho de desempenho, caso em que, assim como você pode escrever esses bits na montagem de qualquer maneira.

Então, é bom saber montagem em prol de uma melhor compreensão de como as coisas funcionam, mas o conhecimento adquirido não é necessariamente directamente aplicável à forma como você escrever código em linguagens de alto nível. Na mesma nota, no entanto, descobri que aprender como chamadas de função de trabalho no nível da montagem-code (aprendendo sobre os registros da pilha e afins, aprendendo sobre como os parâmetros são passados ??na pilha, aprendendo como funciona o automático de armazenamento, etc.) fez muito mais fácil de entender problemas que tive no código de nível superior, como "fora do espaço de pilha" erros e erros "inválida convenção de chamada".

O conceito mais importante é SIMD, e uso criativo do mesmo. O uso adequado de SIMD pode dar enormes benefícios de desempenho em uma enorme variedade de aplicações que vão desde tudo, de processamento de string para manipulação de vídeo à matemática matriz. Este é o lugar onde você pode obter mais 10x aumento de desempenho mais de código C puro -. É por isso que a montagem ainda é útil para além da mera depuração

Alguns exemplos do trabalho de projecto I em (todos os números são contagens de ciclo de clock em um Core 2):

Inverse 8x8 H.264 DCT (transformar frequência):

c: 1332
mmx: 187
sse2: 127

8x8 Chroma compensação de movimento (filtro de interpolação bilinear):

c: 639
mmx: 144
sse2: 110
ssse3: 79

4 16x16 operações Diferença Soma de Absolute (busca de movimento):

c: 3948
mmx: 278
sse2: 231
ssse3: 215

(sim, isso mesmo - mais de 18x mais rápido que C)

erro quadrado médio de um bloco 16x16:

c: 1013
mmx: 193
sse2: 131

Variação de um bloco 16x16:

c: 783
mmx: 171
sse2: 106

Memória, registros, saltos, loops, turnos e as várias operações pode-se realizar em assembler. Não perca os dias de depuração meus programas de classe linguagem assembly - eles eram dolorosos! -., Mas certamente me deu uma boa base

Nós esquecemos (ou nunca soube, talvez) que toda esta fantasia-calças coisas que usamos hoje (e que o amor que eu!) Resume-se a tudo isso no final.

Agora, certamente podemos ter uma carreira produtiva e lucrativa sem saber assembler, mas acho que estes conceitos são bom saber.

Eu diria que aprender recursão e laços na montagem tem me ensinado muito. Isso me fez entender o conceito subjacente de como o compilador / intérprete da linguagem eu estou usando empurra as coisas para uma pilha, e aparece-los fora, pois precisa deles. Eu também aprendi a explorar o estouro de pilha infame. (Que ainda é surpreendentemente fácil em C com algum get- e put- comandos).

Além de usar asm em todos os dias situações, eu não acho que eu iria usar qualquer um dos conceitos de montagem me ensinou.

Eu diria que modos de endereçamento são extremamente importantes.

A minha alma mater levou isso a um extremo, e porque x86 não têm o suficiente deles, estudamos tudo em um simulador de PDP11 que deve ter tido pelo menos 7 deles que eu me lembro. Em retrospecto, isso foi uma boa escolha.

tempo

execução rápida:

  • processamento paralelo
  • instruções simples
  • tabelas de pesquisa
  • previsão de desvios, canalizando

rápido acesso lento para armazenamento:

  • registros
  • cache e vários níveis de cache de
  • pilha de memória e pilha
  • memória virtual
  • E / S externa

Hoje em dia, x86 asm não é uma linha directa para as entranhas do CPU, mas mais de uma API. Os opcodes assembler que você escreve são eles próprios são compilados em uma instrução de conjunto completamente diferente, reorganizado, reescrita, fixa-up e geralmente mutilado irreconhecível.

Portanto, não é como aprender assembler lhe dá uma percepção fundamental sobre o que está acontecendo dentro da CPU. IMHO, mais importante do que aprender assembler é obter uma boa compreensão de como o CPU-alvo e da memória obras de hierarquia.

Esta série de artigos cobre o último tópico muito bem.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top